aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/README3
-rw-r--r--src/client.c1
-rw-r--r--src/client.h1
-rw-r--r--src/common.h83
-rw-r--r--src/daemon.c4
-rw-r--r--src/daemon.h104
-rw-r--r--src/sat.c27
-rw-r--r--src/satd-add.c43
-rw-r--r--src/satd.c1
-rw-r--r--src/satq.c1
-rw-r--r--src/satr.c1
-rw-r--r--src/satrm.c1
12 files changed, 120 insertions, 150 deletions
diff --git a/src/README b/src/README
index c77d17e..51fa80c 100644
--- a/src/README
+++ b/src/README
@@ -23,5 +23,6 @@ client.[ch] Used by sat{,q,r,rm}.c, code for communicating
daemon.[ch] Used by satd*.c, some shared code for daemons objects.
-common.h Used by sat{,q,r,rm,d}.c, some shared code.
+common.h Used by sat{,q,r,rm,d'}.c, some shared code.
+ Included via client.h and daemon.h.
diff --git a/src/client.c b/src/client.c
index 3573f46..80cd527 100644
--- a/src/client.c
+++ b/src/client.c
@@ -20,7 +20,6 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "client.h"
-#include "common.h"
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
diff --git a/src/client.h b/src/client.h
index a7640e7..8f27d73 100644
--- a/src/client.h
+++ b/src/client.h
@@ -22,6 +22,7 @@
#ifndef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE
#endif
+#include "common.h"
#include <stddef.h>
diff --git a/src/common.h b/src/common.h
index 68d465e..187723e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -47,6 +47,43 @@ static const char *failed__ = NULL;
/**
+ * A queued job.
+ */
+struct job {
+ /**
+ * The job number.
+ */
+ size_t no;
+
+ /**
+ * The number of “argv” elements in `payload`.
+ */
+ int argc;
+
+ /**
+ * The clock in which `ts` is measured.
+ */
+ clockid_t clk;
+
+ /**
+ * The time when the job shall be executed.
+ */
+ struct timespec ts;
+
+ /**
+ * The number of bytes in `payload`.
+ */
+ size_t n;
+
+ /**
+ * “argv” followed by “envp”.
+ */
+ char payload[];
+};
+
+
+
+/**
* Defines the function `void usage(void)`
* that prints usage information.
*
@@ -132,3 +169,49 @@ fail: \
free(msg); \
return 1;
+
+/**
+ * This block of code allows us to compile with DEBUG=valgrind
+ * or DEBUG=strace and have all exec:s be wrapped in
+ * valgrind --leak-check=full --show-leak-kinds=all or
+ * strace, respectively. Very useful for debugging. However,
+ * children do not inherit strace, so between forking and
+ * exec:ing we do not have strace.
+ */
+#if 1 && defined(DEBUG)
+# if ((DEBUG == 2) || (DEBUG == 3))
+# ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
+__attribute__((__used__))
+# endif
+# if DEBUG == 2
+# define DEBUGPROG "strace"
+# else
+# define DEBUGPROG "valgrind"
+# endif
+# define execl(path, _, ...) (execl)("/usr/bin/" DEBUGPROG, "/usr/bin/" DEBUGPROG, path, __VA_ARGS__)
+# define execve(...) execve_(__VA_ARGS__)
+static int
+execve_(const char *path, char *const argv[], char *const envp[])
+{
+ size_t n = 0;
+ char **new_argv = NULL;
+ int x = (DEBUG - 2) * 2, saved_errno;
+ while (argv[n++]);
+ t (!(new_argv = malloc((n + 1 + (size_t)x) * sizeof(char *))));
+ new_argv[x] = "--show-leak-kinds=all";
+ new_argv[1] = "--leak-check=full";
+ new_argv[0] = "/usr/bin/" DEBUGPROG;
+ new_argv[1 + x] = path;
+ memcpy(new_argv + 2 + x, argv + 1, (n - 1) * sizeof(char *));
+ (execve)(*new_argv, new_argv, envp);
+fail:
+ return saved_errno = errno, free(new_argv), errno = saved_errno, -1;
+}
+# ifdef __GNUC__
+# pragma GCC diagnostic pop
+# endif
+# endif
+#endif
+
diff --git a/src/daemon.c b/src/daemon.c
index e4c444e..ee05cf7 100644
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -103,6 +103,8 @@ pwriten(int fildes, const void *buf, size_t nbyte, size_t offset)
/**
* Wrapper for `read` that reads all available data.
*
+ * `errno` is set to `EBADMSG` on success.
+ *
* @param fd The file descriptor from which to to read.
* @param buf Output parameter for the data.
* @param n Output parameter for the number of read bytes.
@@ -131,7 +133,7 @@ readall(int fd, char **buf, size_t *n)
new = realloc(buffer, *n = ptr);
*buf = ptr ? (new ? new : buffer) : NULL;
shutdown(SOCK_FILENO, SHUT_RD);
- return 0;
+ return errno = EBADMSG, 0;
fail:
saved_errno = errno;
diff --git a/src/daemon.h b/src/daemon.h
index d860d1f..cb6736a 100644
--- a/src/daemon.h
+++ b/src/daemon.h
@@ -22,6 +22,7 @@
#ifndef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE
#endif
+#include "common.h"
#include <stddef.h>
#include <errno.h>
#include <string.h>
@@ -83,23 +84,6 @@
-#ifndef t
-/**
- * Go to `fail` if a statement evaluates to non-zero.
- *
- * @param ... The statement.
- */
-# ifndef DEBUG
-# define t(...) do { if (__VA_ARGS__) goto fail; } while (0)
-# else
-# define t(...) do { if ((__VA_ARGS__) ? (failed__ = #__VA_ARGS__) : 0) { (perror)(failed__); goto fail; } } while (0)
-static const char *failed__ = NULL;
-# define perror(_) ((void)(_))
-# endif
-#endif
-
-
-
/**
* `dup2(OLD, NEW)` and, on success, `close(OLD)`.
*
@@ -144,43 +128,6 @@ fail: \
/**
- * A queued job.
- */
-struct job {
- /**
- * The job number.
- */
- size_t no;
-
- /**
- * The number of “argv” elements in `payload`.
- */
- int argc;
-
- /**
- * The clock in which `ts` is measured.
- */
- clockid_t clk;
-
- /**
- * The time when the job shall be executed.
- */
- struct timespec ts;
-
- /**
- * The number of bytes in `payload`.
- */
- size_t n;
-
- /**
- * “argv” followed by “envp”.
- */
- char payload[];
-};
-
-
-
-/**
* Wrapper for `pread` that reads the required amount of data.
*
* @param fildes See pread(3).
@@ -205,6 +152,8 @@ ssize_t pwriten(int fildes, const void *buf, size_t nbyte, size_t offset);
/**
* Wrapper for `read` that reads all available data.
*
+ * `errno` is set to `EBADMSG` on success.
+ *
* @param fd The file descriptor from which to to read.
* @param buf Output parameter for the data.
* @param n Output parameter for the number of read bytes.
@@ -289,50 +238,3 @@ int remove_job(const char *jobno, int runjob);
*/
struct job **get_jobs(void);
-
-
-/**
- * This block of code allows us to compile with DEBUG=valgrind
- * or DEBUG=strace and have all exec:s be wrapped in
- * valgrind --leak-check=full --show-leak-kinds=all or
- * strace, respectively. Very useful for debugging. However,
- * children do not inherit strace, so between forking and
- * exec:ing we do not have strace.
- */
-#if 1 && defined(DEBUG)
-# if ((DEBUG == 2) || (DEBUG == 3))
-# ifdef __GNUC__
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
-__attribute__((__used__))
-# endif
-# if DEBUG == 2
-# define DEBUGPROG "strace"
-# else
-# define DEBUGPROG "valgrind"
-# endif
-# define execl(path, _, ...) (execl)("/usr/bin/" DEBUGPROG, "/usr/bin/" DEBUGPROG, path, __VA_ARGS__)
-# define execve(...) execve_(__VA_ARGS__)
-static int
-execve_(const char *path, char *const argv[], char *const envp[])
-{
- size_t n = 0;
- char **new_argv = NULL;
- int x = (DEBUG - 2) * 2, saved_errno;
- while (argv[n++]);
- t (!(new_argv = malloc((n + 1 + (size_t)x) * sizeof(char *))));
- new_argv[x] = "--show-leak-kinds=all";
- new_argv[1] = "--leak-check=full";
- new_argv[0] = "/usr/bin/" DEBUGPROG;
- new_argv[1 + x] = path;
- memcpy(new_argv + 2 + x, argv + 1, (n - 1) * sizeof(char *));
- (execve)(*new_argv, new_argv, envp);
-fail:
- return saved_errno = errno, free(new_argv), errno = saved_errno, -1;
-}
-# ifdef __GNUC__
-# pragma GCC diagnostic pop
-# endif
-# endif
-#endif
-
diff --git a/src/sat.c b/src/sat.c
index 5431208..147c327 100644
--- a/src/sat.c
+++ b/src/sat.c
@@ -21,7 +21,6 @@
*/
#include "parse_time.h"
#include "client.h"
-#include "common.h"
#include <errno.h>
#include <unistd.h>
@@ -53,19 +52,20 @@ main(int argc, char *argv[], char *envp[])
{
#define E(CASE, DESC) case CASE: return fprintf(stderr, "%s: %s: %s\n", argv0, DESC, argv[1]), 2
- struct timespec ts;
- clockid_t clk;
char *msg = NULL;
+ char *timearg;
void *new;
- size_t n, size = 64;
+ size_t size = 64;
+ struct job job = { .no = 0 };
if ((argc < 3) || (argv[1][0] == '-'))
usage();
- argv0 = argv[0];
+ argv0 = argv[0], timearg = argv[1];
+ job.argc = argc -= 2, argv += 2;
/* Parse the time argument. */
- if (parse_time(argv[1], &ts, &clk)) {
+ if (parse_time(timearg, &(job.ts), &(job.clk))) {
switch (errno) {
E (EINVAL, "time parameter cound not be parsed, perhaps you need an external parser");
E (ERANGE, "the specified time is beyond the limit of what can be stored");
@@ -74,9 +74,6 @@ main(int argc, char *argv[], char *envp[])
}
}
- argc -= 2;
- argv += 2;
-
retry:
/* Get the size of the current working directory's pathname. */
t (!(new = realloc(msg, size <<= 1)));
@@ -87,15 +84,13 @@ retry:
size = strlen(getcwd(msg, size)) + 1, free(msg);
/* Construct message to send to the daemon. */
- n = measure_array(argv) + size + measure_array(envp);
- t (!(msg = malloc(n + sizeof(argc) + sizeof(clk) + sizeof(ts))));
- store_array(getcwd(store_array(msg, argv), size) + size, envp);
- memcpy(msg + n, &argc, sizeof(argc)), n += sizeof(argc);
- memcpy(msg + n, &clk, sizeof(clk)), n += sizeof(clk);
- memcpy(msg + n, &ts, sizeof(ts)), n += sizeof(ts);
+ job.n = measure_array(argv) + size + measure_array(envp);
+ t (!(msg = malloc(sizeof(job) + job.n)));
+ memcpy(msg, &job, sizeof(job));
+ store_array(getcwd(store_array(msg + sizeof(job), argv), size) + size, envp);
/* Send job to daemon, start daemon if necessary. */
- SEND(SAT_QUEUE, n, msg);
+ SEND(SAT_QUEUE, sizeof(job) + job.n, msg);
END(msg);
}
diff --git a/src/satd-add.c b/src/satd-add.c
index fba4465..c550072 100644
--- a/src/satd-add.c
+++ b/src/satd-add.c
@@ -37,49 +37,40 @@
int
main(int argc, char *argv[])
{
+#define M ((struct job *)message)
+
size_t n = 0, elements = 0, i;
ssize_t r;
char *message = NULL;
- int msg_argc;
- struct job *job = NULL;
struct stat attr;
DAEMON_PROLOGUE;
/* Receive and validate message. */
- t (readall(SOCK_FILENO, &message, &n));
- t (n < sizeof(int) + sizeof(clockid_t) + sizeof(struct timespec));
- n -= sizeof(int) + sizeof(clockid_t) + sizeof(struct timespec);
- msg_argc = *(int *)(message + n);
- t ((msg_argc < 1) || !n || message[n - 1]);
- for (i = n; i--; elements += !message[i]);
- t (elements < (size_t)msg_argc);
-
- /* Parse message. */
- t (!(job = malloc(sizeof(*job) + n)));
- job->argc = msg_argc;/* *(int *)(message + n); "See a few lines above."; */
- job->clk = *(clockid_t *)(message + n + sizeof(int));
- job->ts = *(struct timespec *)(message + n + sizeof(int) + sizeof(clockid_t));
- memcpy(job->payload, message, job->n = n);
+ t (readall(SOCK_FILENO, &message, &n) || (n < sizeof(struct job)));
+ t (M->n != (n -= sizeof(struct job)));
+ t ((M->argc < 1) || !n || message[sizeof(struct job) - 1 + n]);
+ for (i = n; i--; elements += !message[sizeof(struct job) + i]);
+ t (elements < (size_t)(M->argc));
/* Update state file and run hook. */
t (flock(STATE_FILENO, LOCK_EX));
t (fstat(STATE_FILENO, &attr));
- t (r = preadn(STATE_FILENO, &(job->no), sizeof(job->no), (size_t)0), r < 0);
- if (r < (ssize_t)sizeof(job->no))
- job->no = 0;
+ t (r = preadn(STATE_FILENO, &(M->no), sizeof(M->no), (size_t)0), r < 0);
+ if (r < (ssize_t)sizeof(M->no))
+ M->no = 0;
else
- job->no += 1;
- t (pwriten(STATE_FILENO, &(job->no), sizeof(job->no), (size_t)0) < (ssize_t)sizeof(job->no));
- if (attr.st_size < (off_t)sizeof(job->no))
- attr.st_size = (off_t)sizeof(job->no);
- t (pwriten(STATE_FILENO, job, sizeof(*job) + n, (size_t)(attr.st_size)) < (ssize_t)n);
+ M->no += 1;
+ t (pwriten(STATE_FILENO, &(M->no), sizeof(M->no), (size_t)0) < (ssize_t)sizeof(M->no));
+ if (attr.st_size < (off_t)sizeof(M->no))
+ attr.st_size = (off_t)sizeof(M->no);
+ n += sizeof(struct job);
+ t (pwriten(STATE_FILENO, message, n, (size_t)(attr.st_size)) < (ssize_t)n);
fsync(STATE_FILENO);
- run_job_or_hook(job, "queued");
+ run_job_or_hook(M, "queued");
t (flock(STATE_FILENO, LOCK_UN));
DAEMON_CLEANUP_START;
free(message);
- free(job);
DAEMON_CLEANUP_END;
}
diff --git a/src/satd.c b/src/satd.c
index 8865c51..d9745ef 100644
--- a/src/satd.c
+++ b/src/satd.c
@@ -19,7 +19,6 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-#include "common.h"
#include "daemon.h"
#include "daemonise.h"
#include <unistd.h>
diff --git a/src/satq.c b/src/satq.c
index e851c1b..7f92878 100644
--- a/src/satq.c
+++ b/src/satq.c
@@ -20,7 +20,6 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "client.h"
-#include "common.h"
diff --git a/src/satr.c b/src/satr.c
index 0543d58..42bfda4 100644
--- a/src/satr.c
+++ b/src/satr.c
@@ -20,7 +20,6 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "client.h"
-#include "common.h"
diff --git a/src/satrm.c b/src/satrm.c
index 45f4bc2..fda6288 100644
--- a/src/satrm.c
+++ b/src/satrm.c
@@ -20,7 +20,6 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "client.h"
-#include "common.h"