aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/client.c20
-rw-r--r--src/client.h2
-rw-r--r--src/common.h8
-rw-r--r--src/daemon.c79
-rw-r--r--src/daemon.h21
-rw-r--r--src/daemonise.c2
-rw-r--r--src/daemonise.h2
-rw-r--r--src/parse_time.c107
-rw-r--r--src/parse_time.h2
-rw-r--r--src/sat.c10
-rw-r--r--src/satd-add.c16
-rw-r--r--src/satd-diminished.c101
-rw-r--r--src/satd-list.c115
-rw-r--r--src/satd-rm.c5
-rw-r--r--src/satd-run.c7
-rw-r--r--src/satd-timer.c2
-rw-r--r--src/satd.c96
-rw-r--r--src/satq.c2
-rw-r--r--src/satr.c2
-rw-r--r--src/satrm.c2
20 files changed, 257 insertions, 344 deletions
diff --git a/src/client.c b/src/client.c
index b37b9e3..3573f46 100644
--- a/src/client.c
+++ b/src/client.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -99,7 +99,7 @@ send_command(enum command cmd, size_t n, const char *restrict msg)
/* Create socket. */
stpcpy(strrchr(address.sun_path, '/'), "/socket");
t ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1);
- t (connect(fd, (const struct sockaddr *)(_cvoid = &address), (socklen_t)sizeof(address)) == -1);
+ t (connect(fd, (const struct sockaddr *)(_cvoid = &address), (socklen_t)sizeof(address)));
/* Send message. */
t (write(fd, &cmd_, sizeof(cmd_)) < (ssize_t)sizeof(cmd_));
@@ -133,10 +133,8 @@ receive_again:
goto receive_again;
done:
- shutdown(fd, SHUT_RD);
- close(fd);
- errno = 0;
- return -goterr;
+ shutdown(fd, SHUT_RD), close(fd);
+ return errno = 0, -goterr;
fail:
saved_errno = (goterr ? 0 : errno);
@@ -144,8 +142,7 @@ fail:
close(fd);
free(buf);
errno = saved_errno;
- if (eot)
- goto done;
+ if (eot) goto done;
return -1;
}
@@ -160,8 +157,7 @@ size_t
measure_array(char *array[])
{
size_t rc = 0;
- for (; *array; array++)
- rc += strlen(*array) + 1;
+ while (*array) rc += strlen(*array++) + 1;
return rc * sizeof(char);
}
@@ -176,10 +172,8 @@ measure_array(char *array[])
char *
store_array(char *restrict storage, char *array[])
{
- for (; *array; array++) {
+ for (; *array; array++, storage++)
storage = stpcpy(storage, *array);
- *storage++ = 0;
- }
return storage;
}
diff --git a/src/client.h b/src/client.h
index 22ff1ac..a7640e7 100644
--- a/src/client.h
+++ b/src/client.h
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
diff --git a/src/common.h b/src/common.h
index 1401c37..68d465e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -35,12 +35,12 @@
*
* @param ... The statement.
*/
-# ifdef DEBUG
+# ifndef DEBUG
+# define t(...) do { if (__VA_ARGS__) goto fail; } while (0)
+# else
# 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 e9c79d9..e4c444e 100644
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -52,9 +52,9 @@ extern char **environ;
if (r == 0) \
break; \
n += r; \
- nbyte -= (size_t)r; \
+ buffer += r; \
offset += (size_t)r; \
- buffer += (size_t)r; \
+ nbyte -= (size_t)r; \
} \
done: \
sigprocmask(SIG_SETMASK, &oldmask, NULL); \
@@ -103,8 +103,6 @@ pwriten(int fildes, const void *buf, size_t nbyte, size_t offset)
/**
* 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.
@@ -118,21 +116,20 @@ readall(int fd, char **buf, size_t *n)
{
char *buffer = NULL;
size_t ptr = 0, size = 128;
- ssize_t got = 1;
+ ssize_t got;
char *new;
int saved_errno;
- for (; got; ptr += (size_t)got) {
+ do {
if ((buffer == NULL) || (ptr == size)) {
t (!(new = realloc(buffer, size <<= 1)));
buffer = new;
}
t (got = read(fd, buffer + ptr, size - ptr), got < 0);
- }
+ } while (ptr += (size_t)got, got);
- new = realloc(buffer, ptr);
+ new = realloc(buffer, *n = ptr);
*buf = ptr ? (new ? new : buffer) : NULL;
- *n = ptr;
shutdown(SOCK_FILENO, SHUT_RD);
return 0;
@@ -164,15 +161,12 @@ restore_array(char *buf, size_t len, size_t *n)
char **rc = malloc((len + 1) * sizeof(char*));
char **new = NULL;
size_t i = 0, e = 0;
+
t (!rc);
- while (i < len) {
- rc[e++] = buf + i;
- i += strlen(buf + i) + 1;
- }
- rc[e] = NULL;
- new = realloc(rc, (e + 1) * sizeof(char*));
- if (n)
- *n = e;
+ while (i < len) i += strlen(rc[e++] = buf + i) + 1;
+ if (n) *n = e;
+ rc[e++] = NULL;
+ new = realloc(rc, e * sizeof(char*));
fail:
return new ? new : rc;
}
@@ -216,9 +210,9 @@ reopen(int fd, int oflag)
sprintf(path, "/dev/fd/%i", fd);
if (r = open(path, oflag), r < 0)
return -1;
- if (dup2(r, fd) == -1)
+ if (DUP2_AND_CLOSE(r, fd) == -1)
return saved_errno = errno, close(r), errno = saved_errno, -1;
- return close(r), 0;
+ return 0;
}
@@ -245,7 +239,7 @@ send_string(int sockfd, int outfd, ...)
va_end(args);
t (write(sockfd, &out, sizeof(out)) < (ssize_t)sizeof(out));
- t (write(sockfd, &n, sizeof(n)) < (ssize_t)sizeof(n));
+ t (write(sockfd, &n, sizeof(n)) < (ssize_t)sizeof(n));
va_start(args, outfd);
while ((s = va_arg(args, const char *)))
@@ -290,28 +284,19 @@ run_job_or_hook(struct job *job, const char *hook)
argv[1] = (strstr)(hook, hook); /* strstr: just to remove a warning */
}
- switch ((pid = fork())) {
- case -1:
- goto fail;
- case 0:
- close(SOCK_FILENO);
- close(STATE_FILENO);
- close(BOOT_FILENO);
- close(REAL_FILENO);
+ if (!(pid = fork())) {
+ close(SOCK_FILENO), close(STATE_FILENO);
+ close(BOOT_FILENO), close(REAL_FILENO);
(void)(status = chdir(envp[0]));
environ = envp + 1;
execvp(*argv, argv);
exit(1);
- default:
- t (waitpid(pid, &status, 0) != pid);
- break;
}
+ t ((pid < 0) || (waitpid(pid, &status, 0) != pid));
fail:
saved_errno = errno;
- free(args);
- free(argv);
- free(envp);
+ free(args), free(argv), free(envp);
errno = saved_errno;
return status ? 1 : -!!saved_errno;
}
@@ -336,7 +321,7 @@ remove_job(const char *jobno, int runjob)
struct stat attr;
struct job job;
struct job *job_full = NULL;
- int rc = 0, saved_errno;
+ int rc = 0, saved_errno = 0;
if (jobno) {
no = (errno = 0, strtoul)(jobno, &end, 10);
@@ -351,11 +336,11 @@ remove_job(const char *jobno, int runjob)
if (!jobno || (job.no == no))
goto found_it;
}
- t (flock(STATE_FILENO, LOCK_UN));
+ flock(STATE_FILENO, LOCK_UN); /* Failure isn't fatal. */
return errno = 0, -1;
found_it:
- job_full = malloc(sizeof(job) + job.n);
+ t (!(job_full = malloc(sizeof(job) + job.n)));
*job_full = job;
t (preadn(STATE_FILENO, job_full->payload, job.n, off + sizeof(job)) < (ssize_t)(job.n));
n -= off + sizeof(job) + job.n;
@@ -372,21 +357,19 @@ found_it:
saved_errno = errno;
run_job_or_hook(job_full, rc ? "failure" : "success");
rc = rc == 1 ? 0 : rc;
- free(job_full);
- errno = saved_errno;
} else {
run_job_or_hook(job_full, "removed");
- free(job_full);
}
- flock(STATE_FILENO, LOCK_UN); /* Unlock late so that hooks are synchronised. */
+ free(job_full);
+ flock(STATE_FILENO, LOCK_UN); /* Unlock late so that hooks are synchronised. Failure isn't fatal. */
+ errno = saved_errno;
return rc;
fail:
saved_errno = errno;
flock(STATE_FILENO, LOCK_UN);
- free(buf);
- free(job_full);
+ free(buf), free(job_full);
errno = saved_errno;
return -1;
}
@@ -418,16 +401,14 @@ get_jobs(void)
t (preadn(STATE_FILENO, js[j++]->payload, job.n, off) < (ssize_t)(job.n));
off += job.n;
}
- js[j] = NULL;
t (flock(STATE_FILENO, LOCK_UN));
- return js;
+ return js[j] = NULL, js;
fail:
saved_errno = errno;
- while (j--)
- free(js[j]);
- free(js);
flock(STATE_FILENO, LOCK_UN);
+ while (j--) free(js[j]);
+ free(js);
errno = saved_errno;
return NULL;
}
diff --git a/src/daemon.h b/src/daemon.h
index 5aaa1c6..d860d1f 100644
--- a/src/daemon.h
+++ b/src/daemon.h
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -89,18 +89,29 @@
*
* @param ... The statement.
*/
-# ifdef DEBUG
+# ifndef DEBUG
+# define t(...) do { if (__VA_ARGS__) goto fail; } while (0)
+# else
# 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
/**
+ * `dup2(OLD, NEW)` and, on success, `close(OLD)`.
+ *
+ * @param OLD:int The file descriptor to duplicate and close.
+ * @param NEW:int The new file descriptor.
+ * @return 0 on success, -1 on error.
+ */
+#define DUP2_AND_CLOSE(OLD, NEW) (dup2(OLD, NEW) == -1 ? -1 : (close(OLD), 0))
+
+
+
+/**
* Macro to put directly after the variable definitions in `main`.
*/
#define DAEMON_PROLOGUE \
@@ -194,8 +205,6 @@ ssize_t pwriten(int fildes, const void *buf, size_t nbyte, size_t offset);
/**
* 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.
diff --git a/src/daemonise.c b/src/daemonise.c
index f8da122..822e0ed 100644
--- a/src/daemonise.c
+++ b/src/daemonise.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
diff --git a/src/daemonise.h b/src/daemonise.h
index 6585154..7bcea08 100644
--- a/src/daemonise.h
+++ b/src/daemonise.h
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
diff --git a/src/parse_time.c b/src/parse_time.c
index 83b0e65..4d4e92d 100644
--- a/src/parse_time.c
+++ b/src/parse_time.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -31,6 +31,9 @@
+#define W(...) do { __VA_ARGS__ } while (0)
+
+
/**
* The number of seconds in a day.
*/
@@ -44,14 +47,21 @@
#define FAIL(e) return errno = (e), -1
/**
+ * Set errno to EINVAL and return if a condition is not met.
+ *
+ * @return cond:int The condition.
+ */
+#define REQUIRE(cond) W(if (!(cond)) FAIL(EINVAL);)
+
+/**
* `a *= b` with overflow check.
*/
-#define MUL(a, b) if (a > timemax / (b)) FAIL(ERANGE); else a *= (b)
+#define MUL(a, b) W(if (a > timemax / (b)) FAIL(ERANGE); else a *= (b);)
/**
* `a += b` with overflow check.
*/
-#define ADD(a, b) if (a > timemax - (b)) FAIL(ERANGE); else a += (b)
+#define ADD(a, b) W(if (a > timemax - (b)) FAIL(ERANGE); else a += (b);)
@@ -63,7 +73,7 @@ extern char *argv0;
/**
* The highest value that can be stored in `time_t`.
*/
-const time_t timemax = (sizeof(time_t) == sizeof(long long int)) ? LLONG_MAX : LONG_MAX;
+static const time_t timemax = (sizeof(time_t) == sizeof(long long int)) ? (time_t)LLONG_MAX : (time_t)LONG_MAX;
@@ -90,24 +100,18 @@ strtotime(const char *str, const char **end)
# pragma GCC diagnostic ignored "-Wcast-qual"
#endif
time_t rc;
- long long int rcll;
- long int rcl;
- if (!isdigit(*str))
- FAIL(EINVAL);
+ REQUIRE(isdigit(*str));
+ errno = 0;
/* The outer if-statement is for when `time_t` is update to `long long int`.
* which is need to avoid the year 2038 problem. Be we have to use `strtol`
* if `time_t` is `long int`, otherwise we will not detect overflow. */
- errno = 0;
- if (sizeof(time_t) == sizeof(long long int)) {
- rcll = strtoll(str, (char **)end, 10);
- rc = (time_t)rcll;
- } else {
- rcl = strtol(str, (char **)end, 10);
- rc = (time_t)rcl;
- }
+ if (sizeof(time_t) == sizeof(long long int))
+ rc = (time_t)strtoll(str, (char **)end, 10);
+ else
+ rc = (time_t)strtol(str, (char **)end, 10);
return errno ? 0 : rc;
#ifdef __GNUC__
@@ -119,40 +123,35 @@ strtotime(const char *str, const char **end)
/**
* Parse a time on the format HH:MM[:SS].
*
- * @param str The time string.
+ * @param str Pointer to time string, will be updated to the end
+ * of the parsing of it.
* @param ts Output parameter for the POSIX time the string
* represents.
- * @param end Output parameter for the end of the parsing of `str`.
* @return 0 on success, -1 on error.
*
* @throws EINVAL `str` could not be parsed.
* @throws ERANGE `str` specifies a time beyond what can be stored.
*/
static int
-parse_time_time(const char *str, struct timespec *ts, const char **end)
+parse_time_time(const char **str, struct timespec *ts)
{
time_t tm;
- memset(ts, 0, sizeof(*ts));
- ts->tv_sec = strtotime(str, end), str = *end;
- t (errno);
+ /* Hours. */
+ t (ts->tv_sec = strtotime(*str, str), errno);
/* Must not be restricted to 23, beyond 24 is legal. */
MUL(ts->tv_sec, (time_t)(60 * 60));
- if (*str++ != ':')
- FAIL(EINVAL);
- tm = strtotime(str, end), str = *end;
- t (errno);
- if (tm >= 60)
- FAIL(EINVAL);
+ /* Minutes. */
+ REQUIRE(*(*str)++ == ':');
+ t (tm = strtotime(*str, str), errno);
+ REQUIRE(tm < 60);
MUL(tm, (time_t)60);
ADD(ts->tv_sec, tm);
- if (*str++ != ':')
- return 0;
-
- tm = strtotime(str, end);
- t (errno);
+ /* Seconds. */
+ if (*(*str)++ != ':') return 0;
+ t (tm = strtotime(*str, str), errno);
/* Do not restrict to 59, or 60, there can be more than +1 leap second. */
ADD(ts->tv_sec, tm);
@@ -165,20 +164,19 @@ fail:
/**
* Parse a time with only a second-count.
*
- * @param str The time string.
+ * @param str Pointer to time string, will be updated to the end
+ * of the parsing of it.
* @param ts Output parameter for the POSIX time the string
* represents.
- * @param end Output parameter for the end of the parsing of `str`.
* @return 0 on success, -1 on error.
*
* @throws EINVAL `str` could not be parsed.
* @throws ERANGE `str` specifies a time beyond what can be stored.
*/
static int
-parse_time_seconds(const char *str, struct timespec *ts, const char **end)
+parse_time_seconds(const char **str, struct timespec *ts)
{
- memset(ts, 0, sizeof(*ts));
- ts->tv_sec = strtotime(str, end);
+ ts->tv_sec = strtotime(*str, str);
return errno ? -1 : 0;
}
@@ -208,12 +206,15 @@ parse_time_seconds(const char *str, struct timespec *ts, const char **end)
int
parse_time(const char *str, struct timespec *ts, clockid_t *clk)
{
+#define FIX_NSEC(T) (((T)->tv_nsec >= 1000000000L) ? ((T)->tv_sec += 1, (T)->tv_nsec -= 1000000000L) : 0L)
+
struct timespec now;
int points, plus = *str == '+';
const char *start = str;
- const char *end;
time_t adj;
+ ts->tv_nsec = 0;
+
/* Get current time and clock. */
*clk = plus ? CLOCK_BOOTTIME : CLOCK_REALTIME;
clock_gettime(*clk, &now);
@@ -226,14 +227,13 @@ parse_time(const char *str, struct timespec *ts, clockid_t *clk)
}
/* HH:MM[:SS[.NNNNNNNNN]] or seconds? */
- if (strchr(str, ':')) {
- t (parse_time_time(str, ts, &end));
+ if (strchr(str += plus, ':')) {
+ t (parse_time_time(&str, ts));
adj = now.tv_sec - (now.tv_sec % ONE_DAY);
ADD(ts->tv_sec, adj); /* In case the HH is really large. */
} else {
- t (parse_time_seconds(str + plus, ts, &end));
+ t (parse_time_seconds(&str, ts));
}
- str = end;
/* Parse up to nanosecond resolution. */
if (*str != '.')
@@ -244,22 +244,19 @@ parse_time(const char *str, struct timespec *ts, clockid_t *clk)
ts->tv_nsec += *str & 15;
} else if ((points == 9) && (*str >= '5')) {
ts->tv_nsec += 1;
+ /* I would like to have FIX_NSEC here, but the
+ * compile will complain and it is not worth it. */
}
}
while (points++ < 9) ts->tv_nsec *= 10;
- if (ts->tv_nsec > 999999999L) {
- ts->tv_sec += 1;
- ts->tv_nsec = 0;
- }
+ FIX_NSEC(ts);
no_nanoseconds:
/* Check for error at end, and missing explicit UTC. */
if (*str) {
- if (*clk == CLOCK_BOOTTIME)
- FAIL(EINVAL);
+ REQUIRE(*clk != CLOCK_BOOTTIME);
while (*str == ' ') str++;
- if (strcasecmp(str, "Z") && strcasecmp(str, "UTC"))
- FAIL(EINVAL);
+ REQUIRE(!strcasecmp(str, "Z") || !strcasecmp(str, "UTC"));
} else if (*clk == CLOCK_REALTIME) {
fprintf(stderr,
"%s: warning: parsing as UTC, you can avoid this warning "
@@ -270,11 +267,7 @@ no_nanoseconds:
if (*clk == CLOCK_BOOTTIME) {
ts->tv_sec += now.tv_sec;
ts->tv_nsec += now.tv_nsec;
- if (ts->tv_nsec >= 1000000000L) {
- ts->tv_sec += 1;
- ts->tv_nsec -= 1000000000L;
- }
- return 0;
+ FIX_NSEC(ts);
} else if (ts->tv_sec < now.tv_sec) { /* Ignore partial second. */
ts->tv_sec += ONE_DAY;
if (ts->tv_sec < now.tv_sec)
@@ -282,7 +275,7 @@ no_nanoseconds:
if (!strchr(start, ':'))
fprintf(stderr,
"%s: warning: the specified time is in the past, "
- "it is being adjust to be tomorrow instead.\n", argv0);
+ "it is being adjust to be tomorrow instead.\n", argv0);
}
return 0;
diff --git a/src/parse_time.h b/src/parse_time.h
index efe5ad5..4b8ada3 100644
--- a/src/parse_time.h
+++ b/src/parse_time.h
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
diff --git a/src/sat.c b/src/sat.c
index e3e1e84..5431208 100644
--- a/src/sat.c
+++ b/src/sat.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -88,11 +88,11 @@ retry:
/* Construct message to send to the daemon. */
n = measure_array(argv) + size + measure_array(envp);
- t (!(msg = malloc(n + sizeof(int) + sizeof(clk) + sizeof(ts))));
+ t (!(msg = malloc(n + sizeof(argc) + sizeof(clk) + sizeof(ts))));
store_array(getcwd(store_array(msg, argv), size) + size, envp);
- 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);
+ memcpy(msg + n, &argc, sizeof(argc)), n += sizeof(argc);
+ 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
index f1fa4ed..fba4465 100644
--- a/src/satd-add.c
+++ b/src/satd-add.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -48,7 +48,7 @@ main(int argc, char *argv[])
/* Receive and validate message. */
t (readall(SOCK_FILENO, &message, &n));
t (n < sizeof(int) + sizeof(clockid_t) + sizeof(struct timespec));
- n -= sizeof(int) + sizeof(clockid_t) + sizeof(struct timespec);
+ n -= sizeof(int) + sizeof(clockid_t) + sizeof(struct timespec);
msg_argc = *(int *)(message + n);
t ((msg_argc < 1) || !n || message[n - 1]);
for (i = n; i--; elements += !message[i]);
@@ -56,11 +56,10 @@ main(int argc, char *argv[])
/* Parse message. */
t (!(job = malloc(sizeof(*job) + n)));
- job->argc = msg_argc;
- job->clk = *(clockid_t *)(message + n + sizeof(int));
- job->ts = *(struct timespec *)(message + n + sizeof(int) + sizeof(clockid_t));
- job->n = n;
- memcpy(job->payload, message, n);
+ job->argc = msg_argc;/* *(int *)(message + n); "See a few lines above."; */
+ job->clk = *(clockid_t *)(message + n + sizeof(int));
+ job->ts = *(struct timespec *)(message + n + sizeof(int) + sizeof(clockid_t));
+ memcpy(job->payload, message, job->n = n);
/* Update state file and run hook. */
t (flock(STATE_FILENO, LOCK_EX));
@@ -73,8 +72,7 @@ main(int argc, char *argv[])
t (pwriten(STATE_FILENO, &(job->no), sizeof(job->no), (size_t)0) < (ssize_t)sizeof(job->no));
if (attr.st_size < (off_t)sizeof(job->no))
attr.st_size = (off_t)sizeof(job->no);
- n += sizeof(*job);
- t (pwriten(STATE_FILENO, job, n, (size_t)(attr.st_size)) < (ssize_t)n);
+ t (pwriten(STATE_FILENO, job, sizeof(*job) + n, (size_t)(attr.st_size)) < (ssize_t)n);
fsync(STATE_FILENO);
run_job_or_hook(job, "queued");
t (flock(STATE_FILENO, LOCK_UN));
diff --git a/src/satd-diminished.c b/src/satd-diminished.c
index 7a9c353..c8c0b53 100644
--- a/src/satd-diminished.c
+++ b/src/satd-diminished.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -65,6 +65,14 @@ static volatile pid_t timer_pid = NO_TIMER_SPAWNED;
*/
static volatile pid_t child_count = 0;
+/**
+ * Timer specification for an unset timer.
+ */
+static const struct itimerspec nilspec = {
+ .it_interval.tv_sec = 0, .it_value.tv_sec = 0,
+ .it_interval.tv_nsec = 0, .it_value.tv_nsec = 0,
+};
+
/**
@@ -103,45 +111,50 @@ sighandler(int signo)
static int
spawn(int command, int fd, char *argv[], char *envp[])
{
+#define IMAGE(CASE, NAME) case CASE: image = DAEMON_IMAGE(NAME); break
+
const char *image;
pid_t pid;
-fork_again:
- switch ((pid = fork())) {
- case -1:
+ /* Try forking until we success. */
+ while ((pid = fork()) == -1) {
if (errno != EAGAIN)
return -1;
(void) sleep(1); /* Possibly shorter because of SIGCHLD. */
- goto fork_again;
- case 0:
- switch (command) {
- case SAT_QUEUE: image = DAEMON_IMAGE("add"); break;
- case SAT_REMOVE: image = DAEMON_IMAGE("rm"); break;
- case SAT_PRINT: image = DAEMON_IMAGE("list"); break;
- case SAT_RUN: image = DAEMON_IMAGE("run"); break;
- case -1: image = DAEMON_IMAGE("timer"); break;
- default:
- fprintf(stderr, "%s: invalid command received.\n", argv[0]);
- goto child_fail;
- }
- if (command < 0) {
- close(SOCK_FILENO), close(LOCK_FILENO);
- execve(image, argv, envp);
- } else {
- close(BOOT_FILENO), close(REAL_FILENO), close(LOCK_FILENO);
- if (dup2(fd, SOCK_FILENO) != -1)
- close(fd), fd = SOCK_FILENO, execve(image, argv, envp);
- }
- perror(argv[0]);
- child_fail:
- close(fd);
- exit(1);
- default:
+ }
+
+ /* Parent. */
+ if (pid) {
child_count++;
if (command < 0)
timer_pid = pid;
return 0;
}
+
+ /* Child. */
+ switch (command) {
+ IMAGE(SAT_QUEUE, "add");
+ IMAGE(SAT_REMOVE, "rm");
+ IMAGE(SAT_PRINT, "list");
+ IMAGE(SAT_RUN, "run");
+ IMAGE(-1, "timer");
+ default:
+ fprintf(stderr, "%s: invalid command received.\n", argv[0]);
+ goto silent_fail;
+ }
+ if (command < 0) {
+ close(LOCK_FILENO), close(SOCK_FILENO);
+ } else {
+ close(LOCK_FILENO), close(BOOT_FILENO), close(REAL_FILENO);
+ t (DUP2_AND_CLOSE(fd, SOCK_FILENO) == -1);
+ fd = SOCK_FILENO;
+ }
+ execve(image, argv, envp);
+fail:
+ perror(argv[0]);
+silent_fail:
+ close(fd);
+ exit(1);
}
@@ -173,14 +186,10 @@ static int
test_timer(int fd, const fd_set *fdset)
{
int64_t _overrun;
- struct itimerspec spec = {
- .it_interval.tv_sec = 0, .it_value.tv_sec = 0,
- .it_interval.tv_nsec = 0, .it_value.tv_nsec = 0,
- };
if (!FD_ISSET(fd, fdset)) return 0;
if (read(fd, &_overrun, (size_t)8) < 8) return -1;
if (timer_pid == NO_TIMER_SPAWNED) return 1;
- return timerfd_settime(fd, TFD_TIMER_ABSTIME, &spec, NULL) ? -1 : 1;
+ return timerfd_settime(fd, TFD_TIMER_ABSTIME, &nilspec, NULL) * 2 + 1;
}
@@ -208,16 +217,17 @@ main(int argc, char *argv[], char *envp[])
/* The magnificent loop. */
again:
+ /* Update the a newer version of the daemon? */
if (received_signo == SIGHUP) {
execve(DAEMON_IMAGE("diminished"), argv, envp);
perror(argv[0]);
}
- if (expired || ((received_signo == SIGCHLD) && (timer_pid == NO_TIMER_SPAWNED))) {
- expired = 0;
- t (spawn(-1, -1, argv, envp));
- }
+ /* Need to set new timer values? */
+ if (expired || ((received_signo == SIGCHLD) && (timer_pid == NO_TIMER_SPAWNED)))
+ t (expired = 0, spawn(-1, -1, argv, envp));
received_signo = 0;
#if 1 || !defined(DEBUG)
+ /* Can we quit yet? */
if (accepted && !child_count) {
t (r = is_timer_set(BOOT_FILENO), r < 0); if (r) goto not_done;
t (r = is_timer_set(REAL_FILENO), r < 0); if (r) goto not_done;
@@ -229,6 +239,7 @@ again:
}
#endif
not_done:
+ /* Wait for something to happen. */
FD_ZERO(&fdset);
FD_SET(SOCK_FILENO, &fdset);
FD_SET(BOOT_FILENO, &fdset);
@@ -237,20 +248,16 @@ not_done:
t (errno != EINTR);
goto again;
}
+ /* Was any jobs expired? */
t ((expired |= test_timer(BOOT_FILENO, &fdset)) < 0);
t ((expired |= test_timer(REAL_FILENO, &fdset)) < 0);
+ /* Accept connections. */
if (!FD_ISSET(SOCK_FILENO, &fdset))
goto again;
if (fd = accept(SOCK_FILENO, NULL, NULL), fd == -1) {
- switch (errno) {
- case ECONNABORTED:
- case EINTR:
- goto again;
- default:
- /* Including EMFILE, ENFILE, and ENOMEM
- * because of potential resource leak. */
- goto fail;
- }
+ t ((errno != ECONNABORTED) && (errno != EINTR));
+ /* Including EMFILE, ENFILE, and ENOMEM because of potential resource leak. */
+ goto again;
}
accepted = 1;
if (read(fd, &type, sizeof(type)) <= 0)
diff --git a/src/satd-list.c b/src/satd-list.c
index 75f7996..12c06a7 100644
--- a/src/satd-list.c
+++ b/src/satd-list.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -38,7 +38,8 @@
static char *
quote(const char *str)
{
-#define UNSAFE(c) strchr(" \"$()[]{};|&^#!?*~`<>", c)
+#define UNSAFE(c) strchr(" \"$()[]{};|&^#!?*~`<>", c)
+#define N(I, S, B, Q) (I*in + S*sn + B*bn + Q*qn + rn)
size_t in = 0; /* < ' ' or 127 */
size_t sn = 0; /* in UNSAFE */
@@ -49,10 +50,6 @@ quote(const char *str)
const unsigned char *s;
char *rc = NULL;
- if (!*str) {
- return strdup("''");
- }
-
for (s = (const unsigned char *)str; *s; s++) {
if (*s < ' ') in++;
else if (*s == 127) in++;
@@ -61,25 +58,20 @@ quote(const char *str)
else if (*s == '\'') qn++;
else rn++;
}
-
- switch (in ? 2 : (sn + bn + qn) ? 1 : 0) {
- case 0:
- return strdup(str);
- case 1:
- n = rn + sn + bn + 4 * qn + 4 * in + 2;
- t (!(rc = malloc((n + 1) * sizeof(char))));
- rc[i++] = '\'';
+ if (N(1, 1, 1, 1) == rn)
+ return strdup(rn ? str : "''");
+
+ n = in ? (N(4, 1, 2, 2) + 3) : (N(0, 1, 1, 4) + 2);
+ t (!(rc = malloc((n + 1) * sizeof(char))));
+ rc[i += !!in] = '$';
+ rc[i += 1] = '\'';
+ if (in == 0) {
for (s = (const unsigned char *)str; *s; s++) {
rc[i++] = (char)*s;
if (*s == '\'')
rc[i++] = '\\', rc[i++] = '\'', rc[i++] = '\'';
}
- break;
- default:
- n = 4 * in + rn + sn + 2 * bn + 2 * qn + 3;
- t (!(rc = malloc((n + 1) * sizeof(char))));
- rc[i++] = '$';
- rc[i++] = '\'';
+ } else {
for (s = (const unsigned char *)str; *s; s++) {
if ((*s < ' ') || (*s == 127)) {
rc[i++] = '\\';
@@ -90,7 +82,6 @@ quote(const char *str)
else if (strchr("\\'", *s)) rc[i++] = '\\', rc[i++] = (char)*s;
else rc[i++] = (char)*s;
}
- break;
}
rc[i++] = '\'';
rc[i] = '\0';
@@ -110,24 +101,14 @@ static void
strduration(char *buffer, time_t s)
{
char *buf = buffer;
- int seconds, minutes, hours;
- seconds = (int)(s % 60), s /= 60;
- minutes = (int)(s % 60), s /= 60;
- hours = (int)(s % 24), s /= 24;
- if (s) {
- buf += sprintf(buf, "%llid", (long long int)s);
- buf += sprintf(buf, "%02i:", hours);
- buf += sprintf(buf, "%02i:", minutes);
- } else if (hours) {
- buf += sprintf(buf, "%i:", hours);
- buf += sprintf(buf, "%02i:", minutes);
- } else if (minutes) {
- buf += sprintf(buf, "%i:", minutes);
- } else {
- sprintf(buf, "%i", seconds);
- return;
- }
- sprintf(buf, "%02i", seconds);
+ int secs, mins, hours, sd = 0, md = 0, hd = 0;
+ secs = (int)(s % 60), s /= 60;
+ mins = (int)(s % 60), s /= 60;
+ hours = (int)(s % 24), s /= 24;
+ if (s) hd++, buf += sprintf(buf, "%llid", (long long int)s);
+ if (hd | hours) md++, buf += sprintf(buf, "%0*i:", ++hd, hours);
+ if (md | mins) sd++, buf += sprintf(buf, "%0*i:", ++md, mins);
+ /*just for alignment*/ buf += sprintf(buf, "%0*i:", ++sd, secs);
}
@@ -140,13 +121,21 @@ strduration(char *buffer, time_t s)
static int
send_job_human(struct job *job)
{
+#define FIX_NSEC(T) (((T)->tv_nsec < 0L) ? ((T)->tv_sec -= 1, (T)->tv_nsec += 1000000000L) : 0L)
+#define ARRAY(LIST) \
+ for (arg = LIST; *arg; arg++) { \
+ free(qstr); \
+ t (!(qstr = quote(*arg))); \
+ t (send_string(SOCK_FILENO, STDOUT_FILENO, " ", qstr, NULL)); \
+ }
+
struct tm *tm;
struct timespec rem;
const char *clk;
char rem_s[3 * sizeof(time_t) + sizeof("d00:00:00")];
char *qstr = NULL;
char *wdir = NULL;
- char line[sizeof("job: %zu clock: unrecognised argc: %i remaining: , argv[0]: ")
+ char line[sizeof("job: %zu clock: unrecognised argc: %i remaining: argv[0]: ")
+ 3 * sizeof(size_t) + 3 * sizeof(int) + sizeof(rem_s) + 9];
char timestr_a[sizeof("-00-00 00:00:00") + 3 * sizeof(time_t)];
char timestr_b[10];
@@ -162,10 +151,7 @@ send_job_human(struct job *job)
return errno == EINVAL ? 0 : -1;
rem.tv_sec = job->ts.tv_sec - rem.tv_sec;
rem.tv_nsec = job->ts.tv_nsec - rem.tv_nsec;
- if (rem.tv_nsec < 0) {
- rem.tv_sec -= 1;
- rem.tv_nsec += 1000000000L;
- }
+ FIX_NSEC(&rem);
if (rem.tv_sec < 0)
/* This job will be removed momentarily, do not list it. (To simply things.) */
return 0;
@@ -181,14 +167,11 @@ send_job_human(struct job *job)
strduration(rem_s, rem.tv_sec);
/* Get textual representation of the expiration time. */
- switch (job->clk) {
- case CLOCK_REALTIME:
+ if (job->clk == CLOCK_REALTIME) {
t (!(tm = localtime(&(job->ts.tv_sec))));
strftime(timestr_a, sizeof(timestr_a), "%Y-%m-%d %H:%M:%S", tm);
- break;
- default:
+ } else {
strduration(timestr_a, job->ts.tv_sec);
- break;
}
sprintf(timestr_b, "%09li", job->ts.tv_nsec);
@@ -202,37 +185,19 @@ send_job_human(struct job *job)
t (!(wdir = quote(envp[0])));
sprintf(line, "job: %zu clock: %s argc: %i remaining: %s.%09li argv[0]: ",
job->no, clk, job->argc, rem_s, rem.tv_nsec);
- t (send_string(SOCK_FILENO, STDOUT_FILENO,
- line, qstr, "\n",
- " time: ", timestr_a, ".", timestr_b, "\n",
- " wdir:", wdir, "\n",
- " argv:",
- NULL));
- for (arg = argv; *arg; arg++) {
- free(qstr);
- t (!(qstr = quote(*arg)));
- t (send_string(SOCK_FILENO, STDOUT_FILENO, " ", qstr, NULL));
- }
- free(qstr), qstr = NULL;
- t (send_string(SOCK_FILENO, STDOUT_FILENO, "\n envp:", NULL));
- for (arg = envp + 1; *arg; arg++) {
- t (!(qstr = quote(*arg)));
- t (send_string(SOCK_FILENO, STDOUT_FILENO, " ", qstr, NULL));
- free(qstr);
- }
- qstr = NULL;
- t (send_string(SOCK_FILENO, STDOUT_FILENO, "\n\n", NULL));
+ t (send_string(SOCK_FILENO, STDOUT_FILENO, line, qstr,
+ "\n time: ", timestr_a, ".", timestr_b,
+ "\n wdir: ", wdir,
+ "\n argv:", NULL));
+ free(qstr);
+ ARRAY(argv); t (send_string(SOCK_FILENO, STDOUT_FILENO, "\n envp:", NULL));
+ ARRAY(envp + 1); t (send_string(SOCK_FILENO, STDOUT_FILENO, "\n\n", NULL));
done:
saved_errno = errno;
- free(qstr);
- free(args);
- free(argv);
- free(wdir);
- free(envp);
+ free(qstr), free(args), free(argv), free(wdir), free(envp);
errno = saved_errno;
return rc;
-
fail:
rc = -1;
goto done;
diff --git a/src/satd-rm.c b/src/satd-rm.c
index 435c302..d33160c 100644
--- a/src/satd-rm.c
+++ b/src/satd-rm.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -43,8 +43,7 @@ main(int argc, char *argv[])
/* Receive and validate message. */
t (readall(SOCK_FILENO, &message, &n) || !n || message[n - 1]);
- msg_argv = restore_array(message, n, NULL);
- t (!msg_argv);
+ t (!(msg_argv = restore_array(message, n, NULL)));
/* Perform action. */
for (arg = msg_argv; *arg; arg++)
diff --git a/src/satd-run.c b/src/satd-run.c
index 9543ca4..cf3f065 100644
--- a/src/satd-run.c
+++ b/src/satd-run.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -43,10 +43,7 @@ main(int argc, char *argv[])
/* 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);
- }
+ t (n && !(msg_argv = restore_array(message, n, NULL)));
/* Perform action. */
if (msg_argv) {
diff --git a/src/satd-timer.c b/src/satd-timer.c
index 671555e..113b50a 100644
--- a/src/satd-timer.c
+++ b/src/satd-timer.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
diff --git a/src/satd.c b/src/satd.c
index 9ec322b..8865c51 100644
--- a/src/satd.c
+++ b/src/satd.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
@@ -39,6 +39,12 @@
#ifndef SATD_BACKLOG
# define SATD_BACKLOG 5
#endif
+#if SATD_BACKLOG > SOMAXCONN
+# undef SATD_BACKLOG
+# defined SATD_BACKLOG SOMAXCONN
+#endif
+
+#define close(fd) (fd < 0 ? 0 : close(fd))
@@ -56,10 +62,9 @@ USAGE("[-f]")
static int
create_socket(struct sockaddr_un *address)
{
- int fd = -1, bound = 0;
const void *_cvoid;
const char *dir;
- int saved_errno;
+ int fd = -1, saved_errno;
/* Get socket address. */
dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run");
@@ -71,19 +76,13 @@ create_socket(struct sockaddr_un *address)
/* Create socket. */
unlink(address->sun_path);
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);
+ t (fchmod(fd, S_IRWXU));
+ t (bind(fd, (const struct sockaddr *)(_cvoid = address), (socklen_t)sizeof(*address)));
/* EADDRINUSE just means that the file already exists, not that it is actually used. */
- bound = 1;
return fd;
fail:
- saved_errno = errno;
- if (fd >= 0)
- close(fd);
- if (bound)
- unlink(address->sun_path);
- errno = saved_errno;
+ saved_errno = errno, close(fd), errno = saved_errno;
return -1;
}
@@ -109,9 +108,7 @@ create_state(char **state_path)
*state_path = path, path = NULL;
fail:
- saved_errno = errno;
- free(path);
- errno = saved_errno;
+ saved_errno = errno, free(path), errno = saved_errno;
return fd;
}
@@ -127,7 +124,7 @@ create_lock(void)
const char *dir;
char *path;
char *p;
- int fd = -1, saved_errno;
+ int fd = -1, saved_errno = 0;
/* Create directory. */
dir = getenv("XDG_RUNTIME_DIR"), dir = (dir ? dir : "/run");
@@ -141,16 +138,17 @@ create_lock(void)
/* Check that the daemon is not running, and mark it as running. */
if (flock(fd, LOCK_EX | LOCK_NB)) {
- t (fd = -1, errno != EWOULDBLOCK);
+ t (errno != EWOULDBLOCK);
fprintf(stderr, "%s: the daemon is already in reading.\n", argv0);
errno = 0;
goto fail;
}
+ goto done;
fail:
- saved_errno = errno;
- free(path);
- errno = saved_errno;
+ saved_errno = errno, close(fd);
+done:
+ free(path), errno = saved_errno;
return fd;
}
@@ -169,29 +167,23 @@ fail:
static char *
hookpath(const char *env, const char *suffix)
{
+ struct passwd *pwd;
const char *prefix = NULL;
char *path;
- struct passwd *pwd;
- if (!env) {
- if (!getuid())
- goto try_next;
+ if (env) {
+ prefix = getenv(env);
+ } else if (getuid()) {
pwd = getpwuid(getuid());
prefix = pwd ? pwd->pw_dir : NULL;
- } else {
- prefix = getenv(env);
}
if (!prefix || !*prefix)
- goto try_next;
+ return errno = 0, NULL;
t (!(path = malloc((strlen(prefix) + strlen(suffix) + 1) * sizeof(char))));
stpcpy(stpcpy(path, prefix), suffix);
-
- return path;
-try_next:
- errno = 0;
fail:
- return NULL;
+ return path;
}
@@ -208,25 +200,14 @@ fail:
static int
dup2_and_null(int old, int new)
{
- int fd = -1;
- int saved_errno;
-
- if (old == new) goto done;
- t (dup2(old, new) == -1);
- close(old);
- if (old >= 3) goto done;
- t (fd = open("/dev/null", O_RDWR), fd == -1);
- if (fd == old) goto done;
- t (dup2(fd, old) == -1);
- close(fd), fd = -1;
+ int fd = -1, saved_errno;
-done:
+ if (old == new) return new; t (DUP2_AND_CLOSE(old, new));
+ if (old >= 3) return new; t (fd = open("/dev/null", O_RDWR), fd == -1);
+ if (fd == old) return new; t (DUP2_AND_CLOSE(fd, old));
return new;
fail:
- saved_errno = errno;
- if (fd >= 0)
- close(fd);
- errno = saved_errno;
+ saved_errno = errno, close(fd), errno = saved_errno;
return -1;
}
@@ -259,9 +240,8 @@ main(int argc, char *argv[])
/* Parse command line. */
if (argc > 0) argv0 = argv[0];
if (argc > 2) usage();
- if (argc == 2)
- if (!(foreground = !strcmp(argv[1], "-f")))
- usage();
+ if ((argc == 2) && (!(foreground = !strcmp(argv[1], "-f"))))
+ usage();
/* Get hook-script pathname. */
if (!getenv("SAT_HOOK_PATH")) {
@@ -287,11 +267,7 @@ main(int argc, char *argv[])
t (timerfd_settime(real, TFD_TIMER_ABSTIME, &spec, NULL));
/* Listen for incoming conections. */
-#if SOMAXCONN < SATD_BACKLOG
- t (listen(sock, SOMAXCONN));
-#else
t (listen(sock, SATD_BACKLOG));
-#endif
/* Daemonise. */
t (foreground ? 0 : daemonise("satd", DAEMONISE_KEEP_FDS | DAEMONISE_NEW_PID, 3, 4, 5, 6, 7, -1));
@@ -303,14 +279,8 @@ fail:
if (errno)
perror(argv0);
free(path);
- if (sock >= 0) {
- unlink(address.sun_path);
- close(sock);
- }
- if (state >= 0) close(state);
- if (boot >= 0) close(boot);
- if (real >= 0) close(real);
- if (lock >= 0) close(lock);
+ if (sock >= 0) unlink(address.sun_path);
+ close(sock), close(state), close(boot), close(real), close(lock);
undaemonise();
return 1;
}
diff --git a/src/satq.c b/src/satq.c
index 048634d..e851c1b 100644
--- a/src/satq.c
+++ b/src/satq.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
diff --git a/src/satr.c b/src/satr.c
index b1a587b..0543d58 100644
--- a/src/satr.c
+++ b/src/satr.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),
diff --git a/src/satrm.c b/src/satrm.c
index 7904416..45f4bc2 100644
--- a/src/satrm.c
+++ b/src/satrm.c
@@ -1,5 +1,5 @@
/**
- * Copyright © 2015 Mattias Andrée <maandree@member.fsf.org>
+ * Copyright © 2015, 2016 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"),