diff options
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | src/client.c | 2 | ||||
-rw-r--r-- | src/common.h | 8 | ||||
-rw-r--r-- | src/daemon.c | 3 | ||||
-rw-r--r-- | src/daemon.h | 13 | ||||
-rw-r--r-- | src/satd-diminished.c | 4 | ||||
-rw-r--r-- | src/satd-timer.c | 3 | ||||
-rw-r--r-- | src/satd.c | 56 |
8 files changed, 69 insertions, 24 deletions
diff --git a/Makefile.in b/Makefile.in index 7f3f2ea..dcc4126 100644 --- a/Makefile.in +++ b/Makefile.in @@ -102,3 +102,7 @@ _EVERYTHING = $(foreach F,$(___EVERYTHING_INFO),doc/info/$(F).texinfo) \ # All of the make rules and the configurations. include $(v)mk/all.mk +ifdef DEBUG +_CPPFLAGS += -DDEBUG=1 +endif + diff --git a/src/client.c b/src/client.c index a0f58e3..9e5600e 100644 --- a/src/client.c +++ b/src/client.c @@ -65,7 +65,7 @@ send_command(enum command cmd, size_t n, const char *restrict msg) dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run"); if (strlen(dir) + sizeof("/" PACKAGE "/socket") > sizeof(address.sun_path)) t ((errno = ENAMETOOLONG)); - stpcpy(stpcpy(address.sun_path, dir), "/" PACKAGE "/state"); /* Yes, "state", It is temporary. */ + stpcpy(stpcpy(address.sun_path, dir), "/" PACKAGE "/lock"); /* Yes, "lock", It is temporary. */ address.sun_family = AF_UNIX; /* Any daemon listening? */ diff --git a/src/common.h b/src/common.h index 375cf49..1401c37 100644 --- a/src/common.h +++ b/src/common.h @@ -35,7 +35,13 @@ * * @param ... The statement. */ -# define t(...) do { if (__VA_ARGS__) goto fail; } while (0) +# ifdef DEBUG +# define t(...) do { if ((__VA_ARGS__) ? (failed__ = #__VA_ARGS__) : 0) { (perror)(failed__); goto fail; } } while (0) +static const char *failed__ = NULL; +# define perror(_) ((void)(_)) +# else +# define t(...) do { if (__VA_ARGS__) goto fail; } while (0) +# endif #endif diff --git a/src/daemon.c b/src/daemon.c index 830beca..977e845 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -218,8 +218,7 @@ reopen(int fd, int oflag) return -1; if (dup2(r, fd) == -1) return saved_errno = errno, close(r), errno = saved_errno, -1; - close(fd); - return 0; + return close(r), 0; } diff --git a/src/daemon.h b/src/daemon.h index c36e314..567e268 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -55,6 +55,11 @@ */ #define REAL_FILENO 6 +/** + * The file descriptor for the lock file. + */ +#define LOCK_FILENO 7 + /** * Command: queue a job. @@ -84,7 +89,13 @@ * * @param ... The statement. */ -# define t(...) do { if (__VA_ARGS__) goto fail; } while (0) +# ifdef DEBUG +# define t(...) do { if ((__VA_ARGS__) ? (failed__ = #__VA_ARGS__) : 0) { (perror)(failed__); goto fail; } } while (0) +static const char *failed__ = NULL; +# define perror(_) ((void)(_)) +# else +# define t(...) do { if (__VA_ARGS__) goto fail; } while (0) +# endif #endif diff --git a/src/satd-diminished.c b/src/satd-diminished.c index 5316398..f0df567 100644 --- a/src/satd-diminished.c +++ b/src/satd-diminished.c @@ -113,10 +113,10 @@ fork_again: goto child_fail; } if (command < 0) { - close(SOCK_FILENO); + close(SOCK_FILENO), close(LOCK_FILENO); execve(image, argv, envp); } else { - close(BOOT_FILENO), close(REAL_FILENO); + close(BOOT_FILENO), close(REAL_FILENO), close(LOCK_FILENO); if (dup2(fd, SOCK_FILENO) != -1) close(fd), fd = SOCK_FILENO, execve(image, argv, envp); } diff --git a/src/satd-timer.c b/src/satd-timer.c index 4550465..310c23d 100644 --- a/src/satd-timer.c +++ b/src/satd-timer.c @@ -63,6 +63,8 @@ main(int argc, char *argv[]) struct job **job; int rc = 0; + t (reopen(STATE_FILENO, O_RDWR)); + /* Get current expiration time. */ t (timerfd_gettime(BOOT_FILENO, &bootspec)); t (timerfd_gettime(REAL_FILENO, &realspec)); @@ -88,6 +90,7 @@ done: for (job = jobs; *job; job++) free(*job); free(jobs); + close(STATE_FILENO); return rc; fail: perror(argv[0]); @@ -48,7 +48,7 @@ USAGE("[-f]") /** - * Create the socket, but not its directory. + * Create the socket. * * @param address Output parameter for the socket address. * @return The file descriptor for the socket, -1 on error. @@ -89,11 +89,7 @@ fail: /** - * Create the state file, and its directory. - * - * This will also check that the daemon is not - * running. The daemon holds a shared lock on - * the state file. + * Create the state file. * * @return A file descriptor to the state file, -1 on error. */ @@ -102,34 +98,58 @@ create_state(void) { const char *dir; char *path; - char *p; - int fd, saved_errno; + int fd = -1, saved_errno; /* Create directory. */ dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run"); t (!(path = malloc(strlen(dir) * sizeof(char) + sizeof("/" PACKAGE "/state")))); + stpcpy(stpcpy(path, dir), "/" PACKAGE "/state"); + t (fd = open(path, O_RDWR | O_CREAT /* but not O_EXCL or O_TRUNC */, S_IRUSR | S_IWUSR), fd == -1); + +fail: + saved_errno = errno; + free(path); + errno = saved_errno; + return fd; +} + + +/** + * Create and lock the lock file, and its directory. + * + * @return A file descriptor to the lock file, -1 on error. + */ +static int +create_lock(void) +{ + const char *dir; + char *path; + char *p; + int fd = -1, saved_errno; + + /* Create directory. */ + dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run"); + t (!(path = malloc(strlen(dir) * sizeof(char) + sizeof("/" PACKAGE "/lock")))); p = stpcpy(stpcpy(path, dir), "/" PACKAGE); t (mkdir(path, S_IRWXU) && (errno != EEXIST)); /* Open file. */ - stpcpy(p, "/state"); - t (fd = open(path, O_RDWR | O_CREAT /* but not O_EXCL */, S_IRUSR | S_IWUSR), fd == -1); - free(path), path = NULL; + stpcpy(p, "/lock"); + t (fd = open(path, O_RDWR | O_CREAT /* but not O_EXCL or O_TRUNC */, S_IRUSR | S_IWUSR), fd == -1); /* Check that the daemon is not running, and mark it as running. */ if (flock(fd, LOCK_EX | LOCK_NB)) { - t (errno != EWOULDBLOCK); + t (fd = -1, errno != EWOULDBLOCK); fprintf(stderr, "%s: the daemon's state file is already in use.\n", argv0); errno = 0; goto fail; } - return fd; fail: saved_errno = errno; free(path); errno = saved_errno; - return -1; + return fd; } @@ -230,7 +250,7 @@ main(int argc, char *argv[]) t (path = path ? path : hookpath(PRE, SUF), !path && errno) struct sockaddr_un address; - int sock = -1, state = -1, boot = -1, real = -1, foreground = 0; + int sock = -1, state = -1, boot = -1, real = -1, lock = -1, foreground = 0; char *path = NULL; struct itimerspec spec; @@ -250,7 +270,8 @@ main(int argc, char *argv[]) free(path), path = NULL; } - /* Open/create state file, and create socket. */ + /* Open/create lock file and state file, and create socket. */ + GET_FD(lock, LOCK_FILENO, create_lock()); GET_FD(state, STATE_FILENO, create_state()); GET_FD(sock, SOCK_FILENO, create_socket(&address)); @@ -271,7 +292,7 @@ main(int argc, char *argv[]) #endif /* Daemonise. */ - t (foreground ? 0 : daemonise("satd", DAEMONISE_KEEP_FDS | DAEMONISE_NEW_PID, 3, 4, 5, 6, -1)); + t (foreground ? 0 : daemonise("satd", DAEMONISE_KEEP_FDS | DAEMONISE_NEW_PID, 3, 4, 5, 6, 7, -1)); /* Change to a process image without all this initialisation text. */ execl(LIBEXECDIR "/" PACKAGE "/satd-diminished", argv0, address.sun_path, NULL); @@ -287,6 +308,7 @@ fail: if (state >= 0) close(state); if (boot >= 0) close(boot); if (real >= 0) close(real); + if (lock >= 0) close(lock); undaemonise(); return 1; } |