2 This file is part of libdaemon.
4 Copyright 2003-2008 Lennart Poettering
6 libdaemon 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.1 of the
9 License, or (at your option) any later version.
11 libdaemon 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 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with libdaemon. If not, see
18 <http://www.gnu.org/licenses/>.
32 #include <sys/types.h>
35 #include <sys/select.h>
44 #define ETIME ETIMEDOUT /* For FreeBSD */
51 #define VARRUN LOCALSTATEDIR "/run"
53 const char *daemon_pid_file_ident = NULL;
54 daemon_pid_file_proc_t daemon_pid_file_proc = daemon_pid_file_proc_default;
56 const char *daemon_pid_file_proc_default(void) {
58 static char *fn = NULL;
60 asprintf(&fn, "%s/%s.pid", VARRUN, daemon_pid_file_ident ? daemon_pid_file_ident : "unknown");
62 static char fn[PATH_MAX];
63 snprintf(fn, sizeof(fn), "%s/%s.pid", VARRUN, daemon_pid_file_ident ? daemon_pid_file_ident : "unknown");
69 static int lock_file(int fd, int enable) {
72 memset(&f, 0, sizeof(f));
73 f.l_type = enable ? F_WRLCK : F_UNLCK;
74 f.l_whence = SEEK_SET;
78 if (fcntl(fd, F_SETLKW, &f) < 0) {
80 if (enable && errno == EBADF) {
83 if (fcntl(fd, F_SETLKW, &f) >= 0)
87 daemon_log(LOG_WARNING, "fcntl(F_SETLKW) failed: %s", strerror(errno));
94 pid_t daemon_pid_file_is_running(void) {
97 int fd = -1, locked = -1;
98 pid_t ret = (pid_t) -1, pid;
103 if (!(fn = daemon_pid_file_proc())) {
108 if ((fd = open(fn, O_RDWR, 0644)) < 0) {
109 if ((fd = open(fn, O_RDONLY, 0644)) < 0) {
111 daemon_log(LOG_WARNING, "Failed to open PID file: %s", strerror(errno));
117 if ((locked = lock_file(fd, 1)) < 0)
120 if ((l = read(fd, txt, sizeof(txt)-1)) < 0) {
121 int saved_errno = errno;
122 daemon_log(LOG_WARNING, "read(): %s", strerror(errno));
129 txt[strcspn(txt, "\r\n")] = 0;
132 lpid = strtol(txt, &e, 10);
135 if (errno != 0 || !e || *e || (long) pid != lpid) {
136 daemon_log(LOG_WARNING, "PID file corrupt, removing. (%s)", fn);
142 if (kill(pid, 0) != 0 && errno != EPERM) {
143 int saved_errno = errno;
144 daemon_log(LOG_WARNING, "Process %lu died: %s; trying to remove PID file. (%s)", (unsigned long) pid, strerror(errno), fn);
155 int saved_errno = errno;
165 int daemon_pid_file_kill(int s) {
168 if ((pid = daemon_pid_file_is_running()) == (pid_t) -1)
171 if (kill(pid, s) < 0)
177 int daemon_pid_file_kill_wait(int s, int m) {
181 if ((pid = daemon_pid_file_is_running()) < 0)
184 if (kill(pid, s) < 0)
191 struct timeval tv = { 0, 100000 };
193 if (time(NULL) > t) {
198 if ((r = kill(pid, 0)) < 0 && errno != ESRCH)
204 if (select(0, NULL, NULL, NULL, &tv) < 0)
209 int daemon_pid_file_create(void) {
220 if (!(fn = daemon_pid_file_proc())) {
225 if ((fd = open(fn, O_CREAT|O_RDWR|O_EXCL, 0644)) < 0) {
226 daemon_log(LOG_ERR, "open(%s): %s", fn, strerror(errno));
230 if ((locked = lock_file(fd, 1)) < 0) {
231 int saved_errno = errno;
237 snprintf(t, sizeof(t), "%lu\n", (unsigned long) getpid());
240 if (write(fd, t, l) != l) {
241 int saved_errno = errno;
242 daemon_log(LOG_WARNING, "write(): %s", strerror(errno));
253 int saved_errno = errno;
267 int daemon_pid_file_remove(void) {
270 if (!(fn = daemon_pid_file_proc())) {