diff options
-rw-r--r-- | src/README | 4 | ||||
-rw-r--r-- | src/common.h | 4 | ||||
-rw-r--r-- | src/daemon.c | 135 | ||||
-rw-r--r-- | src/daemon.h | 89 | ||||
-rw-r--r-- | src/sat.c | 22 | ||||
-rw-r--r-- | src/satd-add.c | 57 | ||||
-rw-r--r-- | src/satd-diminished.c | 11 | ||||
-rw-r--r-- | src/satd-list.c | 49 | ||||
-rw-r--r-- | src/satd-rm.c | 51 | ||||
-rw-r--r-- | src/satd-run.c | 53 | ||||
-rw-r--r-- | src/satd.c | 13 |
11 files changed, 452 insertions, 36 deletions
@@ -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); + @@ -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: +} + @@ -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 |