]> code.delx.au - pulseaudio/blob - polyp/pid.c
* remove autospawn lock file usage
[pulseaudio] / polyp / pid.c
1 /* $Id$ */
2
3 /***
4 This file is part of polypaudio.
5
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <sys/types.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <assert.h>
33 #include <stdlib.h>
34 #include <limits.h>
35 #include <signal.h>
36
37 #include "pid.h"
38 #include "util.h"
39 #include "log.h"
40
41 static pid_t read_pid(const char *fn, int fd) {
42 ssize_t r;
43 char t[20], *e = NULL;
44 long int pid;
45
46 assert(fn && fd >= 0);
47
48 if ((r = pa_loop_read(fd, t, sizeof(t)-1)) < 0) {
49 pa_log(__FILE__": WARNING: failed to read PID file '%s': %s\n", fn, strerror(errno));
50 return (pid_t) -1;
51 }
52
53 if (r == 0)
54 return (pid_t) 0;
55
56 t[r] = 0;
57
58 if (!t[0] || (pid = strtol(t, &e, 0)) == 0 || (*e != 0 && *e != '\n')) {
59 pa_log(__FILE__": WARNING: failed to parse PID file '%s'\n", fn);
60 return (pid_t) -1;
61 }
62
63 return (pid_t) pid;
64 }
65
66 int pa_pid_file_create(void) {
67 int fd = -1, lock = -1;
68 int ret = -1;
69 char fn[PATH_MAX];
70 char t[20];
71 pid_t pid;
72 size_t l;
73
74 pa_runtime_path("pid", fn, sizeof(fn));
75 if ((fd = open(fn, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) < 0) {
76 pa_log(__FILE__": WARNING: failed to open PID file '%s': %s\n", fn, strerror(errno));
77 goto fail;
78 }
79
80 lock = pa_lock_fd(fd, 1);
81
82 if ((pid = read_pid(fn, fd)) == (pid_t) -1)
83 pa_log(__FILE__": corrupt PID file, overwriting.\n");
84 else if (pid > 0) {
85 if (kill(pid, 0) >= 0 || errno != ESRCH) {
86 pa_log(__FILE__": valid PID file.\n");
87 goto fail;
88 }
89
90 pa_log(__FILE__": stale PID file, overwriting.\n");
91 }
92
93 lseek(fd, 0, SEEK_SET);
94
95 snprintf(t, sizeof(t), "%lu", (unsigned long) getpid());
96 l = strlen(t);
97
98 if (pa_loop_write(fd, t, l) != (ssize_t) l) {
99 pa_log(__FILE__": failed to write PID file.\n");
100 goto fail;
101 }
102
103 ret = 0;
104
105 fail:
106 if (fd >= 0) {
107 if (lock >= 0)
108 pa_lock_fd(fd, 0);
109
110 close(fd);
111 }
112
113 return ret;
114 }
115
116 int pa_pid_file_remove(void) {
117 int fd = -1, lock = -1;
118 char fn[PATH_MAX];
119 int ret = -1;
120 pid_t pid;
121
122 pa_runtime_path("pid", fn, sizeof(fn));
123 if ((fd = open(fn, O_RDWR)) < 0) {
124 pa_log(__FILE__": WARNING: failed to open PID file '%s': %s\n", fn, strerror(errno));
125 goto fail;
126 }
127
128 lock = pa_lock_fd(fd, 1);
129
130 if ((pid = read_pid(fn, fd)) == (pid_t) -1)
131 goto fail;
132
133 if (pid != getpid()) {
134 pa_log(__FILE__": WARNING: PID file '%s' not mine!\n", fn);
135 goto fail;
136 }
137
138 if (ftruncate(fd, 0) < 0) {
139 pa_log(__FILE__": failed to truncate PID file '%s': %s\n", fn, strerror(errno));
140 goto fail;
141 }
142
143 if (unlink(fn) < 0) {
144 pa_log(__FILE__": failed to remove PID file '%s': %s\n", fn, strerror(errno));
145 goto fail;
146 }
147
148 ret = 0;
149
150 fail:
151
152 if (fd >= 0) {
153 if (lock >= 0)
154 pa_lock_fd(fd, 0);
155
156 close(fd);
157 }
158
159 return ret;
160 }
161
162 int pa_pid_file_check_running(pid_t *pid) {
163 return pa_pid_file_kill(0, pid);
164 }
165
166 int pa_pid_file_kill(int sig, pid_t *pid) {
167 int fd = -1, lock = -1;
168 char fn[PATH_MAX];
169 int ret = -1;
170 pid_t _pid;
171
172 if (!pid)
173 pid = &_pid;
174
175 pa_runtime_path("pid", fn, sizeof(fn));
176 if ((fd = open(fn, O_RDONLY)) < 0)
177 goto fail;
178
179 lock = pa_lock_fd(fd, 1);
180
181 if ((*pid = read_pid(fn, fd)) == (pid_t) -1)
182 goto fail;
183
184 ret = kill(*pid, sig);
185
186 fail:
187
188 if (fd >= 0) {
189 if (lock >= 0)
190 pa_lock_fd(fd, 0);
191
192 close(fd);
193 }
194
195 return ret;
196
197 }