From 3c77c6e7d3f597400b3ae10dd1228aabf1ad6280 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 20 Nov 2004 23:48:18 +0000 Subject: * remove autospawn lock file usage * fix some compiler warnings * implement PID file support git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@296 fefdeb5f-60dc-0310-8127-8f9354f1896f --- polyp/pid.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 polyp/pid.c (limited to 'polyp/pid.c') diff --git a/polyp/pid.c b/polyp/pid.c new file mode 100644 index 00000000..142c4f6d --- /dev/null +++ b/polyp/pid.c @@ -0,0 +1,197 @@ +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + polypaudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with polypaudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pid.h" +#include "util.h" +#include "log.h" + +static pid_t read_pid(const char *fn, int fd) { + ssize_t r; + char t[20], *e = NULL; + long int pid; + + assert(fn && fd >= 0); + + if ((r = pa_loop_read(fd, t, sizeof(t)-1)) < 0) { + pa_log(__FILE__": WARNING: failed to read PID file '%s': %s\n", fn, strerror(errno)); + return (pid_t) -1; + } + + if (r == 0) + return (pid_t) 0; + + t[r] = 0; + + if (!t[0] || (pid = strtol(t, &e, 0)) == 0 || (*e != 0 && *e != '\n')) { + pa_log(__FILE__": WARNING: failed to parse PID file '%s'\n", fn); + return (pid_t) -1; + } + + return (pid_t) pid; +} + +int pa_pid_file_create(void) { + int fd = -1, lock = -1; + int ret = -1; + char fn[PATH_MAX]; + char t[20]; + pid_t pid; + size_t l; + + pa_runtime_path("pid", fn, sizeof(fn)); + if ((fd = open(fn, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) < 0) { + pa_log(__FILE__": WARNING: failed to open PID file '%s': %s\n", fn, strerror(errno)); + goto fail; + } + + lock = pa_lock_fd(fd, 1); + + if ((pid = read_pid(fn, fd)) == (pid_t) -1) + pa_log(__FILE__": corrupt PID file, overwriting.\n"); + else if (pid > 0) { + if (kill(pid, 0) >= 0 || errno != ESRCH) { + pa_log(__FILE__": valid PID file.\n"); + goto fail; + } + + pa_log(__FILE__": stale PID file, overwriting.\n"); + } + + lseek(fd, 0, SEEK_SET); + + snprintf(t, sizeof(t), "%lu", (unsigned long) getpid()); + l = strlen(t); + + if (pa_loop_write(fd, t, l) != (ssize_t) l) { + pa_log(__FILE__": failed to write PID file.\n"); + goto fail; + } + + ret = 0; + +fail: + if (fd >= 0) { + if (lock >= 0) + pa_lock_fd(fd, 0); + + close(fd); + } + + return ret; +} + +int pa_pid_file_remove(void) { + int fd = -1, lock = -1; + char fn[PATH_MAX]; + int ret = -1; + pid_t pid; + + pa_runtime_path("pid", fn, sizeof(fn)); + if ((fd = open(fn, O_RDWR)) < 0) { + pa_log(__FILE__": WARNING: failed to open PID file '%s': %s\n", fn, strerror(errno)); + goto fail; + } + + lock = pa_lock_fd(fd, 1); + + if ((pid = read_pid(fn, fd)) == (pid_t) -1) + goto fail; + + if (pid != getpid()) { + pa_log(__FILE__": WARNING: PID file '%s' not mine!\n", fn); + goto fail; + } + + if (ftruncate(fd, 0) < 0) { + pa_log(__FILE__": failed to truncate PID file '%s': %s\n", fn, strerror(errno)); + goto fail; + } + + if (unlink(fn) < 0) { + pa_log(__FILE__": failed to remove PID file '%s': %s\n", fn, strerror(errno)); + goto fail; + } + + ret = 0; + +fail: + + if (fd >= 0) { + if (lock >= 0) + pa_lock_fd(fd, 0); + + close(fd); + } + + return ret; +} + +int pa_pid_file_check_running(pid_t *pid) { + return pa_pid_file_kill(0, pid); +} + +int pa_pid_file_kill(int sig, pid_t *pid) { + int fd = -1, lock = -1; + char fn[PATH_MAX]; + int ret = -1; + pid_t _pid; + + if (!pid) + pid = &_pid; + + pa_runtime_path("pid", fn, sizeof(fn)); + if ((fd = open(fn, O_RDONLY)) < 0) + goto fail; + + lock = pa_lock_fd(fd, 1); + + if ((*pid = read_pid(fn, fd)) == (pid_t) -1) + goto fail; + + ret = kill(*pid, sig); + +fail: + + if (fd >= 0) { + if (lock >= 0) + pa_lock_fd(fd, 0); + + close(fd); + } + + return ret; + +} -- cgit