change low FDs are handled in Samba
authorAndrew Bartlett <abartlet@samba.org>
Fri, 2 Mar 2012 08:32:56 +0000 (19:32 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 4 Mar 2012 09:14:34 +0000 (10:14 +0100)
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
lib/util/debug.c
lib/util/samba_util.h
source3/printing/spoolssd.c
source3/rpc_server/epmd.c
source3/rpc_server/lsasd.c
source3/smbd/server.c

index 2af1631..4c1d29e 100644 (file)
  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);
 }
index a638851..a7e2a0f 100644 (file)
@@ -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;
index a0989d5..13fe831 100644 (file)
@@ -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.
index 9a5d1b0..5775505 100644 (file)
@@ -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);
index 0d5e6ec..c28d857 100644 (file)
@@ -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);
index 575b863..416a3b3 100644 (file)
@@ -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();
 
index 0fb7d16..cab23bc 100644 (file)
@@ -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);