~ubuntu-branches/ubuntu/vivid/cctools/vivid

« back to all changes in this revision

Viewing changes to dttools/src/daemon.c

  • Committer: Package Import Robot
  • Author(s): Michael Hanke
  • Date: 2012-03-30 12:40:01 UTC
  • mfrom: (9.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20120330124001-ze0lhxm5uwq2e3mo
Tags: 3.4.2-2
Added patch to handle a missing CFLAGS variable in Python's sysconfig
report (Closes: #661658).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "daemon.h"
 
2
 
 
3
#include "debug.h"
 
4
 
 
5
#include <unistd.h>
 
6
#include <fcntl.h>
 
7
#include <sys/stat.h>
 
8
 
 
9
#include <errno.h>
 
10
#include <limits.h>
 
11
#include <stdlib.h>
 
12
#include <string.h>
 
13
 
 
14
#if defined(OPEN_MAX)
 
15
#define DAEMON_FD_MAX  OPEN_MAX
 
16
#elif defined(_POSIX_OPEN_MAX)
 
17
#define DAEMON_FD_MAX  _POSIX_OPEN_MAX
 
18
#else
 
19
#define DAEMON_FD_MAX  0
 
20
#endif
 
21
 
 
22
#define OPEN_MAX_GUESS  256
 
23
 
 
24
static int fd_max (void)
 
25
{
 
26
        errno = 0;
 
27
        int max = (int) sysconf(_SC_OPEN_MAX);
 
28
        if (max == -1) {
 
29
                if (errno == 0) {
 
30
                        if (DAEMON_FD_MAX == 0) { /* indefinite limit */
 
31
                                max = OPEN_MAX_GUESS;
 
32
                        } else {
 
33
                                max = DAEMON_FD_MAX;
 
34
                        }
 
35
                } else {
 
36
                        debug(D_DEBUG, "sysconf(_SC_OPEN_MAX) error: %s", strerror(errno));
 
37
                        exit(EXIT_FAILURE);
 
38
                }
 
39
        }
 
40
        return max;
 
41
}
 
42
 
 
43
void daemonize (int cdroot)
 
44
{
 
45
        /* Become seesion leader and lose controlling terminal */
 
46
        pid_t pid = fork();
 
47
        if (pid < 0) {
 
48
                debug(D_DEBUG, "could not fork: %s", strerror(errno));
 
49
                exit(EXIT_FAILURE);
 
50
        } else if (pid > 0) {
 
51
                exit(EXIT_SUCCESS); /* exit parent */
 
52
        }
 
53
 
 
54
        pid_t group = setsid();
 
55
        if (group == (pid_t) -1) {
 
56
                debug(D_DEBUG, "could not create session: %s", strerror(errno));
 
57
                exit(EXIT_FAILURE);
 
58
        }
 
59
 
 
60
        /* Second fork ensures process cannot acquire controlling terminal */
 
61
        pid = fork();
 
62
        if (pid < 0) {
 
63
                debug(D_DEBUG, "could not fork: %s", strerror(errno));
 
64
                exit(EXIT_FAILURE);
 
65
        } else if (pid > 0) {
 
66
                exit(EXIT_SUCCESS); /* exit parent */
 
67
        }
 
68
 
 
69
        if (cdroot){
 
70
                int status = chdir("/");
 
71
                if (status == -1) {
 
72
                        debug(D_DEBUG, "could not chdir to `/': %s", strerror(errno));
 
73
                        exit(EXIT_FAILURE);
 
74
                }
 
75
        }
 
76
 
 
77
        umask(0);
 
78
 
 
79
        int fd, max = fd_max();
 
80
        for (fd = 0; fd < max; fd++) {
 
81
                if (close(fd) == -1 && errno != EBADF) {
 
82
                        debug(D_DEBUG, "could not close open file descriptor: %s", strerror(errno));
 
83
                        exit(EXIT_FAILURE);
 
84
                }
 
85
        }
 
86
 
 
87
        int fd0 = open("/dev/null", O_RDONLY);
 
88
        int fd1 = open("/dev/null", O_WRONLY);
 
89
        int fd2 = open("/dev/null", O_WRONLY);
 
90
 
 
91
        if (!(fd0 == STDIN_FILENO && fd1 == STDOUT_FILENO && fd2 == STDERR_FILENO)) {
 
92
                debug(D_DEBUG, "could not open `/dev/null': %d %d %d: %s", fd0, fd1, fd2, strerror(errno));
 
93
                exit(EXIT_FAILURE);
 
94
        }
 
95
}