diff options
Diffstat (limited to 'service.c')
-rw-r--r-- | service.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/service.c b/service.c index f5038da..3472151 100644 --- a/service.c +++ b/service.c @@ -14,11 +14,15 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <assert.h> +#include <err.h> #include <fcntl.h> +#include <limits.h> #include <paths.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <syslog.h> #include <unistd.h> #include "daemon.h" @@ -100,3 +104,51 @@ err: serviceFree(service); return -1; } + +void serviceStart(struct Service *service) { + if (service->state == Start) return; + service->intent = Start; + // TODO: Reset restart interval. + + service->pid = fork(); + if (service->pid < 0) { + syslog(LOG_ERR, "fork: %m"); + return; + // FIXME: Do we treat this as a restart condition? + } + if (service->pid) { + service->state = Start; + return; + } + + closelog(); + dup2(service->outPipe[1], STDOUT_FILENO); + dup2(service->errPipe[1], STDERR_FILENO); + + int error = chdir(serviceDir); + if (error) err(StopExit, "%s", serviceDir); + + error = setgid(serviceGID); + if (error) err(StopExit, "setgid"); + + error = setuid(serviceUID); + if (error) err(StopExit, "setuid"); + + size_t len = 0; + char command[ARG_MAX]; + for (size_t i = 0; i < prepend.len; ++i) { + int n = snprintf( + &command[len], sizeof(command) - len, "%s;", prepend.commands[i] + ); + assert(n > 0); + len += n; + } + snprintf(&command[len], sizeof(command) - len, "exec %s", service->command); + + execle( + _PATH_BSHELL, + _PATH_BSHELL, "-c", command, service->name, NULL, + serviceEnviron + ); + err(StopExit, "%s", _PATH_BSHELL); +} |