diff --git nsd.c nsd.c index 98dec613..e9d7b2cc 100644 --- nsd.c +++ nsd.c @@ -91,6 +91,9 @@ usage (void) " -n tcp-count The maximum number of TCP connections per server.\n" " -P pidfile Specify the PID file to write.\n" " -p port Specify the port to listen to.\n" + " -r Print a newline into the file descriptor index\n" + " described in the READY_FD environment variable to\n" + " indicate that nsd is ready to accept connections.\n" " -s seconds Dump statistics every SECONDS seconds.\n" " -t chrootdir Change root to specified directory on startup.\n" ); @@ -323,6 +326,24 @@ sig_handler(int sig) } } +/* + * Parse envvar as a positive integer. + * + */ +int +get_fd_from_env(const char* key) +{ + char *env = getenv(key); + if (!env || env[0] == '\0') + return -1; + errno = 0; + char *endptr; + int fd = (int)strtol(env, &endptr, 10); + if (errno != 0 || endptr[0] != '\0') + return -1; + return fd; +} + /* * Statistic output... * @@ -450,7 +471,7 @@ main(int argc, char *argv[]) } /* Parse the command line... */ - while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:s:u:t:X:V:v" + while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:rs:u:t:X:V:v" #ifndef NDEBUG /* only when configured with --enable-checking */ "F:L:" #endif /* NDEBUG */ @@ -533,6 +554,9 @@ main(int argc, char *argv[]) tcp_port = optarg; udp_port = optarg; break; + case 'r': + nsd.readyfd = 1; + break; case 's': #ifdef BIND8_STATS nsd.st.period = atoi(optarg); @@ -965,6 +989,18 @@ main(int argc, char *argv[]) } #endif /* HAVE_SSL */ + /* When asked to notify readiness via REⒶDY_FD, do so. */ + if (nsd.readyfd) { + int readyfd = get_fd_from_env("READY_FD"); + if (readyfd < 0) + error("READY_FD unset or contains garbage"); + unsetenv("READY_FD"); + int ret = dprintf(readyfd, "\n"); + close(readyfd); + if (ret < 0) + error("could not write to READY_FD index"); + } + /* Unless we're debugging, fork... */ if (!nsd.debug) { int fd; diff --git nsd.h nsd.h index de3ae8e1..ff27b798 100644 --- nsd.h +++ nsd.h @@ -179,6 +179,7 @@ struct nsd unsigned server_kind; struct namedb *db; int debug; + int readyfd; size_t child_count; struct nsd_child *children;