1/***
2  This file is part of libdaemon.
3
4  Copyright 2003-2008 Lennart Poettering
5
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.
10
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.
15
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***/
20
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
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>
40
41#include "dfork.h"
42#include "dnonblock.h"
43#include "dlog.h"
44
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
52
53static int _daemon_retval_pipe[2] = { -1, -1 };
54
55static int _null_open(int f, int fd) {
56    int fd2;
57
58    if ((fd2 = open("/dev/null", f)) < 0)
59        return -1;
60
61    if (fd2 == fd)
62        return fd;
63
64    if (dup2(fd2, fd) < 0)
65        return -1;
66
67    close(fd2);
68    return fd;
69}
70
71static ssize_t atomic_read(int fd, void *d, size_t l) {
72    ssize_t t = 0;
73
74    while (l > 0) {
75        ssize_t r;
76
77        if ((r = read(fd, d, l)) <= 0) {
78
79            if (r < 0)
80                return t > 0 ? t : -1;
81            else
82                return t;
83        }
84
85        t += r;
86        d = (char*) d + r;
87        l -= r;
88    }
89
90    return t;
91}
92
93static ssize_t atomic_write(int fd, const void *d, size_t l) {
94    ssize_t t = 0;
95
96    while (l > 0) {
97        ssize_t r;
98
99        if ((r = write(fd, d, l)) <= 0) {
100
101            if (r < 0)
102                return t > 0 ? t : -1;
103            else
104                return t;
105        }
106
107        t += r;
108        d = (const char*) d + r;
109        l -= r;
110    }
111
112    return t;
113}
114
115static int move_fd_up(int *fd) {
116    assert(fd);
117
118    while (*fd <= 2) {
119        if ((*fd = dup(*fd)) < 0) {
120            daemon_log(LOG_ERR, "dup(): %s", strerror(errno));
121            return -1;
122        }
123    }
124
125    return 0;
126}
127
128static void sigchld(int s) {
129}
130
131pid_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;
137
138    memset(&sa_new, 0, sizeof(sa_new));
139    sa_new.sa_handler = sigchld;
140    sa_new.sa_flags = SA_RESTART;
141
142    if (sigemptyset(&ss_new) < 0) {
143        daemon_log(LOG_ERR, "sigemptyset() failed: %s", strerror(errno));
144        return (pid_t) -1;
145    }
146
147    if (sigaddset(&ss_new, SIGCHLD) < 0) {
148        daemon_log(LOG_ERR, "sigaddset() failed: %s", strerror(errno));
149        return (pid_t) -1;
150    }
151
152    if (sigaction(SIGCHLD, &sa_new, &sa_old) < 0) {
153        daemon_log(LOG_ERR, "sigaction() failed: %s", strerror(errno));
154        return (pid_t) -1;
155    }
156
157    if (sigprocmask(SIG_UNBLOCK, &ss_new, &ss_old) < 0) {
158        daemon_log(LOG_ERR, "sigprocmask() failed: %s", strerror(errno));
159
160        saved_errno = errno;
161        sigaction(SIGCHLD, &sa_old, NULL);
162        errno = saved_errno;
163
164        return (pid_t) -1;
165    }
166
167    if (pipe(pipe_fds) < 0) {
168        daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
169
170        saved_errno = errno;
171        sigaction(SIGCHLD, &sa_old, NULL);
172        sigprocmask(SIG_SETMASK, &ss_old, NULL);
173        errno = saved_errno;
174
175        return (pid_t) -1;
176    }
177
178    if ((pid = fork()) < 0) { /* First fork */
179        daemon_log(LOG_ERR, "First fork() failed: %s", strerror(errno));
180
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;
187
188        return (pid_t) -1;
189
190    } else if (pid == 0) {
191        pid_t dpid;
192
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. */
196
197        if (daemon_log_use & DAEMON_LOG_AUTO)
198            daemon_log_use = DAEMON_LOG_SYSLOG;
199
200        if (close(pipe_fds[0]) < 0) {
201            daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
202            goto fail;
203        }
204
205        /* Move file descriptors up*/
206        if (move_fd_up(&pipe_fds[1]) < 0)
207            goto fail;
208
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;
213
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;
217        }
218
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;
222        }
223
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;
227        }
228
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;
236        }
237
238        umask(0077);
239
240        if (chdir("/") < 0) {
241            daemon_log(LOG_ERR, "chdir() failed: %s", strerror(errno));
242            goto fail;
243        }
244
245        if ((pid = fork()) < 0) { /* Second fork */
246            daemon_log(LOG_ERR, "Second fork() failed: %s", strerror(errno));
247            goto fail;
248
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. */
256
257            if (sigaction(SIGCHLD, &sa_old, NULL) < 0) {
258                daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
259                goto fail;
260            }
261
262            if (sigprocmask(SIG_SETMASK, &ss_old, NULL) < 0) {
263                daemon_log(LOG_ERR, "sigprocmask() failed: %s", strerror(errno));
264                goto fail;
265            }
266
267            if (signal(SIGTTOU, SIG_IGN) == SIG_ERR) {
268                daemon_log(LOG_ERR, "signal(SIGTTOU, SIG_IGN) failed: %s", strerror(errno));
269                goto fail;
270            }
271
272            if (signal(SIGTTIN, SIG_IGN) == SIG_ERR) {
273                daemon_log(LOG_ERR, "signal(SIGTTIN, SIG_IGN) failed: %s", strerror(errno));
274                goto fail;
275            }
276
277            if (signal(SIGTSTP, SIG_IGN) == SIG_ERR) {
278                daemon_log(LOG_ERR, "signal(SIGTSTP, SIG_IGN) failed: %s", strerror(errno));
279                goto fail;
280            }
281
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;
286            }
287
288            if (close(pipe_fds[1]) < 0) {
289                daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
290                goto fail;
291            }
292
293            return 0;
294
295        } else {
296            /* Second father */
297            close(pipe_fds[1]);
298            _exit(0);
299        }
300
301    fail:
302        dpid = (pid_t) -1;
303
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));
306
307        close(pipe_fds[1]);
308        _exit(0);
309
310    } else {
311        /* First father */
312        pid_t dpid;
313
314        close(pipe_fds[1]);
315
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;
323        }
324
325        sigprocmask(SIG_SETMASK, &ss_old, NULL);
326        sigaction(SIGCHLD, &sa_old, NULL);
327
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;
334
335        saved_errno = errno;
336        close(pipe_fds[0]);
337        errno = saved_errno;
338
339        return dpid;
340    }
341}
342
343int daemon_retval_init(void) {
344
345    if (_daemon_retval_pipe[0] < 0 || _daemon_retval_pipe[1] < 0) {
346
347        if (pipe(_daemon_retval_pipe) < 0) {
348            daemon_log(LOG_ERR, "pipe(): %s", strerror(errno));
349            return -1;
350        }
351    }
352
353    return 0;
354}
355
356void daemon_retval_done(void) {
357    int saved_errno = errno;
358
359    if (_daemon_retval_pipe[0] >= 0)
360        close(_daemon_retval_pipe[0]);
361
362    if (_daemon_retval_pipe[1] >= 0)
363        close(_daemon_retval_pipe[1]);
364
365    _daemon_retval_pipe[0] = _daemon_retval_pipe[1] = -1;
366
367    errno = saved_errno;
368}
369
370int daemon_retval_send(int i) {
371    ssize_t r;
372
373    if (_daemon_retval_pipe[1] < 0) {
374        errno = EINVAL;
375        return -1;
376    }
377
378    r = atomic_write(_daemon_retval_pipe[1], &i, sizeof(i));
379
380    daemon_retval_done();
381
382    if (r != sizeof(i)) {
383
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;
389        }
390
391        return -1;
392    }
393
394    return 0;
395}
396
397int daemon_retval_wait(int timeout) {
398    ssize_t r;
399    int i;
400
401    if (timeout > 0) {
402        struct timeval tv;
403        int s;
404        fd_set fds;
405
406        tv.tv_sec = timeout;
407        tv.tv_usec = 0;
408
409        FD_ZERO(&fds);
410        FD_SET(_daemon_retval_pipe[0], &fds);
411
412        if ((s = select(FD_SETSIZE, &fds, 0, 0, &tv)) != 1) {
413
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");
419            }
420
421            return -1;
422        }
423    }
424
425    if ((r = atomic_read(_daemon_retval_pipe[0], &i, sizeof(i))) != sizeof(i)) {
426
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;
435        }
436
437        return -1;
438    }
439
440    daemon_retval_done();
441
442    return i;
443}
444
445int daemon_close_all(int except_fd, ...) {
446    va_list ap;
447    int n = 0, i, r;
448    int *p;
449    int saved_errno;
450
451    va_start(ap, except_fd);
452
453    if (except_fd >= 0)
454        for (n = 1; va_arg(ap, int) >= 0; n++)
455            ;
456
457    va_end(ap);
458
459    if (!(p = malloc(sizeof(int) * (n+1))))
460        return -1;
461
462    va_start(ap, except_fd);
463
464    i = 0;
465    if (except_fd >= 0) {
466        int fd;
467        p[i++] = except_fd;
468
469        while ((fd = va_arg(ap, int)) >= 0)
470            p[i++] = fd;
471    }
472    p[i] = -1;
473
474    va_end(ap);
475
476    r = daemon_close_allv(p);
477
478    saved_errno = errno;
479    free(p);
480    errno = saved_errno;
481
482    return r;
483}
484
485/** Same as daemon_close_all but takes an array of fds, terminated by -1 */
486int daemon_close_allv(const int except_fds[]) {
487    struct rlimit rl;
488    int fd, maxfd;
489
490#ifdef __linux__
491    int saved_errno;
492
493    DIR *d;
494
495    if ((d = opendir("/proc/self/fd"))) {
496
497        struct dirent *de;
498
499        while ((de = readdir(d))) {
500            int found;
501            long l;
502            char *e = NULL;
503            int i;
504
505            if (de->d_name[0] == '.')
506                continue;
507
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;
514            }
515
516            fd = (int) l;
517
518            if ((long) fd != l) {
519                closedir(d);
520                errno = EINVAL;
521                return -1;
522            }
523
524            if (fd < 3)
525                continue;
526
527            if (fd == dirfd(d))
528                continue;
529
530            if (fd == _daemon_retval_pipe[1])
531                continue;
532
533            found = 0;
534            for (i = 0; except_fds[i] >= 0; i++)
535                if (except_fds[i] == fd) {
536                    found = 1;
537                    break;
538                }
539
540            if (found)
541                continue;
542
543            if (close(fd) < 0) {
544                saved_errno = errno;
545                closedir(d);
546                errno = saved_errno;
547
548                return -1;
549            }
550
551            if (fd == _daemon_retval_pipe[0])
552                _daemon_retval_pipe[0] = -1;    /* mark as closed */
553        }
554
555        closedir(d);
556        return 0;
557    }
558
559#endif
560
561    if (getrlimit(RLIMIT_NOFILE, &rl) > 0)
562        maxfd = (int) rl.rlim_max;
563    else
564        maxfd = sysconf(_SC_OPEN_MAX);
565
566    for (fd = 3; fd < maxfd; fd++) {
567        int i, found;
568
569        if (fd == _daemon_retval_pipe[1])
570            continue;
571
572        found = 0;
573        for (i = 0; except_fds[i] >= 0; i++)
574            if (except_fds[i] == fd) {
575                found = 1;
576                break;
577            }
578
579        if (found)
580            continue;
581
582        if (close(fd) < 0 && errno != EBADF)
583            return -1;
584
585        if (fd == _daemon_retval_pipe[0])
586            _daemon_retval_pipe[0] = -1;        /* mark as closed */
587    }
588
589    return 0;
590}
591
592int daemon_unblock_sigs(int except, ...) {
593    va_list ap;
594    int n = 0, i, r;
595    int *p;
596    int saved_errno;
597
598    va_start(ap, except);
599
600    if (except >= 1)
601        for (n = 1; va_arg(ap, int) >= 0; n++)
602            ;
603
604    va_end(ap);
605
606    if (!(p = malloc(sizeof(int) * (n+1))))
607        return -1;
608
609    va_start(ap, except);
610
611    i = 0;
612    if (except >= 1) {
613        int sig;
614        p[i++] = except;
615
616        while ((sig = va_arg(ap, int)) >= 0)
617            p[i++] = sig;
618    }
619    p[i] = -1;
620
621    va_end(ap);
622
623    r = daemon_unblock_sigsv(p);
624
625    saved_errno = errno;
626    free(p);
627    errno = saved_errno;
628
629    return r;
630}
631
632int daemon_unblock_sigsv(const int except[]) {
633    int i;
634    sigset_t ss;
635
636    if (sigemptyset(&ss) < 0)
637        return -1;
638
639    for (i = 0; except[i] > 0; i++)
640        if (sigaddset(&ss, except[i]) < 0)
641            return -1;
642
643    return sigprocmask(SIG_SETMASK, &ss, NULL);
644}
645
646int daemon_reset_sigs(int except, ...) {
647    va_list ap;
648    int n = 0, i, r;
649    int *p;
650    int saved_errno;
651
652    va_start(ap, except);
653
654    if (except >= 1)
655        for (n = 1; va_arg(ap, int) >= 0; n++)
656            ;
657
658    va_end(ap);
659
660    if (!(p = malloc(sizeof(int) * (n+1))))
661        return -1;
662
663    va_start(ap, except);
664
665    i = 0;
666    if (except >= 1) {
667        int sig;
668        p[i++] = except;
669
670        while ((sig = va_arg(ap, int)) >= 0)
671            p[i++] = sig;
672    }
673    p[i] = -1;
674
675    va_end(ap);
676
677    r = daemon_reset_sigsv(p);
678
679    saved_errno = errno;
680    free(p);
681    errno = saved_errno;
682
683    return r;
684}
685
686int daemon_reset_sigsv(const int except[]) {
687    int sig;
688
689    for (sig = 1; sig < SIGNAL_UPPER_BOUND; sig++) {
690        int reset = 1;
691
692        switch (sig) {
693            case SIGKILL:
694            case SIGSTOP:
695                reset = 0;
696                break;
697
698            default: {
699                int i;
700
701                for (i = 0; except[i] > 0; i++) {
702                    if (sig == except[i]) {
703                        reset = 0;
704                        break;
705                    }
706                }
707            }
708        }
709
710        if (reset) {
711            struct sigaction sa;
712
713            memset(&sa, 0, sizeof(sa));
714            sa.sa_handler = SIG_DFL;
715
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;
721        }
722    }
723
724    return 0;
725}
726