aboutsummaryrefslogtreecommitdiffstats
path: root/src/satd.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@member.fsf.org>2015-12-31 02:22:30 +0100
committerMattias Andrée <maandree@member.fsf.org>2015-12-31 02:25:33 +0100
commitc6754b16c19726bbe38d0d7473147e19dc561b35 (patch)
tree7c4bca36245b1a34513a06983d0bd08d50965a15 /src/satd.c
parentwrapping (diff)
downloadsat-c6754b16c19726bbe38d0d7473147e19dc561b35.tar.gz
sat-c6754b16c19726bbe38d0d7473147e19dc561b35.tar.bz2
sat-c6754b16c19726bbe38d0d7473147e19dc561b35.tar.xz
some improvements and fixes
Signed-off-by: Mattias Andrée <maandree@member.fsf.org>
Diffstat (limited to '')
-rw-r--r--src/satd.c125
1 files changed, 70 insertions, 55 deletions
diff --git a/src/satd.c b/src/satd.c
index df2cda9..0b8160c 100644
--- a/src/satd.c
+++ b/src/satd.c
@@ -48,7 +48,7 @@ USAGE("[-f]")
/**
- * Create the socket.
+ * Create the socket, but not its directory.
*
* @param address Output parameter for the socket address.
* @return The file descriptor for the socket, -1 on error.
@@ -63,37 +63,19 @@ create_socket(struct sockaddr_un *address)
/* Get socket address. */
dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run");
- if (strlen(dir) + sizeof("/satd.socket") > sizeof(address->sun_path))
+ if (strlen(dir) + sizeof("/" PACKAGE "/socket") > sizeof(address->sun_path))
t ((errno = ENAMETOOLONG));
- stpcpy(stpcpy(address->sun_path, dir), "/satd.socket");
+ stpcpy(stpcpy(address->sun_path, dir), "/" PACKAGE "/socket");
address->sun_family = AF_UNIX;
- /* Check that no living process owns the socket. */
- fd = open(address->sun_path, O_RDONLY);
- if (fd == -1) {
- t (errno != ENOENT);
- goto does_not_exist;
- } else if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
- t (errno != EWOULDBLOCK);
- fprintf(stderr, "%s: the daemon's socket file is already in use.\n", argv0);
- errno = 0;
- goto fail;
- }
-
/* Create socket. */
unlink(address->sun_path);
- flock(fd, LOCK_UN);
- close(fd), fd = -1;
-does_not_exist:
t ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1);
t (fchmod(fd, S_IRWXU) == -1);
t (bind(fd, (const struct sockaddr *)(_cvoid = address), (socklen_t)sizeof(*address)) == -1);
/* EADDRINUSE just means that the file already exists, not that it is actually used. */
bound = 1;
- /* Mark the socket as owned by a living process. */
- t (flock(fd, LOCK_SH));
-
return fd;
fail:
saved_errno = errno;
@@ -107,6 +89,51 @@ 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.
+ *
+ * @return A file descriptor to the state file, -1 on error.
+ */
+static int
+create_state(void)
+{
+ const char *dir;
+ char *path;
+ char *p;
+ int fd, saved_errno;
+
+ /* Create directory. */
+ dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run");
+ t (!(path = malloc(strlen(dir) * sizeof(char) + sizeof("/" PACKAGE "/state"))));
+ 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;
+
+ /* Check that the daemon is not running, and mark it as running. */
+ if (flock(fd, LOCK_EX | LOCK_NB)) {
+ t (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;
+}
+
+
+/**
* Construct the pathname for the hook script.
*
* @param env The environment variable to use for the beginning
@@ -159,16 +186,16 @@ fail:
static int
dup2_and_null(int old, int new)
{
- int want, fd = -1;
+ int fd = -1;
int saved_errno;
if (old == new) goto done;
t (dup2(old, new) == -1);
- close(old), want = old;
- if (want >= 3) goto done;
+ close(old);
+ if (old >= 3) goto done;
t (fd = open("/dev/null", O_RDWR), fd == -1);
- if (fd == want) goto done;
- t (dup2(fd, want) == -1);
+ if (fd == old) goto done;
+ t (dup2(fd, old) == -1);
close(fd), fd = -1;
done:
@@ -195,11 +222,17 @@ fail:
int
main(int argc, char *argv[])
{
+#define GET_FD(FD, WANT, CALL) \
+ t (FD = CALL, FD == -1); \
+ t (dup2_and_null(FD, WANT) == -1); \
+ FD = WANT
+#define HOOKPATH(PRE, SUF) \
+ t (path = path ? path : hookpath(PRE, SUF), !path && errno)
+
struct sockaddr_un address;
int sock = -1, state = -1, boot = -1, real = -1, foreground = 0;
char *path = NULL;
struct itimerspec spec;
- const char *dir;
/* Parse command line. */
if (argc > 0) argv0 = argv[0];
@@ -210,38 +243,20 @@ main(int argc, char *argv[])
/* Get hook-script pathname. */
if (!getenv("SAT_HOOK_PATH")) {
- t (path = hookpath("XDG_CONFIG_HOME", "/sat/hook"), !path && errno);
- t (path = path ? path : hookpath("HOME", "/.config/sat/hook"), !path && errno);
- t (path = path ? path : hookpath(NULL, "/.config/sat/hook"), !path && errno);
+ HOOKPATH("XDG_CONFIG_HOME", "/sat/hook");
+ HOOKPATH("HOME", "/.config/sat/hook");
+ HOOKPATH(NULL, "/.config/sat/hook");
t (setenv("SAT_HOOK_PATH", path ? path : "/etc/sat/hook", 1));
free(path), path = NULL;
}
- /* Open/create state file. */
- dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run");
- t (!(path = malloc(strlen(dir) * sizeof(char) + sizeof("/satd.state"))));
- stpcpy(stpcpy(path, dir), "/satd.state");
- t (state = open(path, O_RDWR | O_CREAT /* but not O_EXCL */, S_IRWXU), state == -1);
- free(path), path = NULL;
-
- /* The state file 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);
- t (dup2_and_null(sock, SOCK_FILENO) == -1);
- sock = SOCK_FILENO;
-
- /* Create CLOCK_BOOTTIME timer. */
- t (boot = timerfd_create(CLOCK_BOOTTIME, 0), boot == -1);
- t (dup2_and_null(boot, BOOT_FILENO) == -1);
- boot = BOOT_FILENO;
+ /* Open/create state file, and create socket. */
+ GET_FD(state, STATE_FILENO, create_state());
+ GET_FD(sock, SOCK_FILENO, create_socket(&address));
- /* Create CLOCK_REALTIME timer. */
- t (real = timerfd_create(CLOCK_REALTIME, 0), real == -1);
- t (dup2_and_null(real, BOOT_FILENO) == -1);
- real = BOOT_FILENO;
+ /* Create timers. */
+ GET_FD(boot, BOOT_FILENO, timerfd_create(CLOCK_BOOTTIME, 0));
+ GET_FD(real, REAL_FILENO, timerfd_create(CLOCK_REALTIME, 0));
/* Configure timers. */
memset(&spec, 0, sizeof(spec));
@@ -256,7 +271,7 @@ main(int argc, char *argv[])
#endif
/* Daemonise. */
- t (foreground ? 0 : daemonise("satd", DAEMONISE_KEEP_FDS, 3, 4, 5, 6, -1));
+ t (foreground ? 0 : daemonise("satd", DAEMONISE_KEEP_FDS | DAEMONISE_NEW_PID, 3, 4, 5, 6, -1));
/* Change to a process image without all this initialisation text. */
execl(LIBEXECDIR "/" PACKAGE "/satd-diminished", argv0, address.sun_path, NULL);