diff options
-rw-r--r-- | libdaemon/dexec.c | 3 | ||||
-rw-r--r-- | libdaemon/dexec.h | 2 | ||||
-rw-r--r-- | libdaemon/dfork.c | 19 | ||||
-rw-r--r-- | libdaemon/dlog.c | 7 | ||||
-rw-r--r-- | libdaemon/dpid.c | 31 | ||||
-rw-r--r-- | libdaemon/dsignal.c | 4 |
6 files changed, 52 insertions, 14 deletions
diff --git a/libdaemon/dexec.c b/libdaemon/dexec.c index 10c757c..0a21777 100644 --- a/libdaemon/dexec.c +++ b/libdaemon/dexec.c @@ -39,6 +39,7 @@ #include "dlog.h" #include "dsignal.h" +#include "dfork.h" #include "dexec.h" @@ -84,6 +85,8 @@ int daemon_execv(const char *dir, int *ret, const char *prog, va_list ap) { daemon_log(LOG_ERR, "Unable to open /dev/null as STDIN"); _exit(EXIT_FAILURE); } + + daemon_close_all(-1); umask(0022); /* Set up a sane umask */ diff --git a/libdaemon/dexec.h b/libdaemon/dexec.h index 4b74f5e..27b5ba1 100644 --- a/libdaemon/dexec.h +++ b/libdaemon/dexec.h @@ -42,7 +42,7 @@ extern "C" { * the specified pointer. The calling process is blocked until the * child finishes and all child output (either STDOUT or STDIN) has * been written to syslog. Running this function requires that - * daemon_siginal() has been called with SIGCHLD as argument. + * daemon_signal() has been called with SIGCHLD as argument. * * @param dir Working directory for the process. * @param ret A pointer to an integer to write the return value of the program to. diff --git a/libdaemon/dfork.c b/libdaemon/dfork.c index ad7a77f..7a8e0bf 100644 --- a/libdaemon/dfork.c +++ b/libdaemon/dfork.c @@ -280,8 +280,10 @@ void daemon_retval_done(void) { int daemon_retval_send(int i) { ssize_t r; - if (_daemon_retval_pipe[1] < 0) + if (_daemon_retval_pipe[1] < 0) { + errno = EINVAL; return -1; + } r = atomic_write(_daemon_retval_pipe[1], &i, sizeof(i)); @@ -291,8 +293,10 @@ int daemon_retval_send(int i) { if (r < 0) daemon_log(LOG_ERR, "write() failed while writing return value to pipe: %s", strerror(errno)); - else + else { daemon_log(LOG_ERR, "write() too short while writing return value from pipe"); + errno = EINVAL; + } return -1; } @@ -319,8 +323,10 @@ int daemon_retval_wait(int timeout) { if (s < 0) daemon_log(LOG_ERR, "select() failed while waiting for return value: %s", strerror(errno)); - else + else { + errno = ETIMEDOUT; daemon_log(LOG_ERR, "Timeout reached while wating for return value"); + } return -1; } @@ -330,10 +336,13 @@ int daemon_retval_wait(int timeout) { if (r < 0) daemon_log(LOG_ERR, "read() failed while reading return value from pipe: %s", strerror(errno)); - else if (r == 0) + else if (r == 0) { daemon_log(LOG_ERR, "read() failed with EOF while reading return value from pipe."); - else if (r > 0) + errno = EINVAL; + } else if (r > 0) { daemon_log(LOG_ERR, "read() too short while reading return value from pipe."); + errno = EINVAL; + } return -1; } diff --git a/libdaemon/dlog.c b/libdaemon/dlog.c index 3748cf8..f832147 100644 --- a/libdaemon/dlog.c +++ b/libdaemon/dlog.c @@ -26,6 +26,7 @@ #include <stdarg.h> #include <stdio.h> #include <string.h> +#include <errno.h> #include "dlog.h" @@ -33,6 +34,9 @@ enum daemon_log_flags daemon_log_use = DAEMON_LOG_AUTO|DAEMON_LOG_STDERR; const char* daemon_log_ident = NULL; void daemon_logv(int prio, const char* template, va_list arglist) { + int saved_errno; + + saved_errno = errno; if (daemon_log_use & DAEMON_LOG_SYSLOG) { openlog(daemon_log_ident ? daemon_log_ident : "UNKNOWN", LOG_PID, LOG_DAEMON); @@ -48,7 +52,8 @@ void daemon_logv(int prio, const char* template, va_list arglist) { vfprintf(stdout, template, arglist); fprintf(stdout, "\n"); } - + + errno = saved_errno; } void daemon_log(int prio, const char* template, ...) { diff --git a/libdaemon/dpid.c b/libdaemon/dpid.c index e25b7ad..4cfba91 100644 --- a/libdaemon/dpid.c +++ b/libdaemon/dpid.c @@ -78,9 +78,13 @@ pid_t daemon_pid_file_is_running(void) { int fd = -1, locked = -1; pid_t ret = (pid_t) -1, pid; ssize_t l; + long lpid; + char *e = NULL; - if (!(fn = daemon_pid_file_proc())) + if (!(fn = daemon_pid_file_proc())) { + errno = EINVAL; goto finish; + } if ((fd = open(fn, O_RDWR, 0644)) < 0) { if (errno != ENOENT) @@ -99,16 +103,22 @@ pid_t daemon_pid_file_is_running(void) { } txt[l] = 0; + + errno = 0; + lpid = strtol(txt, &e, 10); + pid = (pid_t) lpid; - if ((pid = (pid_t) atoi(txt)) <= 0) { + if (errno != 0 || !e || *e || (long) pid != lpid) { daemon_log(LOG_WARNING, "PID file corrupt, removing. (%s)", fn); unlink(fn); goto finish; } if (kill(pid, 0) != 0 && errno != EPERM) { + int saved_errno = errno; daemon_log(LOG_WARNING, "Process %lu died: %s; removing PID file. (%s)", (unsigned long) pid, strerror(errno), fn); unlink(fn); + errno = saved_errno; goto finish; } @@ -117,8 +127,10 @@ pid_t daemon_pid_file_is_running(void) { finish: if (fd >= 0) { + int saved_errno = errno; if (locked >= 0) lock_file(fd, 0); + errno = saved_errno; close(fd); } @@ -180,8 +192,10 @@ int daemon_pid_file_create(void) { u = umask(022); - if (!(fn = daemon_pid_file_proc())) + if (!(fn = daemon_pid_file_proc())) { + errno = EINVAL; goto finish; + } if ((fd = open(fn, O_CREAT|O_RDWR|O_EXCL, 0644)) < 0) { daemon_log(LOG_ERR, "open(%s): %s", fn, strerror(errno)); @@ -189,15 +203,19 @@ int daemon_pid_file_create(void) { } if ((locked = lock_file(fd, 1)) < 0) { + int saved_errno = errno; unlink(fn); + errno = saved_errno; goto finish; } snprintf(t, sizeof(t), "%lu\n", (unsigned long) getpid()); if (write(fd, t, l = strlen(t)) != l) { + int saved_errno = errno; daemon_log(LOG_WARNING, "write(): %s", strerror(errno)); unlink(fn); + errno = saved_errno; goto finish; } @@ -206,10 +224,13 @@ int daemon_pid_file_create(void) { finish: if (fd >= 0) { + int saved_errno = errno; + if (locked >= 0) lock_file(fd, 0); close(fd); + errno = saved_errno; } umask(u); @@ -220,8 +241,10 @@ finish: int daemon_pid_file_remove(void) { const char *fn; - if (!(fn = daemon_pid_file_proc())) + if (!(fn = daemon_pid_file_proc())) { + errno = EINVAL; return -1; + } if (unlink(fn) < 0) return -1; diff --git a/libdaemon/dsignal.c b/libdaemon/dsignal.c index faa832b..3e156c1 100644 --- a/libdaemon/dsignal.c +++ b/libdaemon/dsignal.c @@ -50,7 +50,6 @@ static int _init(void) { if (daemon_nonblock(_signal_pipe[0], 1) < 0 || daemon_nonblock(_signal_pipe[1], 1) < 0) return -1; - } return 0; @@ -131,8 +130,7 @@ int daemon_signal_next(void) { if ((r = read(_signal_pipe[0], &s, sizeof(s))) == sizeof(s)) return s; - - + if (r < 0) { if (errno == EAGAIN) |