diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/daemon.c | 93 | ||||
-rw-r--r-- | src/daemon.h | 2 | ||||
-rw-r--r-- | src/satd-add.c | 7 | ||||
-rw-r--r-- | src/satd-diminished.c | 5 | ||||
-rw-r--r-- | src/satd-list.c | 7 | ||||
-rw-r--r-- | src/satd-rm.c | 7 | ||||
-rw-r--r-- | src/satd-run.c | 7 | ||||
-rw-r--r-- | src/satd.c | 3 |
8 files changed, 103 insertions, 28 deletions
diff --git a/src/daemon.c b/src/daemon.c index 05036b3..edc230c 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -24,6 +24,14 @@ #include <stdarg.h> #include <sys/stat.h> #include <sys/file.h> +#include <sys/wait.h> + + + +/** + * The environment. + */ +extern char **environ; @@ -249,10 +257,67 @@ fail: /** + * Run a job or a hook. + * + * @param job The job. + * @param hook The hook, `NULL` to run the job. + * @return 0 on success, -1 on error, 1 if the child failed. + */ +static int +run_job_or_hook(struct job *job, const char *hook) +{ + pid_t pid; + char **args = NULL; + char **argv = NULL; + char **envp = NULL; + size_t argsn; + void *new; + int status = 0; + int saved_errno; + + t (!(args = restore_array(job->payload, job->n, &argsn))); + t (!(argv = sublist(args, (size_t)(job->argc)))); + t (!(envp = sublist(args + job->argc, argsn - (size_t)(job->argc)))); + + if (hook) { + new = realloc(argv, ((size_t)(job->argc) + 3) * sizeof(*argv)); + t (!new); + argv = new; + memmove(argv + 2, argv, ((size_t)(job->argc) + 1) * sizeof(*argv)); + argv[0] = getenv("SAT_HOOK_PATH"); + argv[1] = strstr(hook, hook); /* strstr: just to remove a warning */ + } + + switch ((pid = fork())) { + case -1: + goto fail; + case 0: + close(SOCK_FILENO); + close(STATE_FILENO); + environ = envp; + execve(*argv, argv, envp); + exit(1); + break; + default: + t (waitpid(pid, &status, 0) != pid); + break; + } + +fail: + saved_errno = errno; + free(args); + free(argv); + free(envp); + errno = saved_errno; + return status ? 1 : -!!saved_errno; +} + + +/** * Removes (and optionally runs) a job. * * @param jobno The job number, `NULL` for any job. - * @param runjob Shall we run the job too? + * @param runjob Shall we run the job too? 2 if its time has expired (not forced). * @return 0 on success, -1 on error. * * @throws 0 The job is not in the queue. @@ -266,7 +331,8 @@ remove_job(const char *jobno, int runjob) ssize_t r; struct stat attr; struct job job; - int saved_errno; + struct job *job_full = NULL; + int rc = 0, saved_errno; if (jobno) { no = (errno = 0, strtoul)(jobno, &end, 10); @@ -287,6 +353,9 @@ remove_job(const char *jobno, int runjob) return 0; found_it: + job_full = malloc(sizeof(job) + job.n); + *job_full = job; + t (preadn(STATE_FILENO, job_full->payload, job.n, off) < (ssize_t)(job.n)); n -= off + sizeof(job) + job.n; t (!(buf = malloc(n))); t (r = preadn(STATE_FILENO, buf, n, off + sizeof(job) + job.n), r < 0); @@ -295,15 +364,27 @@ found_it: free(buf), buf = NULL; fsync(STATE_FILENO); flock(STATE_FILENO, LOCK_UN); - if (runjob == 0) - return 0; - /* TODO run job (when running, remember to use PATH from the job's envp) */ + if (runjob) { + run_job_or_hook(job_full, runjob == 2 ? "expired" : "forced"); + rc = run_job_or_hook(job_full, NULL); + saved_errno = errno; + run_job_or_hook(job_full, rc ? "failure" : "success"); + rc = rc == 1 ? 0 : rc; + free(job_full); + errno = saved_errno; + } else { + run_job_or_hook(job_full, "removed"); + free(job_full); + } + + return rc; fail: saved_errno = errno; flock(STATE_FILENO, LOCK_UN); free(buf); + free(job_full); errno = saved_errno; return -1; } @@ -332,7 +413,7 @@ get_jobs(void) off += sizeof(job); t (!(js[j] = malloc(sizeof(job) + sizeof(job.n)))); *(js[j]) = job; - t (preadn(STATE_FILENO, js[j++] + sizeof(job), job.n, off) < (ssize_t)(job.n)); + t (preadn(STATE_FILENO, js[j++]->payload, job.n, off) < (ssize_t)(job.n)); off += job.n; } js[j] = NULL; diff --git a/src/daemon.h b/src/daemon.h index d279dbc..2e402c8 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -182,7 +182,7 @@ int send_string(int sockfd, int outfd, ...); * Removes (and optionally runs) a job. * * @param jobno The job number, `NULL` for any job. - * @param runjob Shall we run the job too? + * @param runjob Shall we run the job too? 2 if its time has expired (not forced). * @return 0 on success, -1 on error. * * @throws 0 The job is not in the queue. diff --git a/src/satd-add.c b/src/satd-add.c index aa7dde0..5afcf2d 100644 --- a/src/satd-add.c +++ b/src/satd-add.c @@ -26,10 +26,9 @@ /** * Subroutine to the sat daemon: add job. * - * @param argc Should be 4. + * @param argc Should be 3. * @param argv The name of the process, the pathname of the socket, - * the pathname to the state file, and $SAT_HOOK_PATH - * (the pathname of the hook-script.) + * and the pathname to the state file. * @return 0 The process was successful. * @return 1 The process failed queuing the job. */ @@ -40,7 +39,7 @@ main(int argc, char *argv[]) char *message = NULL; int msg_argc; - assert(argc == 4); + assert(argc == 3); t (reopen(STATE_FILENO, O_RDWR)); /* Receive and validate message. */ diff --git a/src/satd-diminished.c b/src/satd-diminished.c index cd8f988..348355f 100644 --- a/src/satd-diminished.c +++ b/src/satd-diminished.c @@ -68,10 +68,9 @@ static void sighandler(int signo) /** * The sat daemon. * - * @param argc Should be 4. + * @param argc Should be 3. * @param argv The name of the process, the pathname of the socket, - * the pathname to the state file, and $SAT_HOOK_PATH - * (the pathname of the hook-script.) + * and the pathname to the state file. * @param envp The environment. * @return 0 The process was successful. * @return 1 The process failed queuing the job. diff --git a/src/satd-list.c b/src/satd-list.c index e9904a5..ee11c3a 100644 --- a/src/satd-list.c +++ b/src/satd-list.c @@ -236,10 +236,9 @@ fail: /** * Subroutine to the sat daemon: list jobs. * - * @param argc Should be 4. + * @param argc Should be 3. * @param argv The name of the process, the pathname of the socket, - * the pathname to the state file, and $SAT_HOOK_PATH - * (the pathname of the hook-script.) + * and the pathname to the state file. * @return 0 The process was successful. * @return 1 The process failed queuing the job. */ @@ -252,7 +251,7 @@ main(int argc, char *argv[]) struct job** job; int rc = 0; - assert(argc == 4); + assert(argc == 3); t (reopen(STATE_FILENO, O_RDWR)); /* Receive and validate message. */ diff --git a/src/satd-rm.c b/src/satd-rm.c index 3229b68..010f795 100644 --- a/src/satd-rm.c +++ b/src/satd-rm.c @@ -26,10 +26,9 @@ /** * Subroutine to the sat daemon: remove jobs. * - * @param argc Should be 4. + * @param argc Should be 3. * @param argv The name of the process, the pathname of the socket, - * the pathname to the state file, and $SAT_HOOK_PATH - * (the pathname of the hook-script.) + * and the pathname to the state file. * @return 0 The process was successful. * @return 1 The process failed queuing the job. */ @@ -42,7 +41,7 @@ main(int argc, char *argv[]) char **arg; int rc = 0; - assert(argc == 4); + assert(argc == 3); t (reopen(STATE_FILENO, O_RDWR)); /* Receive and validate message. */ diff --git a/src/satd-run.c b/src/satd-run.c index 763b8f7..1af4834 100644 --- a/src/satd-run.c +++ b/src/satd-run.c @@ -26,10 +26,9 @@ /** * Subroutine to the sat daemon: run jobs early. * - * @param argc Should be 4. + * @param argc Should be 3. * @param argv The name of the process, the pathname of the socket, - * the pathname to the state file, and $SAT_HOOK_PATH - * (the pathname of the hook-script.) + * and the pathname to the state file. * @return 0 The process was successful. * @return 1 The process failed queuing the job. */ @@ -42,7 +41,7 @@ main(int argc, char *argv[]) char **arg; int rc = 0; - assert(argc == 4); + assert(argc == 3); t (reopen(STATE_FILENO, O_RDWR)); /* Receive and validate message. */ @@ -262,8 +262,7 @@ main(int argc, char *argv[]) t (foreground ? 0 : daemonise("satd", DAEMONISE_KEEP_FDS, sock, -1)); /* Change to a process image without all this initialisation text. */ - execl(LIBEXEC "/" PACKAGE "/satd-diminished", argv0, - address.sun_path, getenv("SAT_HOOK_PATH"), NULL); + execl(LIBEXEC "/" PACKAGE "/satd-diminished", argv0, address.sun_path, NULL); fail: if (errno) |