Don't enable dnsmasq IPSET functionality on 2.4 kernel
[tomato.git] / release / src / router / libdaemon / libdaemon / dfork.c
blob70fce862894ba16d66127d10547799aaa045fad4
1 /***
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/>.
19 ***/
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <string.h>
29 #include <fcntl.h>
30 #include <sys/stat.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <sys/wait.h>
34 #include <assert.h>
35 #include <sys/ioctl.h>
36 #include <signal.h>
37 #include <sys/time.h>
38 #include <sys/resource.h>
39 #include <dirent.h>
41 #include "dfork.h"
42 #include "dnonblock.h"
43 #include "dlog.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
49 #else
50 # error "Unknown upper bound for signals"
51 #endif
53 static int _daemon_retval_pipe[2] = { -1, -1 };
55 static int _null_open(int f, int fd) {
56 int fd2;
58 if ((fd2 = open("/dev/null", f)) < 0)
59 return -1;
61 if (fd2 == fd)
62 return fd;
64 if (dup2(fd2, fd) < 0)
65 return -1;
67 close(fd2);
68 return fd;
71 static ssize_t atomic_read(int fd, void *d, size_t l) {
72 ssize_t t = 0;
74 while (l > 0) {
75 ssize_t r;
77 if ((r = read(fd, d, l)) <= 0) {
79 if (r < 0)
80 return t > 0 ? t : -1;
81 else
82 return t;
85 t += r;
86 d = (char*) d + r;
87 l -= r;
90 return t;
93 static ssize_t atomic_write(int fd, const void *d, size_t l) {
94 ssize_t t = 0;
96 while (l > 0) {
97 ssize_t r;
99 if ((r = write(fd, d, l)) <= 0) {
101 if (r < 0)
102 return t > 0 ? t : -1;
103 else
104 return t;
107 t += r;
108 d = (const char*) d + r;
109 l -= r;
112 return t;
115 static int move_fd_up(int *fd) {
116 assert(fd);
118 while (*fd <= 2) {
119 if ((*fd = dup(*fd)) < 0) {
120 daemon_log(LOG_ERR, "dup(): %s", strerror(errno));
121 return -1;
125 return 0;
128 static void sigchld(int s) {
131 pid_t daemon_fork(void) {
132 pid_t pid;
133 int pipe_fds[2] = {-1, -1};
134 struct sigaction sa_old, sa_new;
135 sigset_t ss_old, ss_new;
136 int saved_errno;
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));
144 return (pid_t) -1;
147 if (sigaddset(&ss_new, SIGCHLD) < 0) {
148 daemon_log(LOG_ERR, "sigaddset() failed: %s", strerror(errno));
149 return (pid_t) -1;
152 if (sigaction(SIGCHLD, &sa_new, &sa_old) < 0) {
153 daemon_log(LOG_ERR, "sigaction() failed: %s", strerror(errno));
154 return (pid_t) -1;
157 if (sigprocmask(SIG_UNBLOCK, &ss_new, &ss_old) < 0) {
158 daemon_log(LOG_ERR, "sigprocmask() failed: %s", strerror(errno));
160 saved_errno = errno;
161 sigaction(SIGCHLD, &sa_old, NULL);
162 errno = saved_errno;
164 return (pid_t) -1;
167 if (pipe(pipe_fds) < 0) {
168 daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
170 saved_errno = errno;
171 sigaction(SIGCHLD, &sa_old, NULL);
172 sigprocmask(SIG_SETMASK, &ss_old, NULL);
173 errno = saved_errno;
175 return (pid_t) -1;
178 if ((pid = fork()) < 0) { /* First fork */
179 daemon_log(LOG_ERR, "First fork() failed: %s", strerror(errno));
181 saved_errno = errno;
182 close(pipe_fds[0]);
183 close(pipe_fds[1]);
184 sigaction(SIGCHLD, &sa_old, NULL);
185 sigprocmask(SIG_SETMASK, &ss_old, NULL);
186 errno = saved_errno;
188 return (pid_t) -1;
190 } else if (pid == 0) {
191 pid_t dpid;
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()
195 * will succeed. */
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));
202 goto fail;
205 /* Move file descriptors up*/
206 if (move_fd_up(&pipe_fds[1]) < 0)
207 goto fail;
209 if (_daemon_retval_pipe[0] >= 0 && move_fd_up(&_daemon_retval_pipe[0]) < 0)
210 goto fail;
211 if (_daemon_retval_pipe[1] >= 0 && move_fd_up(&_daemon_retval_pipe[1]) < 0)
212 goto fail;
214 if (_null_open(O_RDONLY, 0) < 0) {
215 daemon_log(LOG_ERR, "Failed to open /dev/null for STDIN: %s", strerror(errno));
216 goto fail;
219 if (_null_open(O_WRONLY, 1) < 0) {
220 daemon_log(LOG_ERR, "Failed to open /dev/null for STDOUT: %s", strerror(errno));
221 goto fail;
224 if (_null_open(O_WRONLY, 2) < 0) {
225 daemon_log(LOG_ERR, "Failed to open /dev/null for STDERR: %s", strerror(errno));
226 goto fail;
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. */
233 if (setsid() < 0) {
234 daemon_log(LOG_ERR, "setsid() failed: %s", strerror(errno));
235 goto fail;
238 umask(0077);
240 if (chdir("/") < 0) {
241 daemon_log(LOG_ERR, "chdir() failed: %s", strerror(errno));
242 goto fail;
245 if ((pid = fork()) < 0) { /* Second fork */
246 daemon_log(LOG_ERR, "Second fork() failed: %s", strerror(errno));
247 goto fail;
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
255 * TTY. */
257 if (sigaction(SIGCHLD, &sa_old, NULL) < 0) {
258 daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
259 goto fail;
262 if (sigprocmask(SIG_SETMASK, &ss_old, NULL) < 0) {
263 daemon_log(LOG_ERR, "sigprocmask() failed: %s", strerror(errno));
264 goto fail;
267 if (signal(SIGTTOU, SIG_IGN) == SIG_ERR) {
268 daemon_log(LOG_ERR, "signal(SIGTTOU, SIG_IGN) failed: %s", strerror(errno));
269 goto fail;
272 if (signal(SIGTTIN, SIG_IGN) == SIG_ERR) {
273 daemon_log(LOG_ERR, "signal(SIGTTIN, SIG_IGN) failed: %s", strerror(errno));
274 goto fail;
277 if (signal(SIGTSTP, SIG_IGN) == SIG_ERR) {
278 daemon_log(LOG_ERR, "signal(SIGTSTP, SIG_IGN) failed: %s", strerror(errno));
279 goto fail;
282 dpid = getpid();
283 if (atomic_write(pipe_fds[1], &dpid, sizeof(dpid)) != sizeof(dpid)) {
284 daemon_log(LOG_ERR, "write() failed: %s", strerror(errno));
285 goto fail;
288 if (close(pipe_fds[1]) < 0) {
289 daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
290 goto fail;
293 return 0;
295 } else {
296 /* Second father */
297 close(pipe_fds[1]);
298 _exit(0);
301 fail:
302 dpid = (pid_t) -1;
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));
307 close(pipe_fds[1]);
308 _exit(0);
310 } else {
311 /* First father */
312 pid_t dpid;
314 close(pipe_fds[1]);
316 if (waitpid(pid, NULL, WUNTRACED) < 0) {
317 saved_errno = errno;
318 close(pipe_fds[0]);
319 sigaction(SIGCHLD, &sa_old, NULL);
320 sigprocmask(SIG_SETMASK, &ss_old, NULL);
321 errno = saved_errno;
322 return -1;
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.");
330 dpid = (pid_t) -1;
331 errno = EINVAL;
332 } else if (dpid == (pid_t) -1)
333 errno = EIO;
335 saved_errno = errno;
336 close(pipe_fds[0]);
337 errno = saved_errno;
339 return dpid;
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));
349 return -1;
353 return 0;
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;
367 errno = saved_errno;
370 int daemon_retval_send(int i) {
371 ssize_t r;
373 if (_daemon_retval_pipe[1] < 0) {
374 errno = EINVAL;
375 return -1;
378 r = atomic_write(_daemon_retval_pipe[1], &i, sizeof(i));
380 daemon_retval_done();
382 if (r != sizeof(i)) {
384 if (r < 0)
385 daemon_log(LOG_ERR, "write() failed while writing return value to pipe: %s", strerror(errno));
386 else {
387 daemon_log(LOG_ERR, "write() too short while writing return value from pipe");
388 errno = EINVAL;
391 return -1;
394 return 0;
397 int daemon_retval_wait(int timeout) {
398 ssize_t r;
399 int i;
401 if (timeout > 0) {
402 struct timeval tv;
403 int s;
404 fd_set fds;
406 tv.tv_sec = timeout;
407 tv.tv_usec = 0;
409 FD_ZERO(&fds);
410 FD_SET(_daemon_retval_pipe[0], &fds);
412 if ((s = select(FD_SETSIZE, &fds, 0, 0, &tv)) != 1) {
414 if (s < 0)
415 daemon_log(LOG_ERR, "select() failed while waiting for return value: %s", strerror(errno));
416 else {
417 errno = ETIMEDOUT;
418 daemon_log(LOG_ERR, "Timeout reached while wating for return value");
421 return -1;
425 if ((r = atomic_read(_daemon_retval_pipe[0], &i, sizeof(i))) != sizeof(i)) {
427 if (r < 0)
428 daemon_log(LOG_ERR, "read() failed while reading return value from pipe: %s", strerror(errno));
429 else if (r == 0) {
430 daemon_log(LOG_ERR, "read() failed with EOF while reading return value from pipe.");
431 errno = EINVAL;
432 } else if (r > 0) {
433 daemon_log(LOG_ERR, "read() too short while reading return value from pipe.");
434 errno = EINVAL;
437 return -1;
440 daemon_retval_done();
442 return i;
445 int daemon_close_all(int except_fd, ...) {
446 va_list ap;
447 int n = 0, i, r;
448 int *p;
449 int saved_errno;
451 va_start(ap, except_fd);
453 if (except_fd >= 0)
454 for (n = 1; va_arg(ap, int) >= 0; n++)
457 va_end(ap);
459 if (!(p = malloc(sizeof(int) * (n+1))))
460 return -1;
462 va_start(ap, except_fd);
464 i = 0;
465 if (except_fd >= 0) {
466 int fd;
467 p[i++] = except_fd;
469 while ((fd = va_arg(ap, int)) >= 0)
470 p[i++] = fd;
472 p[i] = -1;
474 va_end(ap);
476 r = daemon_close_allv(p);
478 saved_errno = errno;
479 free(p);
480 errno = saved_errno;
482 return r;
485 /** Same as daemon_close_all but takes an array of fds, terminated by -1 */
486 int daemon_close_allv(const int except_fds[]) {
487 struct rlimit rl;
488 int fd, maxfd;
490 #ifdef __linux__
491 int saved_errno;
493 DIR *d;
495 if ((d = opendir("/proc/self/fd"))) {
497 struct dirent *de;
499 while ((de = readdir(d))) {
500 int found;
501 long l;
502 char *e = NULL;
503 int i;
505 if (de->d_name[0] == '.')
506 continue;
508 errno = 0;
509 l = strtol(de->d_name, &e, 10);
510 if (errno != 0 || !e || *e) {
511 closedir(d);
512 errno = EINVAL;
513 return -1;
516 fd = (int) l;
518 if ((long) fd != l) {
519 closedir(d);
520 errno = EINVAL;
521 return -1;
524 if (fd < 3)
525 continue;
527 if (fd == dirfd(d))
528 continue;
530 if (fd == _daemon_retval_pipe[1])
531 continue;
533 found = 0;
534 for (i = 0; except_fds[i] >= 0; i++)
535 if (except_fds[i] == fd) {
536 found = 1;
537 break;
540 if (found)
541 continue;
543 if (close(fd) < 0) {
544 saved_errno = errno;
545 closedir(d);
546 errno = saved_errno;
548 return -1;
551 if (fd == _daemon_retval_pipe[0])
552 _daemon_retval_pipe[0] = -1; /* mark as closed */
555 closedir(d);
556 return 0;
559 #endif
561 if (getrlimit(RLIMIT_NOFILE, &rl) > 0)
562 maxfd = (int) rl.rlim_max;
563 else
564 maxfd = sysconf(_SC_OPEN_MAX);
566 for (fd = 3; fd < maxfd; fd++) {
567 int i, found;
569 if (fd == _daemon_retval_pipe[1])
570 continue;
572 found = 0;
573 for (i = 0; except_fds[i] >= 0; i++)
574 if (except_fds[i] == fd) {
575 found = 1;
576 break;
579 if (found)
580 continue;
582 if (close(fd) < 0 && errno != EBADF)
583 return -1;
585 if (fd == _daemon_retval_pipe[0])
586 _daemon_retval_pipe[0] = -1; /* mark as closed */
589 return 0;
592 int daemon_unblock_sigs(int except, ...) {
593 va_list ap;
594 int n = 0, i, r;
595 int *p;
596 int saved_errno;
598 va_start(ap, except);
600 if (except >= 1)
601 for (n = 1; va_arg(ap, int) >= 0; n++)
604 va_end(ap);
606 if (!(p = malloc(sizeof(int) * (n+1))))
607 return -1;
609 va_start(ap, except);
611 i = 0;
612 if (except >= 1) {
613 int sig;
614 p[i++] = except;
616 while ((sig = va_arg(ap, int)) >= 0)
617 p[i++] = sig;
619 p[i] = -1;
621 va_end(ap);
623 r = daemon_unblock_sigsv(p);
625 saved_errno = errno;
626 free(p);
627 errno = saved_errno;
629 return r;
632 int daemon_unblock_sigsv(const int except[]) {
633 int i;
634 sigset_t ss;
636 if (sigemptyset(&ss) < 0)
637 return -1;
639 for (i = 0; except[i] > 0; i++)
640 if (sigaddset(&ss, except[i]) < 0)
641 return -1;
643 return sigprocmask(SIG_SETMASK, &ss, NULL);
646 int daemon_reset_sigs(int except, ...) {
647 va_list ap;
648 int n = 0, i, r;
649 int *p;
650 int saved_errno;
652 va_start(ap, except);
654 if (except >= 1)
655 for (n = 1; va_arg(ap, int) >= 0; n++)
658 va_end(ap);
660 if (!(p = malloc(sizeof(int) * (n+1))))
661 return -1;
663 va_start(ap, except);
665 i = 0;
666 if (except >= 1) {
667 int sig;
668 p[i++] = except;
670 while ((sig = va_arg(ap, int)) >= 0)
671 p[i++] = sig;
673 p[i] = -1;
675 va_end(ap);
677 r = daemon_reset_sigsv(p);
679 saved_errno = errno;
680 free(p);
681 errno = saved_errno;
683 return r;
686 int daemon_reset_sigsv(const int except[]) {
687 int sig;
689 for (sig = 1; sig < SIGNAL_UPPER_BOUND; sig++) {
690 int reset = 1;
692 switch (sig) {
693 case SIGKILL:
694 case SIGSTOP:
695 reset = 0;
696 break;
698 default: {
699 int i;
701 for (i = 0; except[i] > 0; i++) {
702 if (sig == except[i]) {
703 reset = 0;
704 break;
710 if (reset) {
711 struct sigaction sa;
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))
719 if (errno != EINVAL)
720 return -1;
724 return 0;