aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/README4
-rw-r--r--src/common.h4
-rw-r--r--src/daemon.c135
-rw-r--r--src/daemon.h89
-rw-r--r--src/sat.c22
-rw-r--r--src/satd-add.c57
-rw-r--r--src/satd-diminished.c11
-rw-r--r--src/satd-list.c49
-rw-r--r--src/satd-rm.c51
-rw-r--r--src/satd-run.c53
-rw-r--r--src/satd.c13
11 files changed, 452 insertions, 36 deletions
diff --git a/src/README b/src/README
index e36126f..d9404d2 100644
--- a/src/README
+++ b/src/README
@@ -19,5 +19,7 @@ daemonise.[ch] From <http://github.com/maandree/slibc>;
client.[ch] Used by sat{,q,r,rm}.c, code for communicating
with satd, starts satd transparently if necessary.
-common.h Used by sat{,q,r,rm}.c, some shared code.
+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.
diff --git a/src/common.h b/src/common.h
index 55a0837..36f66af 100644
--- a/src/common.h
+++ b/src/common.h
@@ -26,12 +26,14 @@
+#ifndef t
/**
* Go to `fail` if a statement evaluates to non-zero.
*
* @param ... The statement.
*/
-#define t(...) do { if (__VA_ARGS__) goto fail; } while (0)
+# define t(...) do { if (__VA_ARGS__) goto fail; } while (0)
+#endif
diff --git a/src/daemon.c b/src/daemon.c
new file mode 100644
index 0000000..8d9b1b3
--- /dev/null
+++ b/src/daemon.c
@@ -0,0 +1,135 @@
+/**
+ * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "daemon.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+
+
+/**
+ * Wrapper for `read` that reads all available data.
+ *
+ * Sets `errno` 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.
+ * @return 0 on success, -1 on error.
+ *
+ * @throws Any exception specified for read(3).
+ * @throws Any exception specified for realloc(3).
+ */
+int
+readall(int fd, char **buf, size_t *n);
+{
+ char *buffer = NULL;
+ size_t ptr = 0;
+ size_t size = 0;
+ ssize_t got;
+ char *new;
+ int saved_errno;
+
+ for (;;) {
+ if (ptr == size) {
+ new = realloc(buffer, size <<= 1);
+ t (!new);
+ buffer = wnew;
+ }
+ got = read(fd, buffer + ptr, size - ptr);
+ t (got < 0);
+ if (got == 0)
+ break;
+ ptr += (size_t)got;
+ }
+
+ new = realloc(buffer, ptr);
+ *buf = new ? new : buffer;
+ *n = ptr;
+ return 0;
+
+fail:
+ saved_errno = errno;
+ free(buffer);
+ errno = saved_errno;
+ return -1;
+}
+
+
+/**
+ * Unmarshal a `NULL`-terminated string array.
+ *
+ * The elements are not actually copied, subpointers
+ * to `buf` are stored in the returned list.
+ *
+ * @param buf The marshalled array. Must end with a NUL byte.
+ * @param len The length of `buf`.
+ * @param n Output parameter for the number of elements. May be `NULL`
+ * @return The list, `NULL` on error.
+ *
+ * @throws Any exception specified for realloc(3).
+ */
+char **
+restore_array(char* buf, size_t len, size_t* n)
+{
+ char **rc = malloc((len + 1) * sizeof(char*));
+ char *elem = NULL;
+ char **new;
+ size_t i, e = 0;
+ t (!rc);
+ while (i < len) {
+ rc[++e] = buf + i;
+ i += strlen(buf + i);
+ }
+ rc[e] = NULL;
+ new = realloc(rc, (e + 1) * sizeof(char*));
+ if (n)
+ *n = e;
+ return new ? new : rc;
+fail:
+ return NULL;
+}
+
+
+/**
+ * Create `NULL`-terminate subcopy of an list,
+ *
+ * @param list The list.
+ * @param n The number of elements in the new sublist.
+ * @return The sublist, `NULL` on error.
+ *
+ * @throws Any exception specified for malloc(3).
+ */
+char **
+sublist(char *const *list, size_t n)
+{
+ char **rc = malloc((n + 1) * sizeof(char*));
+ t (!rc);
+ rc[n] = NULL;
+ while (n--)
+ rc[n] = list[n];
+ return rc;
+fail:
+ return NULL;
+}
+
diff --git a/src/daemon.h b/src/daemon.h
new file mode 100644
index 0000000..e56fa76
--- /dev/null
+++ b/src/daemon.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stddef.h>
+
+
+
+/**
+ * The file descriptor for the socket.
+ */
+#define SOCK_FILENO 3
+
+/**
+ * The file descriptor for the state file.
+ */
+#define STATE_FILENO 4
+
+
+
+#ifndef t
+/**
+ * Go to `fail` if a statement evaluates to non-zero.
+ *
+ * @param ... The statement.
+ */
+# define t(...) do { if (__VA_ARGS__) goto fail; } while (0)
+#endif
+
+
+
+/**
+ * Wrapper for `read` that reads all available data.
+ *
+ * Sets `errno` 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.
+ * @return 0 on success, -1 on error.
+ *
+ * @throws Any exception specified for read(3).
+ * @throws Any exception specified for realloc(3).
+ */
+int readall(int fd, char **buf, size_t *n);
+
+/**
+ * Unmarshal a `NULL`-terminated string array.
+ *
+ * The elements are not actually copied, subpointers
+ * to `buf` are stored in the returned list.
+ *
+ * @param buf The marshalled array. Must end with a NUL byte.
+ * @param len The length of `buf`.
+ * @param n Output parameter for the number of elements. May be `NULL`
+ * @return The list, `NULL` on error.
+ *
+ * @throws Any exception specified for realloc(3).
+ */
+char **restore_array(char* buf, size_t len, size_t* n);
+
+/**
+ * Create `NULL`-terminate subcopy of an list,
+ *
+ * @param list The list.
+ * @param n The number of elements in the new sublist.
+ * @return The sublist, `NULL` on error.
+ *
+ * @throws Any exception specified for malloc(3).
+ */
+char **sublist(char *const *list, size_t n);
+
diff --git a/src/sat.c b/src/sat.c
index afdd910..6766542 100644
--- a/src/sat.c
+++ b/src/sat.c
@@ -54,9 +54,6 @@ main(int argc, char *argv[], char *envp[])
struct timespec ts;
clockid_t clk;
char *msg = NULL;
- char **w;
- char **r;
- int removed_empty = 0;
size_t n;
if ((argc < 3) || (argv[1][0] == '-'))
@@ -90,24 +87,13 @@ main(int argc, char *argv[], char *envp[])
argc -= 2;
argv += 2;
- /* Remove empty environment entries */
- for (w = r = envp; *r; r++) {
- if (**r) {
- *w++ = *r;
- } else if (removed_empty == 0) {
- fprintf(stderr,
- "%s: warning: removed empty "
- "environment entry.\n", argv0);
- removed_empty = 0;
- }
- }
-
/* Construct message to send to the daemon. */
n = measure_array(argv) + measure_array(envp);
- t (!(msg = malloc(n + sizeof(clk) + sizeof(ts))));
+ t (!(msg = malloc(n + sizeof(int) + sizeof(clk) + sizeof(ts))));
store_array(store_array(msg, argv), envp);
- memcpy(msg + n, &clk, sizeof(clk)), n += sizeof(clk);
- memcpy(msg + n, &ts, sizeof(ts)), n += sizeof(ts);
+ memcpy(msg + n, &argc, sizeof(int)), n += sizeof(int);
+ memcpy(msg + n, &clk, sizeof(clk)), n += sizeof(clk);
+ memcpy(msg + n, &ts, sizeof(ts)), n += sizeof(ts);
/* Send job to daemon, start daemon if necessary. */
SEND(SAT_QUEUE, n, msg);
diff --git a/src/satd-add.c b/src/satd-add.c
new file mode 100644
index 0000000..f7f2554
--- /dev/null
+++ b/src/satd-add.c
@@ -0,0 +1,57 @@
+/**
+ * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "daemon.h"
+
+
+
+/**
+ * Subroutine to the sat daemon: add job.
+ *
+ * @param argc Should be 4.
+ * @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.)
+ * @return 0 The process was successful.
+ * @return 1 The process failed queuing the job.
+ */
+int
+main(int argc, char *argv[])
+{
+ size_t n = 0, elements = 0, i;
+ char *message = NULL;
+ int msg_argc;
+ char **msg = NULL;
+
+ /* Receive and validate message. */
+ t (readall(SOCK_FILENO, &message, &n));
+ t (n < sizeof(int) + sizeof(clk) + sizeof(ts));
+ n -= sizeof(int) + sizeof(clk) + sizeof(ts);
+ 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);
+ n += sizeof(int) + sizeof(clk) + sizeof(ts);
+
+ return 0;
+fail:
+}
+
diff --git a/src/satd-diminished.c b/src/satd-diminished.c
index 9e8edbd..d9efcf2 100644
--- a/src/satd-diminished.c
+++ b/src/satd-diminished.c
@@ -28,18 +28,9 @@
#include <sys/stat.h>
#include <sys/socket.h>
+#include "daemon.h"
-/**
- * The file descriptor for the socket.
- */
-#define SOCK_FILENO 3
-
-/**
- * The file descriptor for the state file.
- */
-#define STATE_FILENO 4
-
/**
* Command: queue a job.
diff --git a/src/satd-list.c b/src/satd-list.c
new file mode 100644
index 0000000..7cbc2bb
--- /dev/null
+++ b/src/satd-list.c
@@ -0,0 +1,49 @@
+/**
+ * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "daemon.h"
+
+
+
+/**
+ * Subroutine to the sat daemon: list jobs.
+ *
+ * @param argc Should be 4.
+ * @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.)
+ * @return 0 The process was successful.
+ * @return 1 The process failed queuing the job.
+ */
+int
+main(int argc, char *argv[])
+{
+ size_t n = 0;
+ char *message = NULL;
+ char **msg_argv = NULL;
+
+ /* Receive and validate message. */
+ t (readall(SOCK_FILENO, &message, &n) || n);
+
+ return 0;
+fail:
+}
+
diff --git a/src/satd-rm.c b/src/satd-rm.c
new file mode 100644
index 0000000..6c4ed38
--- /dev/null
+++ b/src/satd-rm.c
@@ -0,0 +1,51 @@
+/**
+ * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "daemon.h"
+
+
+
+/**
+ * Subroutine to the sat daemon: remove jobs.
+ *
+ * @param argc Should be 4.
+ * @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.)
+ * @return 0 The process was successful.
+ * @return 1 The process failed queuing the job.
+ */
+int
+main(int argc, char *argv[])
+{
+ size_t n = 0;
+ char *message = NULL;
+ char **msg_argv = NULL;
+
+ /* Receive and validate message. */
+ t (readall(SOCK_FILENO, &message, &n) || !n || message[n - 1]);
+ msg_argv = restore_array(message, n, NULL);
+ t (!msg_argv);
+
+ return 0;
+fail:
+}
+
diff --git a/src/satd-run.c b/src/satd-run.c
new file mode 100644
index 0000000..a2679bb
--- /dev/null
+++ b/src/satd-run.c
@@ -0,0 +1,53 @@
+/**
+ * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "daemon.h"
+
+
+
+/**
+ * Subroutine to the sat daemon: run jobs early.
+ *
+ * @param argc Should be 4.
+ * @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.)
+ * @return 0 The process was successful.
+ * @return 1 The process failed queuing the job.
+ */
+int
+main(int argc, char *argv[])
+{
+ size_t n = 0;
+ char *message = NULL;
+ char **msg_argv = NULL;
+
+ /* Receive and validate message. */
+ t (readall(SOCK_FILENO, &message, &n) || (n && message[n - 1]));
+ if (n) {
+ msg_argv = restore_array(message, n, NULL);
+ t (!msg_argv);
+ }
+
+ return 0;
+fail:
+}
+
diff --git a/src/satd.c b/src/satd.c
index f69af3b..bd927cd 100644
--- a/src/satd.c
+++ b/src/satd.c
@@ -30,6 +30,7 @@
#include "daemonise.h"
#include "common.h"
+#include "daemon.h"
@@ -243,16 +244,16 @@ main(int argc, char *argv[])
t (state == -1);
free(path), path = NULL;
- /* The state fill shall be on fd 4. */
- t (dup2_and_null(state, 4) == -1);
- state = 4;
+ /* The state fill shall be on fd STATE_FILENO. */
+ t (dup2_and_null(state, STATE_FILENO) == -1);
+ state = STATE_FILENO;
/* Create socket. */
t (sock = create_socket(&address), sock == -1);
- /* Socket shall be on fd 3. */
- t (dup2_and_null(sock, 3) == -1);
- sock = 3;
+ /* Socket shall be on fd SOCK_FILENO. */
+ t (dup2_and_null(sock, SOCK_FILENO) == -1);
+ sock = SOCK_FILENO;
/* Listen for incoming conections. */
#if SOMAXCONN < SATD_BACKLOG