aboutsummaryrefslogtreecommitdiff
path: root/contrib/bind9/bin/named/unix/os.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/bin/named/unix/os.c')
-rw-r--r--contrib/bind9/bin/named/unix/os.c56
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 7df7f3b41b56..797754948de3 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) {