From b07d504ca4e476d492beb5552344070e4f96464a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 2 Mar 2012 19:32:56 +1100 Subject: change low FDs are handled in Samba We now only close fds 0, 1, 2 when we are a forked daemon, and take care not to close a file descriptor that we might need for foreground stdin monitoring. This should fix stdout logging in the lsa and epmapper deamons (ie in make test). Andrew Bartlett --- lib/util/become_daemon.c | 22 ++++++++++++++-------- lib/util/debug.c | 11 ++++++++--- lib/util/samba_util.h | 2 +- source3/printing/spoolssd.c | 3 --- source3/rpc_server/epmd.c | 3 --- source3/rpc_server/lsasd.c | 3 --- source3/smbd/server.c | 12 ++---------- 7 files changed, 25 insertions(+), 31 deletions(-) diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c index 2af16316b5..4c1d29e5a7 100644 --- a/lib/util/become_daemon.c +++ b/lib/util/become_daemon.c @@ -29,14 +29,16 @@ Close the low 3 fd's and open dev/null in their place. ********************************************************************/ -_PUBLIC_ void close_low_fds(bool stderr_too) +_PUBLIC_ void close_low_fds(bool stdin_too, bool stdout_too, bool stderr_too) { #ifndef VALGRIND int fd; int i; - close(0); - close(1); + if (stdin_too) + close(0); + if (stdout_too) + close(1); if (stderr_too) close(2); @@ -44,6 +46,10 @@ _PUBLIC_ void close_low_fds(bool stderr_too) /* try and use up these file descriptors, so silly library routines writing to stdout etc won't cause havoc */ for (i=0;i<3;i++) { + if (i == 0 && !stdin_too) + continue; + if (i == 1 && !stdout_too) + continue; if (i == 2 && !stderr_too) continue; @@ -87,9 +93,9 @@ _PUBLIC_ void become_daemon(bool do_fork, bool no_process_group, bool log_stdout } #endif /* HAVE_SETSID */ - if (!log_stdout) { - /* Close fd's 0,1,2. Needed if started by rsh */ - close_low_fds(false); /* Don't close stderr, let the debug system - attach it to the logfile */ - } + /* Close fd's 0,1,2 as appropriate. Needed if started by rsh. */ + /* stdin must be open if we do not fork, for monitoring for + * close. stdout must be open if we are logging there, and we + * never close stderr (but debug might dup it onto a log file) */ + close_low_fds(do_fork, !log_stdout, false); } diff --git a/lib/util/debug.c b/lib/util/debug.c index a6388513c7..a7e2a0f78e 100644 --- a/lib/util/debug.c +++ b/lib/util/debug.c @@ -592,9 +592,14 @@ bool reopen_logs_internal(void) (void)umask(oldumask); /* Take over stderr to catch output into logs */ - if (state.fd > 0 && dup2(state.fd, 2) == -1) { - close_low_fds(true); /* Close stderr too, if dup2 can't point it - at the logfile */ + if (state.fd > 0) { + if (dup2(state.fd, 2) == -1) { + /* Close stderr too, if dup2 can't point it - + at the logfile. There really isn't much + that can be done on such a fundemental + failure... */ + close_low_fds(false, false, true); + } } state.reopening_logs = false; diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h index a0989d5479..13fe831995 100644 --- a/lib/util/samba_util.h +++ b/lib/util/samba_util.h @@ -824,7 +824,7 @@ _PUBLIC_ int idr_remove(struct idr_context *idp, int id); /** Close the low 3 fd's and open dev/null in their place **/ -_PUBLIC_ void close_low_fds(bool stderr_too); +_PUBLIC_ void close_low_fds(bool stdin_too, bool stdout_too, bool stderr_too); /** Become a daemon, discarding the controlling terminal. diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c index 9a5d1b0fef..5775505160 100644 --- a/source3/printing/spoolssd.c +++ b/source3/printing/spoolssd.c @@ -660,9 +660,6 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx, return pid; } - /* child */ - close_low_fds(false); - status = reinit_after_fork(msg_ctx, ev_ctx, true); diff --git a/source3/rpc_server/epmd.c b/source3/rpc_server/epmd.c index 0d5e6ec6af..c28d8574c0 100644 --- a/source3/rpc_server/epmd.c +++ b/source3/rpc_server/epmd.c @@ -159,9 +159,6 @@ void start_epmd(struct tevent_context *ev_ctx, return; } - /* child */ - close_low_fds(false); - status = reinit_after_fork(msg_ctx, ev_ctx, true); diff --git a/source3/rpc_server/lsasd.c b/source3/rpc_server/lsasd.c index 575b863976..416a3b3c13 100644 --- a/source3/rpc_server/lsasd.c +++ b/source3/rpc_server/lsasd.c @@ -875,9 +875,6 @@ void start_lsasd(struct tevent_context *ev_ctx, return; } - /* child */ - close_low_fds(false); - /* save the parent process id so the children can use it later */ parent_id = procid_self(); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 0fb7d16ef6..cab23bc6d5 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -504,12 +504,6 @@ static void smbd_accept_connection(struct tevent_context *ev, * them, counting worker smbds. */ CatchChild(); - /* close our standard file - descriptors */ - if (!debug_get_output_is_stdout()) { - close_low_fds(False); /* Don't close stderr */ - } - status = reinit_after_fork(msg_ctx, ev, true); @@ -1397,10 +1391,8 @@ extern void build_options(bool screen); goes away */ smbd_server_conn->sock = dup(0); - /* close our standard file descriptors */ - if (!debug_get_output_is_stdout()) { - close_low_fds(False); /* Don't close stderr */ - } + /* close stdin, stdout (if not logging to it), but not stderr */ + close_low_fds(true, !debug_get_output_is_stdout(), false); #ifdef HAVE_ATEXIT atexit(killkids); -- cgit