aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in4
-rw-r--r--src/client.c2
-rw-r--r--src/common.h8
-rw-r--r--src/daemon.c3
-rw-r--r--src/daemon.h13
-rw-r--r--src/satd-diminished.c4
-rw-r--r--src/satd-timer.c3
-rw-r--r--src/satd.c56
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]);
diff --git a/src/satd.c b/src/satd.c
index 0b8160c..5b0eaf6 100644
--- a/src/satd.c
+++ b/src/satd.c
@@ -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;
}