2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
28 #include <sys/types.h>
40 #include <pulse/xmalloc.h>
42 #include <pulsecore/core-error.h>
43 #include <pulsecore/core-util.h>
44 #include <pulsecore/log.h>
45 #include <pulsecore/macro.h>
49 /* Read the PID data from the file descriptor fd, and return it. If no
50 * pid could be read, return 0, on failure (pid_t) -1 */
51 static pid_t read_pid(const char *fn, int fd) {
59 if ((r = pa_loop_read(fd, t, sizeof(t)-1, NULL)) < 0) {
60 pa_log_warn("Failed to read PID file '%s': %s", fn, pa_cstrerror(errno));
68 if ((e = strchr(t, '\n')))
71 if (pa_atou(t, &pid) < 0) {
72 pa_log_warn("Failed to parse PID file '%s'", fn);
80 static int open_pid_file(const char *fn, int mode) {
88 if ((fd = pa_open_cloexec(fn, mode
94 if (mode != O_RDONLY || errno != ENOENT)
95 pa_log_warn("Failed to open PID file '%s': %s", fn, pa_cstrerror(errno));
99 /* Try to lock the file. If that fails, go without */
100 if (pa_lock_fd(fd, 1) < 0)
103 if (fstat(fd, &st) < 0) {
104 pa_log_warn("Failed to fstat() PID file '%s': %s", fn, pa_cstrerror(errno));
108 /* Does the file still exist in the file system? When yes, we're done, otherwise restart */
109 if (st.st_nlink >= 1)
112 if (pa_lock_fd(fd, 0) < 0)
115 if (pa_close(fd) < 0) {
116 pa_log_warn("Failed to close file '%s': %s", fn, pa_cstrerror(errno));
127 int saved_errno = errno;
136 static int proc_name_ours(pid_t pid, const char *procname) {
141 pa_snprintf(bn, sizeof(bn), "/proc/%lu/stat", (unsigned long) pid);
143 if (!(f = pa_fopen_cloexec(bn, "r"))) {
144 pa_log_info("Failed to open %s: %s", bn, pa_cstrerror(errno));
151 if (!(fgets(stored, sizeof(stored), f))) {
152 int saved_errno = feof(f) ? EINVAL : errno;
153 pa_log_info("Failed to read from %s: %s", bn, feof(f) ? "EOF" : pa_cstrerror(errno));
162 expected = pa_sprintf_malloc("%lu (%s)", (unsigned long) pid, procname);
163 good = pa_startswith(stored, expected);
166 /*#if !defined(__OPTIMIZE__)*/
168 /* libtool likes to rename our binary names ... */
169 expected = pa_sprintf_malloc("%lu (lt-%s)", (unsigned long) pid, procname);
170 good = pa_startswith(stored, expected);
184 /* Create a new PID file for the current process. */
185 int pa_pid_file_create(const char *procname) {
197 if (!(fn = pa_runtime_path("pid")))
200 if ((fd = open_pid_file(fn, O_CREAT|O_RDWR)) < 0)
203 if ((pid = read_pid(fn, fd)) == (pid_t) -1)
204 pa_log_warn("Corrupt PID file, overwriting.");
209 if ((process = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid)) != NULL) {
210 CloseHandle(process);
212 if (kill(pid, 0) >= 0 || errno != ESRCH) {
216 if ((ours = proc_name_ours(pid, procname)) < 0) {
217 pa_log_warn("Could not check to see if pid %lu is a pulseaudio process. "
218 "Assuming it is and the daemon is already running.", (unsigned long) pid);
223 pa_log("Daemon already running.");
229 pa_log_warn("Stale PID file, overwriting.");
232 /* Overwrite the current PID file */
233 if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) -1 || ftruncate(fd, (off_t) 0) < 0) {
234 pa_log("Failed to truncate PID file '%s': %s", fn, pa_cstrerror(errno));
238 pa_snprintf(t, sizeof(t), "%lu\n", (unsigned long) getpid());
241 if (pa_loop_write(fd, t, l, NULL) != (ssize_t) l) {
242 pa_log("Failed to write PID file.");
252 if (pa_close(fd) < 0) {
253 pa_log("Failed to close PID file '%s': %s", fn, pa_cstrerror(errno));
263 /* Remove the PID file, if it is ours */
264 int pa_pid_file_remove(void) {
270 if (!(fn = pa_runtime_path("pid")))
273 if ((fd = open_pid_file(fn, O_RDWR)) < 0) {
274 pa_log_warn("Failed to open PID file '%s': %s", fn, pa_cstrerror(errno));
278 if ((pid = read_pid(fn, fd)) == (pid_t) -1)
281 if (pid != getpid()) {
282 pa_log("PID file '%s' not mine!", fn);
286 if (ftruncate(fd, (off_t) 0) < 0) {
287 pa_log_warn("Failed to truncate PID file '%s': %s", fn, pa_cstrerror(errno));
297 if (unlink(fn) < 0) {
298 pa_log_warn("Failed to remove PID file '%s': %s", fn, pa_cstrerror(errno));
309 if (pa_close(fd) < 0) {
310 pa_log_warn("Failed to close PID file '%s': %s", fn, pa_cstrerror(errno));
320 /* Check whether the daemon is currently running, i.e. if a PID file
321 * exists and the PID therein too. Returns 0 on success, -1
322 * otherwise. If pid is non-NULL and a running daemon was found,
323 * return its PID therein */
324 int pa_pid_file_check_running(pid_t *pid, const char *procname) {
325 return pa_pid_file_kill(0, pid, procname);
330 /* Kill a current running daemon. Return non-zero on success, -1
331 * otherwise. If successful *pid contains the PID of the daemon
333 int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) {
345 if (!(fn = pa_runtime_path("pid")))
348 if ((fd = open_pid_file(fn, O_RDONLY)) < 0) {
356 if ((*pid = read_pid(fn, fd)) == (pid_t) -1)
362 if ((ours = proc_name_ours(*pid, procname)) < 0)
371 ret = kill(*pid, sig);
376 int saved_errno = errno;
392 #else /* OS_IS_WIN32 */
394 int pa_pid_file_kill(int sig, pid_t *pid, const char *exe_name) {