diff options
Diffstat (limited to 'contrib/bind9/bin/named/unix/os.c')
-rw-r--r-- | contrib/bind9/bin/named/unix/os.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/contrib/bind9/bin/named/unix/os.c b/contrib/bind9/bin/named/unix/os.c index 7df7f3b..7977549 100644 --- a/contrib/bind9/bin/named/unix/os.c +++ b/contrib/bind9/bin/named/unix/os.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: os.c,v 1.46.2.4.8.16 2004/05/04 03:19:42 marka Exp $ */ +/* $Id: os.c,v 1.46.2.4.8.19 2004/10/07 02:34:20 marka Exp $ */ #include <config.h> #include <stdarg.h> @@ -104,6 +104,7 @@ static pid_t mainpid = 0; static struct passwd *runas_pw = NULL; static isc_boolean_t done_setuid = ISC_FALSE; +static int dfd[2] = { -1, -1 }; #ifdef HAVE_LINUX_CAPABILITY_H @@ -161,7 +162,10 @@ linux_setcaps(unsigned int caps) { cap.inheritable = caps; if (syscall(SYS_capset, &caphead, &cap) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("capset failed: %s", strbuf); + ns_main_earlyfatal("capset failed: %s:" + " please ensure that the capset kernel" + " module is loaded. see insmod(8)", + strbuf); } } @@ -302,13 +306,33 @@ ns_os_daemonize(void) { pid_t pid; char strbuf[ISC_STRERRORSIZE]; + if (pipe(dfd) == -1) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("pipe(): %s", strbuf); + } + pid = fork(); if (pid == -1) { isc__strerror(errno, strbuf, sizeof(strbuf)); ns_main_earlyfatal("fork(): %s", strbuf); } - if (pid != 0) - _exit(0); + if (pid != 0) { + int n; + /* + * Wait for the child to finish loading for the first time. + * This would be so much simpler if fork() worked once we + * were multi-threaded. + */ + (void)close(dfd[1]); + do { + char buf; + n = read(dfd[0], &buf, 1); + if (n == 1) + _exit(0); + } while (n == -1 && errno == EINTR); + _exit(1); + } + (void)close(dfd[0]); /* * We're the child. @@ -350,6 +374,20 @@ ns_os_daemonize(void) { } void +ns_os_started(void) { + char buf = 0; + + /* + * Signal to the parent that we stated successfully. + */ + if (dfd[0] != -1 && dfd[1] != -1) { + write(dfd[1], &buf, 1); + close(dfd[1]); + dfd[0] = dfd[1] = -1; + } +} + +void ns_os_opendevnull(void) { devnullfd = open("/dev/null", O_RDWR, 0); } @@ -426,10 +464,14 @@ ns_os_changeuser(void) { #ifdef HAVE_LINUXTHREADS #ifdef HAVE_LINUX_CAPABILITY_H if (!non_root_caps) + ns_main_earlyfatal("-u with Linux threads not supported: " + "requires kernel support for " + "prctl(PR_SET_KEEPCAPS)"); +#else + ns_main_earlyfatal("-u with Linux threads not supported: " + "no capabilities support or capabilities " + "disabled at build time"); #endif - ns_main_earlyfatal( - "-u not supported on Linux kernels older than " - "2.3.99-pre3 or 2.2.18 when using threads"); #endif if (setgid(runas_pw->pw_gid) < 0) { |