aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/daemon.c93
-rw-r--r--src/daemon.h2
-rw-r--r--src/satd-add.c7
-rw-r--r--src/satd-diminished.c5
-rw-r--r--src/satd-list.c7
-rw-r--r--src/satd-rm.c7
-rw-r--r--src/satd-run.c7
-rw-r--r--src/satd.c3
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. */
diff --git a/src/satd.c b/src/satd.c
index fbb1e48..7442741 100644
--- a/src/satd.c
+++ b/src/satd.c
@@ -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)