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/>.
25 #include <sys/types.h>
35 #include <sys/ioctl.h>
38 #include <sys/resource.h>
42 #include "dnonblock.h"
45 #if defined(_NSIG) /* On glibc NSIG does not count RT signals */
46 # define SIGNAL_UPPER_BOUND _NSIG
47 #elif defined(NSIG) /* Solaris defines just this */
48 # define SIGNAL_UPPER_BOUND NSIG
50 # error "Unknown upper bound for signals"
53 static int _daemon_retval_pipe[2] = { -1, -1 };
55 static int _null_open(int f, int fd) {
58 if ((fd2 = open("/dev/null", f)) < 0)
64 if (dup2(fd2, fd) < 0)
71 static ssize_t atomic_read(int fd, void *d, size_t l) {
77 if ((r = read(fd, d, l)) <= 0) {
80 return t > 0 ? t : -1;
93 static ssize_t atomic_write(int fd, const void *d, size_t l) {
99 if ((r = write(fd, d, l)) <= 0) {
102 return t > 0 ? t : -1;
108 d = (const char*) d + r;
115 static int move_fd_up(int *fd) {
119 if ((*fd = dup(*fd)) < 0) {
120 daemon_log(LOG_ERR, "dup(): %s", strerror(errno));
128 static void sigchld(int s) {
131 pid_t daemon_fork(void) {
133 int pipe_fds[2] = {-1, -1};
134 struct sigaction sa_old, sa_new;
135 sigset_t ss_old, ss_new;
138 memset(&sa_new, 0, sizeof(sa_new));
139 sa_new.sa_handler = sigchld;
140 sa_new.sa_flags = SA_RESTART;
142 if (sigemptyset(&ss_new) < 0) {
143 daemon_log(LOG_ERR, "sigemptyset() failed: %s", strerror(errno));
147 if (sigaddset(&ss_new, SIGCHLD) < 0) {
148 daemon_log(LOG_ERR, "sigaddset() failed: %s", strerror(errno));
152 if (sigaction(SIGCHLD, &sa_new, &sa_old) < 0) {
153 daemon_log(LOG_ERR, "sigaction() failed: %s", strerror(errno));
157 if (sigprocmask(SIG_UNBLOCK, &ss_new, &ss_old) < 0) {
158 daemon_log(LOG_ERR, "sigprocmask() failed: %s", strerror(errno));
161 sigaction(SIGCHLD, &sa_old, NULL);
167 if (pipe(pipe_fds) < 0) {
168 daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
171 sigaction(SIGCHLD, &sa_old, NULL);
172 sigprocmask(SIG_SETMASK, &ss_old, NULL);
178 if ((pid = fork()) < 0) { /* First fork */
179 daemon_log(LOG_ERR, "First fork() failed: %s", strerror(errno));
184 sigaction(SIGCHLD, &sa_old, NULL);
185 sigprocmask(SIG_SETMASK, &ss_old, NULL);
190 } else if (pid == 0) {
193 /* First child. Now we are sure not to be a session leader or
194 * process group leader anymore, i.e. we know that setsid()
197 if (daemon_log_use & DAEMON_LOG_AUTO)
198 daemon_log_use = DAEMON_LOG_SYSLOG;
200 if (close(pipe_fds[0]) < 0) {
201 daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
205 /* Move file descriptors up*/
206 if (move_fd_up(&pipe_fds[1]) < 0)
209 if (_daemon_retval_pipe[0] >= 0 && move_fd_up(&_daemon_retval_pipe[0]) < 0)
211 if (_daemon_retval_pipe[1] >= 0 && move_fd_up(&_daemon_retval_pipe[1]) < 0)
214 if (_null_open(O_RDONLY, 0) < 0) {
215 daemon_log(LOG_ERR, "Failed to open /dev/null for STDIN: %s", strerror(errno));
219 if (_null_open(O_WRONLY, 1) < 0) {
220 daemon_log(LOG_ERR, "Failed to open /dev/null for STDOUT: %s", strerror(errno));
224 if (_null_open(O_WRONLY, 2) < 0) {
225 daemon_log(LOG_ERR, "Failed to open /dev/null for STDERR: %s", strerror(errno));
229 /* Create a new session. This will create a new session and a
230 * new process group for us and we will be the ledaer of
231 * both. This should always succeed because we cannot be the
232 * process group leader because we just forked. */
234 daemon_log(LOG_ERR, "setsid() failed: %s", strerror(errno));
240 if (chdir("/") < 0) {
241 daemon_log(LOG_ERR, "chdir() failed: %s", strerror(errno));
245 if ((pid = fork()) < 0) { /* Second fork */
246 daemon_log(LOG_ERR, "Second fork() failed: %s", strerror(errno));
249 } else if (pid == 0) {
250 /* Second child. Our father will exit right-away. That way
251 * we can be sure that we are a child of init now, even if
252 * the process which spawned us stays around for a longer
253 * time. Also, since we are no session leader anymore we
254 * can be sure that we will never acquire a controlling
257 if (sigaction(SIGCHLD, &sa_old, NULL) < 0) {
258 daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
262 if (sigprocmask(SIG_SETMASK, &ss_old, NULL) < 0) {
263 daemon_log(LOG_ERR, "sigprocmask() failed: %s", strerror(errno));
267 if (signal(SIGTTOU, SIG_IGN) == SIG_ERR) {
268 daemon_log(LOG_ERR, "signal(SIGTTOU, SIG_IGN) failed: %s", strerror(errno));
272 if (signal(SIGTTIN, SIG_IGN) == SIG_ERR) {
273 daemon_log(LOG_ERR, "signal(SIGTTIN, SIG_IGN) failed: %s", strerror(errno));
277 if (signal(SIGTSTP, SIG_IGN) == SIG_ERR) {
278 daemon_log(LOG_ERR, "signal(SIGTSTP, SIG_IGN) failed: %s", strerror(errno));
283 if (atomic_write(pipe_fds[1], &dpid, sizeof(dpid)) != sizeof(dpid)) {
284 daemon_log(LOG_ERR, "write() failed: %s", strerror(errno));
288 if (close(pipe_fds[1]) < 0) {
289 daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
304 if (atomic_write(pipe_fds[1], &dpid, sizeof(dpid)) != sizeof(dpid))
305 daemon_log(LOG_ERR, "Failed to write error PID: %s", strerror(errno));
316 if (waitpid(pid, NULL, WUNTRACED) < 0) {
319 sigaction(SIGCHLD, &sa_old, NULL);
320 sigprocmask(SIG_SETMASK, &ss_old, NULL);
325 sigprocmask(SIG_SETMASK, &ss_old, NULL);
326 sigaction(SIGCHLD, &sa_old, NULL);
328 if (atomic_read(pipe_fds[0], &dpid, sizeof(dpid)) != sizeof(dpid)) {
329 daemon_log(LOG_ERR, "Failed to read daemon PID.");
332 } else if (dpid == (pid_t) -1)
343 int daemon_retval_init(void) {
345 if (_daemon_retval_pipe[0] < 0 || _daemon_retval_pipe[1] < 0) {
347 if (pipe(_daemon_retval_pipe) < 0) {
348 daemon_log(LOG_ERR, "pipe(): %s", strerror(errno));
356 void daemon_retval_done(void) {
357 int saved_errno = errno;
359 if (_daemon_retval_pipe[0] >= 0)
360 close(_daemon_retval_pipe[0]);
362 if (_daemon_retval_pipe[1] >= 0)
363 close(_daemon_retval_pipe[1]);
365 _daemon_retval_pipe[0] = _daemon_retval_pipe[1] = -1;
370 int daemon_retval_send(int i) {
373 if (_daemon_retval_pipe[1] < 0) {
378 r = atomic_write(_daemon_retval_pipe[1], &i, sizeof(i));
380 daemon_retval_done();
382 if (r != sizeof(i)) {
385 daemon_log(LOG_ERR, "write() failed while writing return value to pipe: %s", strerror(errno));
387 daemon_log(LOG_ERR, "write() too short while writing return value from pipe");
397 int daemon_retval_wait(int timeout) {
410 FD_SET(_daemon_retval_pipe[0], &fds);
412 if ((s = select(FD_SETSIZE, &fds, 0, 0, &tv)) != 1) {
415 daemon_log(LOG_ERR, "select() failed while waiting for return value: %s", strerror(errno));
418 daemon_log(LOG_ERR, "Timeout reached while wating for return value");
425 if ((r = atomic_read(_daemon_retval_pipe[0], &i, sizeof(i))) != sizeof(i)) {
428 daemon_log(LOG_ERR, "read() failed while reading return value from pipe: %s", strerror(errno));
430 daemon_log(LOG_ERR, "read() failed with EOF while reading return value from pipe.");
433 daemon_log(LOG_ERR, "read() too short while reading return value from pipe.");
440 daemon_retval_done();
445 int daemon_close_all(int except_fd, ...) {
451 va_start(ap, except_fd);
454 for (n = 1; va_arg(ap, int) >= 0; n++)
459 if (!(p = malloc(sizeof(int) * (n+1))))
462 va_start(ap, except_fd);
465 if (except_fd >= 0) {
469 while ((fd = va_arg(ap, int)) >= 0)
476 r = daemon_close_allv(p);
485 /** Same as daemon_close_all but takes an array of fds, terminated by -1 */
486 int daemon_close_allv(const int except_fds[]) {
495 if ((d = opendir("/proc/self/fd"))) {
499 while ((de = readdir(d))) {
505 if (de->d_name[0] == '.')
509 l = strtol(de->d_name, &e, 10);
510 if (errno != 0 || !e || *e) {
518 if ((long) fd != l) {
530 if (fd == _daemon_retval_pipe[1])
534 for (i = 0; except_fds[i] >= 0; i++)
535 if (except_fds[i] == fd) {
551 if (fd == _daemon_retval_pipe[0])
552 _daemon_retval_pipe[0] = -1; /* mark as closed */
561 if (getrlimit(RLIMIT_NOFILE, &rl) > 0)
562 maxfd = (int) rl.rlim_max;
564 maxfd = sysconf(_SC_OPEN_MAX);
566 for (fd = 3; fd < maxfd; fd++) {
569 if (fd == _daemon_retval_pipe[1])
573 for (i = 0; except_fds[i] >= 0; i++)
574 if (except_fds[i] == fd) {
582 if (close(fd) < 0 && errno != EBADF)
585 if (fd == _daemon_retval_pipe[0])
586 _daemon_retval_pipe[0] = -1; /* mark as closed */
592 int daemon_unblock_sigs(int except, ...) {
598 va_start(ap, except);
601 for (n = 1; va_arg(ap, int) >= 0; n++)
606 if (!(p = malloc(sizeof(int) * (n+1))))
609 va_start(ap, except);
616 while ((sig = va_arg(ap, int)) >= 0)
623 r = daemon_unblock_sigsv(p);
632 int daemon_unblock_sigsv(const int except[]) {
636 if (sigemptyset(&ss) < 0)
639 for (i = 0; except[i] > 0; i++)
640 if (sigaddset(&ss, except[i]) < 0)
643 return sigprocmask(SIG_SETMASK, &ss, NULL);
646 int daemon_reset_sigs(int except, ...) {
652 va_start(ap, except);
655 for (n = 1; va_arg(ap, int) >= 0; n++)
660 if (!(p = malloc(sizeof(int) * (n+1))))
663 va_start(ap, except);
670 while ((sig = va_arg(ap, int)) >= 0)
677 r = daemon_reset_sigsv(p);
686 int daemon_reset_sigsv(const int except[]) {
689 for (sig = 1; sig < SIGNAL_UPPER_BOUND; sig++) {
701 for (i = 0; except[i] > 0; i++) {
702 if (sig == except[i]) {
713 memset(&sa, 0, sizeof(sa));
714 sa.sa_handler = SIG_DFL;
716 /* On Linux the first two RT signals are reserved by
717 * glibc, and sigaction() will return EINVAL for them. */
718 if ((sigaction(sig, &sa, NULL) < 0))