diff options
author | Lennart Poettering <lennart@poettering.net> | 2005-06-04 19:07:59 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2005-06-04 19:07:59 +0000 |
commit | 360ff12ea5b1e0dc3c83a373ddce20e109efaa9a (patch) | |
tree | 22efd48841fbbc289d6483a2f5384cc70e604cda /libdaemon | |
parent | 146b5df7b80e1745eef752568210645b7ff4cdff (diff) |
* implement proper PID file locking
git-svn-id: file:///home/lennart/svn/public/libdaemon/trunk@79 153bfa13-eec0-0310-be40-b0cb6a0e1b4b
Diffstat (limited to 'libdaemon')
-rw-r--r-- | libdaemon/Makefile.am | 2 | ||||
-rw-r--r-- | libdaemon/dlog.c | 2 | ||||
-rw-r--r-- | libdaemon/dlog.h | 2 | ||||
-rw-r--r-- | libdaemon/dpid.c | 113 |
4 files changed, 88 insertions, 31 deletions
diff --git a/libdaemon/Makefile.am b/libdaemon/Makefile.am index c14000c..f0dd5e6 100644 --- a/libdaemon/Makefile.am +++ b/libdaemon/Makefile.am @@ -39,4 +39,4 @@ libdaemon_la_SOURCES = \ daemon.h \ $(pkg_include_HEADERS) -libdaemon_la_LDFLAGS = -version-info 2:1:2 +libdaemon_la_LDFLAGS = -version-info 2:2:2 diff --git a/libdaemon/dlog.c b/libdaemon/dlog.c index 1fc3e08..88c4e60 100644 --- a/libdaemon/dlog.c +++ b/libdaemon/dlog.c @@ -29,7 +29,7 @@ #include "dlog.h" enum daemon_log_flags daemon_log_use = DAEMON_LOG_AUTO|DAEMON_LOG_STDERR; -char* daemon_log_ident = 0; +char* daemon_log_ident = NULL; void daemon_log(int prio, const char* template, ...) { va_list arglist; diff --git a/libdaemon/dlog.h b/libdaemon/dlog.h index 0f74dde..55b641a 100644 --- a/libdaemon/dlog.h +++ b/libdaemon/dlog.h @@ -32,7 +32,7 @@ extern "C" { * Contains a robust API for logging messages */ -/** Specifies where to send the log messages to +/** Specifies where to send the log messages to. The global variable daemon_log_use takes values of this type. */ enum daemon_log_flags { DAEMON_LOG_SYSLOG = 1, /**< Log messages are written to syslog */ diff --git a/libdaemon/dpid.c b/libdaemon/dpid.c index e41e37c..7c90297 100644 --- a/libdaemon/dpid.c +++ b/libdaemon/dpid.c @@ -32,13 +32,15 @@ #include <sys/types.h> #include <sys/stat.h> #include <time.h> +#include <fcntl.h> +#include <stddef.h> #include "dpid.h" #include "dlog.h" #define VARRUN "/var/run" -const char *daemon_pid_file_ident = 0; +const char *daemon_pid_file_ident = NULL; daemon_pid_file_proc_t daemon_pid_file_proc = daemon_pid_file_proc_default; const char *daemon_pid_file_proc_default(void) { @@ -47,41 +49,74 @@ const char *daemon_pid_file_proc_default(void) { return fn; } +static int lock_file(int fd, int enable) { + struct flock f; + + memset(&f, 0, sizeof(f)); + f.l_type = enable ? F_WRLCK : F_UNLCK; + f.l_whence = SEEK_SET; + f.l_start = 0; + f.l_len = 0; + + if (fcntl(fd, F_SETLKW, &f) < 0) { + daemon_log(LOG_WARNING, "fcntl(F_SETLKW) failed: %s", strerror(errno)); + return -1; + } + + return 0; +} + pid_t daemon_pid_file_is_running(void) { const char *fn; static char txt[256]; - FILE *f; - pid_t pid; - + int fd = -1, locked = -1; + pid_t ret = (pid_t) -1, pid; + ssize_t l; if (!(fn = daemon_pid_file_proc())) - return (pid_t) -1; + goto finish; - if (!(f = fopen(fn, "r"))) - return (pid_t) -1; + if ((fd = open(fn, O_RDWR, 0644)) < 0) { + if (errno != ENOENT) + daemon_log(LOG_WARNING, "Failed to open PID file: %s", strerror(errno)); - if (!(fgets(txt, sizeof(txt), f))) { - daemon_log(LOG_WARNING, "PID file corrupt, removing. (%s)", fn); - unlink(fn); - fclose(f); - return (pid_t) -1; + goto finish; } - fclose(f); + if ((locked = lock_file(fd, 1)) < 0) + goto finish; + + if ((l = read(fd, txt, sizeof(txt)-1)) < 0) { + daemon_log(LOG_WARNING, "read(): %s", strerror(errno)); + unlink(fn); + goto finish; + } + txt[l] = 0; + if ((pid = (pid_t) atoi(txt)) <= 0) { daemon_log(LOG_WARNING, "PID file corrupt, removing. (%s)", fn); unlink(fn); - return (pid_t) -1; + goto finish; } if (kill(pid, 0) != 0 && errno != EPERM) { - daemon_log(LOG_WARNING, "Daemon %u killed: %s; removing PID file. (%s)", pid, strerror(errno), fn); + daemon_log(LOG_WARNING, "Process %lu died: %s; removing PID file. (%s)", (unsigned long) pid, strerror(errno), fn); unlink(fn); - return (pid_t) -1; + goto finish; } + + ret = pid; - return pid; +finish: + + if (fd >= 0) { + if (locked >= 0) + lock_file(fd, 0); + close(fd); + } + + return ret; } int daemon_pid_file_kill(int s) { @@ -128,23 +163,45 @@ int daemon_pid_file_kill_wait(int s, int m) { int daemon_pid_file_create(void) { const char *fn; - FILE *f; - mode_t save; + int fd = -1; + int ret = -1; + int locked = -1; + char t[64]; + ssize_t l; if (!(fn = daemon_pid_file_proc())) - return -1; + goto finish; - save = umask(022); - - if (!(f = fopen(fn, "w"))) - return -1; + if ((fd = open(fn, O_CREAT|O_RDWR|O_EXCL, 0644)) < 0) { + fprintf(stderr, "open(%s): %s", fn, strerror(errno)); + goto finish; + } - fprintf(f, "%u\n", getpid()); - fclose(f); + if ((locked = lock_file(fd, 1)) < 0) { + unlink(fn); + goto finish; + } - umask(save); + snprintf(t, sizeof(t), "%lu\n", (unsigned long) getpid()); - return 0; + if (write(fd, t, l = strlen(t)) != l) { + daemon_log(LOG_WARNING, "write(): %s", strerror(errno)); + unlink(fn); + goto finish; + } + + ret = 0; + +finish: + + if (fd >= 0) { + if (locked >= 0) + lock_file(fd, 0); + + close(fd); + } + + return ret; } int daemon_pid_file_remove(void) { |