Home | History | Annotate | Download | only in libdaemon
      1 /***
      2   This file is part of libdaemon.
      3 
      4   Copyright 2003-2008 Lennart Poettering
      5 
      6   Permission is hereby granted, free of charge, to any person obtaining a copy
      7   of this software and associated documentation files (the "Software"), to deal
      8   in the Software without restriction, including without limitation the rights
      9   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10   copies of the Software, and to permit persons to whom the Software is
     11   furnished to do so, subject to the following conditions:
     12 
     13   The above copyright notice and this permission notice shall be included in
     14   all copies or substantial portions of the Software.
     15 
     16   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22   SOFTWARE.
     23 
     24 ***/
     25 
     26 #ifdef HAVE_CONFIG_H
     27 #include <config.h>
     28 #endif
     29 
     30 #include <sys/types.h>
     31 #include <unistd.h>
     32 #include <errno.h>
     33 #include <string.h>
     34 #include <fcntl.h>
     35 #include <sys/stat.h>
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #include <sys/wait.h>
     39 #include <assert.h>
     40 #include <sys/ioctl.h>
     41 #include <signal.h>
     42 #include <sys/time.h>
     43 #include <sys/resource.h>
     44 #include <dirent.h>
     45 
     46 #include "dfork.h"
     47 #include "dnonblock.h"
     48 #include "dlog.h"
     49 
     50 #if defined(_NSIG) /* On glibc NSIG does not count RT signals */
     51 # define SIGNAL_UPPER_BOUND _NSIG
     52 #elif defined(NSIG) /* Solaris defines just this */
     53 # define SIGNAL_UPPER_BOUND NSIG
     54 #else
     55 # error "Unknown upper bound for signals"
     56 #endif
     57 
     58 static int _daemon_retval_pipe[2] = { -1, -1 };
     59 
     60 static int _null_open(int f, int fd) {
     61     int fd2;
     62 
     63     if ((fd2 = open("/dev/null", f)) < 0)
     64         return -1;
     65 
     66     if (fd2 == fd)
     67         return fd;
     68 
     69     if (dup2(fd2, fd) < 0)
     70         return -1;
     71 
     72     close(fd2);
     73     return fd;
     74 }
     75 
     76 static ssize_t atomic_read(int fd, void *d, size_t l) {
     77     ssize_t t = 0;
     78 
     79     while (l > 0) {
     80         ssize_t r;
     81 
     82         if ((r = read(fd, d, l)) <= 0) {
     83 
     84             if (r < 0)
     85                 return t > 0 ? t : -1;
     86             else
     87                 return t;
     88         }
     89 
     90         t += r;
     91         d = (char*) d + r;
     92         l -= r;
     93     }
     94 
     95     return t;
     96 }
     97 
     98 static ssize_t atomic_write(int fd, const void *d, size_t l) {
     99     ssize_t t = 0;
    100 
    101     while (l > 0) {
    102         ssize_t r;
    103 
    104         if ((r = write(fd, d, l)) <= 0) {
    105 
    106             if (r < 0)
    107                 return t > 0 ? t : -1;
    108             else
    109                 return t;
    110         }
    111 
    112         t += r;
    113         d = (const char*) d + r;
    114         l -= r;
    115     }
    116 
    117     return t;
    118 }
    119 
    120 static int move_fd_up(int *fd) {
    121     assert(fd);
    122 
    123     while (*fd <= 2) {
    124         if ((*fd = dup(*fd)) < 0) {
    125             daemon_log(LOG_ERR, "dup(): %s", strerror(errno));
    126             return -1;
    127         }
    128     }
    129 
    130     return 0;
    131 }
    132 
    133 static void sigchld(int s) {
    134 }
    135 
    136 pid_t daemon_fork(void) {
    137     pid_t pid;
    138     int pipe_fds[2] = {-1, -1};
    139     struct sigaction sa_old, sa_new;
    140     sigset_t ss_old, ss_new;
    141     int saved_errno;
    142 
    143     memset(&sa_new, 0, sizeof(sa_new));
    144     sa_new.sa_handler = sigchld;
    145     sa_new.sa_flags = SA_RESTART;
    146 
    147     if (sigemptyset(&ss_new) < 0) {
    148         daemon_log(LOG_ERR, "sigemptyset() failed: %s", strerror(errno));
    149         return (pid_t) -1;
    150     }
    151 
    152     if (sigaddset(&ss_new, SIGCHLD) < 0) {
    153         daemon_log(LOG_ERR, "sigaddset() failed: %s", strerror(errno));
    154         return (pid_t) -1;
    155     }
    156 
    157     if (sigaction(SIGCHLD, &sa_new, &sa_old) < 0) {
    158         daemon_log(LOG_ERR, "sigaction() failed: %s", strerror(errno));
    159         return (pid_t) -1;
    160     }
    161 
    162     if (sigprocmask(SIG_UNBLOCK, &ss_new, &ss_old) < 0) {
    163         daemon_log(LOG_ERR, "sigprocmask() failed: %s", strerror(errno));
    164 
    165         saved_errno = errno;
    166         sigaction(SIGCHLD, &sa_old, NULL);
    167         errno = saved_errno;
    168 
    169         return (pid_t) -1;
    170     }
    171 
    172     if (pipe(pipe_fds) < 0) {
    173         daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
    174 
    175         saved_errno = errno;
    176         sigaction(SIGCHLD, &sa_old, NULL);
    177         sigprocmask(SIG_SETMASK, &ss_old, NULL);
    178         errno = saved_errno;
    179 
    180         return (pid_t) -1;
    181     }
    182 
    183     if ((pid = fork()) < 0) { /* First fork */
    184         daemon_log(LOG_ERR, "First fork() failed: %s", strerror(errno));
    185 
    186         saved_errno = errno;
    187         close(pipe_fds[0]);
    188         close(pipe_fds[1]);
    189         sigaction(SIGCHLD, &sa_old, NULL);
    190         sigprocmask(SIG_SETMASK, &ss_old, NULL);
    191         errno = saved_errno;
    192 
    193         return (pid_t) -1;
    194 
    195     } else if (pid == 0) {
    196         pid_t dpid;
    197 
    198         /* First child. Now we are sure not to be a session leader or
    199          * process group leader anymore, i.e. we know that setsid()
    200          * will succeed. */
    201 
    202         if (daemon_log_use & DAEMON_LOG_AUTO)
    203             daemon_log_use = DAEMON_LOG_SYSLOG;
    204 
    205         if (close(pipe_fds[0]) < 0) {
    206             daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
    207             goto fail;
    208         }
    209 
    210         /* Move file descriptors up*/
    211         if (move_fd_up(&pipe_fds[1]) < 0)
    212             goto fail;
    213 
    214         if (_daemon_retval_pipe[0] >= 0 && move_fd_up(&_daemon_retval_pipe[0]) < 0)
    215             goto fail;
    216         if (_daemon_retval_pipe[1] >= 0 && move_fd_up(&_daemon_retval_pipe[1]) < 0)
    217             goto fail;
    218 
    219         if (_null_open(O_RDONLY, 0) < 0) {
    220             daemon_log(LOG_ERR, "Failed to open /dev/null for STDIN: %s", strerror(errno));
    221             goto fail;
    222         }
    223 
    224         if (_null_open(O_WRONLY, 1) < 0) {
    225             daemon_log(LOG_ERR, "Failed to open /dev/null for STDOUT: %s", strerror(errno));
    226             goto fail;
    227         }
    228 
    229         if (_null_open(O_WRONLY, 2) < 0) {
    230             daemon_log(LOG_ERR, "Failed to open /dev/null for STDERR: %s", strerror(errno));
    231             goto fail;
    232         }
    233 
    234         /* Create a new session. This will create a new session and a
    235          * new process group for us and we will be the ledaer of
    236          * both. This should always succeed because we cannot be the
    237          * process group leader because we just forked. */
    238         if (setsid() < 0) {
    239             daemon_log(LOG_ERR, "setsid() failed: %s", strerror(errno));
    240             goto fail;
    241         }
    242 
    243         umask(0077);
    244 
    245         if (chdir("/") < 0) {
    246             daemon_log(LOG_ERR, "chdir() failed: %s", strerror(errno));
    247             goto fail;
    248         }
    249 
    250         if ((pid = fork()) < 0) { /* Second fork */
    251             daemon_log(LOG_ERR, "Second fork() failed: %s", strerror(errno));
    252             goto fail;
    253 
    254         } else if (pid == 0) {
    255             /* Second child. Our father will exit right-away. That way
    256              * we can be sure that we are a child of init now, even if
    257              * the process which spawned us stays around for a longer
    258              * time. Also, since we are no session leader anymore we
    259              * can be sure that we will never acquire a controlling
    260              * TTY. */
    261 
    262             if (sigaction(SIGCHLD, &sa_old, NULL) < 0) {
    263                 daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
    264                 goto fail;
    265             }
    266 
    267             if (sigprocmask(SIG_SETMASK, &ss_old, NULL) < 0) {
    268                 daemon_log(LOG_ERR, "sigprocmask() failed: %s", strerror(errno));
    269                 goto fail;
    270             }
    271 
    272             if (signal(SIGTTOU, SIG_IGN) == SIG_ERR) {
    273                 daemon_log(LOG_ERR, "signal(SIGTTOU, SIG_IGN) failed: %s", strerror(errno));
    274                 goto fail;
    275             }
    276 
    277             if (signal(SIGTTIN, SIG_IGN) == SIG_ERR) {
    278                 daemon_log(LOG_ERR, "signal(SIGTTIN, SIG_IGN) failed: %s", strerror(errno));
    279                 goto fail;
    280             }
    281 
    282             if (signal(SIGTSTP, SIG_IGN) == SIG_ERR) {
    283                 daemon_log(LOG_ERR, "signal(SIGTSTP, SIG_IGN) failed: %s", strerror(errno));
    284                 goto fail;
    285             }
    286 
    287             dpid = getpid();
    288             if (atomic_write(pipe_fds[1], &dpid, sizeof(dpid)) != sizeof(dpid)) {
    289                 daemon_log(LOG_ERR, "write() failed: %s", strerror(errno));
    290                 goto fail;
    291             }
    292 
    293             if (close(pipe_fds[1]) < 0) {
    294                 daemon_log(LOG_ERR, "close() failed: %s", strerror(errno));
    295                 goto fail;
    296             }
    297 
    298             return 0;
    299 
    300         } else {
    301             /* Second father */
    302             close(pipe_fds[1]);
    303             _exit(0);
    304         }
    305 
    306     fail:
    307         dpid = (pid_t) -1;
    308 
    309         if (atomic_write(pipe_fds[1], &dpid, sizeof(dpid)) != sizeof(dpid))
    310             daemon_log(LOG_ERR, "Failed to write error PID: %s", strerror(errno));
    311 
    312         close(pipe_fds[1]);
    313         _exit(0);
    314 
    315     } else {
    316         /* First father */
    317         pid_t dpid;
    318 
    319         close(pipe_fds[1]);
    320 
    321         if (waitpid(pid, NULL, WUNTRACED) < 0) {
    322             saved_errno = errno;
    323             close(pipe_fds[0]);
    324             sigaction(SIGCHLD, &sa_old, NULL);
    325             sigprocmask(SIG_SETMASK, &ss_old, NULL);
    326             errno = saved_errno;
    327             return -1;
    328         }
    329 
    330         sigprocmask(SIG_SETMASK, &ss_old, NULL);
    331         sigaction(SIGCHLD, &sa_old, NULL);
    332 
    333         if (atomic_read(pipe_fds[0], &dpid, sizeof(dpid)) != sizeof(dpid)) {
    334             daemon_log(LOG_ERR, "Failed to read daemon PID.");
    335             dpid = (pid_t) -1;
    336             errno = EINVAL;
    337         } else if (dpid == (pid_t) -1)
    338             errno = EIO;
    339 
    340         saved_errno = errno;
    341         close(pipe_fds[0]);
    342         errno = saved_errno;
    343 
    344         return dpid;
    345     }
    346 }
    347 
    348 int daemon_retval_init(void) {
    349 
    350     if (_daemon_retval_pipe[0] < 0 || _daemon_retval_pipe[1] < 0) {
    351 
    352         if (pipe(_daemon_retval_pipe) < 0) {
    353             daemon_log(LOG_ERR, "pipe(): %s", strerror(errno));
    354             return -1;
    355         }
    356     }
    357 
    358     return 0;
    359 }
    360 
    361 void daemon_retval_done(void) {
    362     int saved_errno = errno;
    363 
    364     if (_daemon_retval_pipe[0] >= 0)
    365         close(_daemon_retval_pipe[0]);
    366 
    367     if (_daemon_retval_pipe[1] >= 0)
    368         close(_daemon_retval_pipe[1]);
    369 
    370     _daemon_retval_pipe[0] = _daemon_retval_pipe[1] = -1;
    371 
    372     errno = saved_errno;
    373 }
    374 
    375 int daemon_retval_send(int i) {
    376     ssize_t r;
    377 
    378     if (_daemon_retval_pipe[1] < 0) {
    379         errno = EINVAL;
    380         return -1;
    381     }
    382 
    383     r = atomic_write(_daemon_retval_pipe[1], &i, sizeof(i));
    384 
    385     daemon_retval_done();
    386 
    387     if (r != sizeof(i)) {
    388 
    389         if (r < 0)
    390             daemon_log(LOG_ERR, "write() failed while writing return value to pipe: %s", strerror(errno));
    391         else {
    392             daemon_log(LOG_ERR, "write() too short while writing return value from pipe");
    393             errno = EINVAL;
    394         }
    395 
    396         return -1;
    397     }
    398 
    399     return 0;
    400 }
    401 
    402 int daemon_retval_wait(int timeout) {
    403     ssize_t r;
    404     int i;
    405 
    406     if (timeout > 0) {
    407         struct timeval tv;
    408         int s;
    409         fd_set fds;
    410 
    411         tv.tv_sec = timeout;
    412         tv.tv_usec = 0;
    413 
    414         FD_ZERO(&fds);
    415         FD_SET(_daemon_retval_pipe[0], &fds);
    416 
    417         if ((s = select(FD_SETSIZE, &fds, 0, 0, &tv)) != 1) {
    418 
    419             if (s < 0)
    420                 daemon_log(LOG_ERR, "select() failed while waiting for return value: %s", strerror(errno));
    421             else {
    422                 errno = ETIMEDOUT;
    423                 daemon_log(LOG_ERR, "Timeout reached while wating for return value");
    424             }
    425 
    426             return -1;
    427         }
    428     }
    429 
    430     if ((r = atomic_read(_daemon_retval_pipe[0], &i, sizeof(i))) != sizeof(i)) {
    431 
    432         if (r < 0)
    433             daemon_log(LOG_ERR, "read() failed while reading return value from pipe: %s", strerror(errno));
    434         else if (r == 0) {
    435             daemon_log(LOG_ERR, "read() failed with EOF while reading return value from pipe.");
    436             errno = EINVAL;
    437         } else if (r > 0) {
    438             daemon_log(LOG_ERR, "read() too short while reading return value from pipe.");
    439             errno = EINVAL;
    440         }
    441 
    442         return -1;
    443     }
    444 
    445     daemon_retval_done();
    446 
    447     return i;
    448 }
    449 
    450 int daemon_close_all(int except_fd, ...) {
    451     va_list ap;
    452     int n = 0, i, r;
    453     int *p;
    454     int saved_errno;
    455 
    456     va_start(ap, except_fd);
    457 
    458     if (except_fd >= 0)
    459         for (n = 1; va_arg(ap, int) >= 0; n++)
    460             ;
    461 
    462     va_end(ap);
    463 
    464     if (!(p = malloc(sizeof(int) * (n+1))))
    465         return -1;
    466 
    467     va_start(ap, except_fd);
    468 
    469     i = 0;
    470     if (except_fd >= 0) {
    471         int fd;
    472         p[i++] = except_fd;
    473 
    474         while ((fd = va_arg(ap, int)) >= 0)
    475             p[i++] = fd;
    476     }
    477     p[i] = -1;
    478 
    479     va_end(ap);
    480 
    481     r = daemon_close_allv(p);
    482 
    483     saved_errno = errno;
    484     free(p);
    485     errno = saved_errno;
    486 
    487     return r;
    488 }
    489 
    490 /** Same as daemon_close_all but takes an array of fds, terminated by -1 */
    491 int daemon_close_allv(const int except_fds[]) {
    492     struct rlimit rl;
    493     int fd, maxfd;
    494 
    495 #ifdef __linux__
    496     int saved_errno;
    497 
    498     DIR *d;
    499 
    500     if ((d = opendir("/proc/self/fd"))) {
    501 
    502         struct dirent *de;
    503 
    504         while ((de = readdir(d))) {
    505             int found;
    506             long l;
    507             char *e = NULL;
    508             int i;
    509 
    510             if (de->d_name[0] == '.')
    511                 continue;
    512 
    513             errno = 0;
    514             l = strtol(de->d_name, &e, 10);
    515             if (errno != 0 || !e || *e) {
    516                 closedir(d);
    517                 errno = EINVAL;
    518                 return -1;
    519             }
    520 
    521             fd = (int) l;
    522 
    523             if ((long) fd != l) {
    524                 closedir(d);
    525                 errno = EINVAL;
    526                 return -1;
    527             }
    528 
    529             if (fd < 3)
    530                 continue;
    531 
    532             if (fd == dirfd(d))
    533                 continue;
    534 
    535             if (fd == _daemon_retval_pipe[1])
    536                 continue;
    537 
    538             found = 0;
    539             for (i = 0; except_fds[i] >= 0; i++)
    540                 if (except_fds[i] == fd) {
    541                     found = 1;
    542                     break;
    543                 }
    544 
    545             if (found)
    546                 continue;
    547 
    548             if (close(fd) < 0) {
    549                 saved_errno = errno;
    550                 closedir(d);
    551                 errno = saved_errno;
    552 
    553                 return -1;
    554             }
    555 
    556             if (fd == _daemon_retval_pipe[0])
    557                 _daemon_retval_pipe[0] = -1;    /* mark as closed */
    558         }
    559 
    560         closedir(d);
    561         return 0;
    562     }
    563 
    564 #endif
    565 
    566     if (getrlimit(RLIMIT_NOFILE, &rl) > 0)
    567         maxfd = (int) rl.rlim_max;
    568     else
    569         maxfd = sysconf(_SC_OPEN_MAX);
    570 
    571     for (fd = 3; fd < maxfd; fd++) {
    572         int i, found;
    573 
    574         if (fd == _daemon_retval_pipe[1])
    575             continue;
    576 
    577         found = 0;
    578         for (i = 0; except_fds[i] >= 0; i++)
    579             if (except_fds[i] == fd) {
    580                 found = 1;
    581                 break;
    582             }
    583 
    584         if (found)
    585             continue;
    586 
    587         if (close(fd) < 0 && errno != EBADF)
    588             return -1;
    589 
    590         if (fd == _daemon_retval_pipe[0])
    591             _daemon_retval_pipe[0] = -1;        /* mark as closed */
    592     }
    593 
    594     return 0;
    595 }
    596 
    597 int daemon_unblock_sigs(int except, ...) {
    598     va_list ap;
    599     int n = 0, i, r;
    600     int *p;
    601     int saved_errno;
    602 
    603     va_start(ap, except);
    604 
    605     if (except >= 1)
    606         for (n = 1; va_arg(ap, int) >= 0; n++)
    607             ;
    608 
    609     va_end(ap);
    610 
    611     if (!(p = malloc(sizeof(int) * (n+1))))
    612         return -1;
    613 
    614     va_start(ap, except);
    615 
    616     i = 0;
    617     if (except >= 1) {
    618         int sig;
    619         p[i++] = except;
    620 
    621         while ((sig = va_arg(ap, int)) >= 0)
    622             p[i++] = sig;
    623     }
    624     p[i] = -1;
    625 
    626     va_end(ap);
    627 
    628     r = daemon_unblock_sigsv(p);
    629 
    630     saved_errno = errno;
    631     free(p);
    632     errno = saved_errno;
    633 
    634     return r;
    635 }
    636 
    637 int daemon_unblock_sigsv(const int except[]) {
    638     int i;
    639     sigset_t ss;
    640 
    641     if (sigemptyset(&ss) < 0)
    642         return -1;
    643 
    644     for (i = 0; except[i] > 0; i++)
    645         if (sigaddset(&ss, except[i]) < 0)
    646             return -1;
    647 
    648     return sigprocmask(SIG_SETMASK, &ss, NULL);
    649 }
    650 
    651 int daemon_reset_sigs(int except, ...) {
    652     va_list ap;
    653     int n = 0, i, r;
    654     int *p;
    655     int saved_errno;
    656 
    657     va_start(ap, except);
    658 
    659     if (except >= 1)
    660         for (n = 1; va_arg(ap, int) >= 0; n++)
    661             ;
    662 
    663     va_end(ap);
    664 
    665     if (!(p = malloc(sizeof(int) * (n+1))))
    666         return -1;
    667 
    668     va_start(ap, except);
    669 
    670     i = 0;
    671     if (except >= 1) {
    672         int sig;
    673         p[i++] = except;
    674 
    675         while ((sig = va_arg(ap, int)) >= 0)
    676             p[i++] = sig;
    677     }
    678     p[i] = -1;
    679 
    680     va_end(ap);
    681 
    682     r = daemon_reset_sigsv(p);
    683 
    684     saved_errno = errno;
    685     free(p);
    686     errno = saved_errno;
    687 
    688     return r;
    689 }
    690 
    691 int daemon_reset_sigsv(const int except[]) {
    692     int sig;
    693 
    694     for (sig = 1; sig < SIGNAL_UPPER_BOUND; sig++) {
    695         int reset = 1;
    696 
    697         switch (sig) {
    698             case SIGKILL:
    699             case SIGSTOP:
    700                 reset = 0;
    701                 break;
    702 
    703             default: {
    704                 int i;
    705 
    706                 for (i = 0; except[i] > 0; i++) {
    707                     if (sig == except[i]) {
    708                         reset = 0;
    709                         break;
    710                     }
    711                 }
    712             }
    713         }
    714 
    715         if (reset) {
    716             struct sigaction sa;
    717 
    718             memset(&sa, 0, sizeof(sa));
    719             sa.sa_handler = SIG_DFL;
    720 
    721             /* On Linux the first two RT signals are reserved by
    722              * glibc, and sigaction() will return EINVAL for them. */
    723             if ((sigaction(sig, &sa, NULL) < 0))
    724                 if (errno != EINVAL)
    725                     return -1;
    726         }
    727     }
    728 
    729     return 0;
    730 }
    731