diff options
-rw-r--r-- | src/satd-diminished.c | 11 | ||||
-rw-r--r-- | src/satd.c | 84 |
2 files changed, 74 insertions, 21 deletions
diff --git a/src/satd-diminished.c b/src/satd-diminished.c index 7120b45..82ab1cf 100644 --- a/src/satd-diminished.c +++ b/src/satd-diminished.c @@ -29,6 +29,11 @@ */ #define SOCK_FILENO 3 +/** + * The file descriptor for the state file. + */ +#define STATE_FILENO 4 + /** * Command: queue a job. @@ -55,9 +60,10 @@ /** * The sat daemon. * - * @param argc Should be 3. + * @param argc Should be 4 * @param argv The name of the process, the pathname of the socket, - * and $SAT_HOOK_PATH (the pathname of the hook-script.) + * 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. */ @@ -72,6 +78,7 @@ main(int argc, char *argv[]) close(SOCK_FILENO); unlink(argv[1]); + unlink(argv[2]); /* Only on success! */ return 0; (void) argc; } @@ -22,6 +22,7 @@ #include <unistd.h> #include <errno.h> #include <pwd.h> +#include <fcntl.h> #include <sys/stat.h> #include <sys/socket.h> #include <sys/un.h> @@ -151,6 +152,45 @@ try_next: /** + * Duplicate a file descriptor, and + * open /dev/null to the old file descriptor. + * However, if `old` is 3 or greater, it will + * be closed rather than /dev/null. + * + * @param old The old file descriptor. + * @param new The new file descriptor. + * @return `new`, -1 on error. + */ +static int +dup2_and_null(int old, int new) +{ + int want, fd = -1; + int saved_errno; + + if (old != new) { + t (dup2(old, new) == -1); + close(old), want = old; + if (want < 3) { + fd = open("/dev/null", O_RDWR); + t (fd == -1); + if (fd != want) { + t (dup2(fd, want) == -1); + close(fd), fd = -1; + } + } + } + + return new; +fail: + saved_errno = errno; + if (fd >= 0) + close(fd); + errno = saved_errno; + return -1; +} + + +/** * The sat daemon initialisation. * * @param argc Any value in [0, 2] is accepted. @@ -164,9 +204,11 @@ int main(int argc, char *argv[]) { struct sockaddr_un address; - int sock = -1, foreground = 0, fd = -1; + int sock = -1, state = -1, foreground = 0; struct stat attr; - char *path; + char *path = NULL; + char *dir; + ssize_t len; /* Parse command line. */ if (argc > 0) argv0 = argv[0]; @@ -188,25 +230,29 @@ main(int argc, char *argv[]) t (setenv("SAT_HOOK_PATH", path, 1)); if (!do_not_free) free(path); + path = NULL; } + /* Open/create state file. */ + dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run"); + t (snprintf(NULL, 0, "%s/satd.state%zn", dir, &len) == -1); + path = malloc(((size_t)len + 1) * sizeof(char)); + t (!path); + sprintf(path, "%s/satd.state", dir); + state = open(path, O_RDWR | O_CREAT /* but not O_EXCL */, S_IRWXU); + t (state == -1); + free(path), path = NULL; + + /* The state fill shall be on fd 4. */ + t (dup2_and_null(state, 4) == -1); + state = 4; + /* Create socket. */ t (sock = create_socket(&address), sock == -1); - /* Socket shall be on fd 3, and all below shall be /dev/null. */ - if (sock != 3) { - int want; - t (dup2(sock, 3) == -1); - close(sock), want = sock, sock = 3; - if (want < 3) { - fd = open("/dev/null", O_RDWR); - t (fd == -1); - if (fd != want) { - t (dup2(fd, want) == -1); - close(fd), fd = -1; - } - } - } + /* Socket shall be on fd 3. */ + t (dup2_and_null(sock, 3) == -1); + sock = 3; /* Listen for incoming conections. */ #if SOMAXCONN < SATD_BACKLOG @@ -225,13 +271,13 @@ main(int argc, char *argv[]) fail: if (errno) perror(argv0); + free(path); if (sock >= 0) { close(sock); unlink(address.sun_path); } - if (fd >= 0) { - close(fd); - } + if (state >= 0) + close(state); undaemonise(); return 1; } |