The branch, master has been updated
       via  4ecac60 runcmd: use set_close_on_exec()
       via  81c5647 runcmd: use a pipe for stdin to child processes
      from  711c18c Change the signature of pthreadpool_finished_job() to 
return 0 on success, errno on fail and return the jobid in a separate variable.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 4ecac6067f6637b160f3beff775c43118e6b684a
Author: Andrew Tridgell <[email protected]>
Date:   Wed Nov 30 15:18:29 2011 +1100

    runcmd: use set_close_on_exec()
    
    this prevents a fd leak to child processes
    
    Autobuild-User: Andrew Bartlett <[email protected]>
    Autobuild-Date: Thu Dec 22 14:00:06 CET 2011 on sn-devel-104

commit 81c564798c84a39c92c2c33d57151a9064940152
Author: Andrew Tridgell <[email protected]>
Date:   Wed Nov 30 14:07:51 2011 +1100

    runcmd: use a pipe for stdin to child processes
    
    this allows child processes to detect the exit of the parent by
    looking for EOF on stdin

-----------------------------------------------------------------------

Summary of changes:
 lib/util/util_runcmd.c |   61 ++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 54 insertions(+), 7 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/util_runcmd.c b/lib/util/util_runcmd.c
index cfe0034..cc274c2 100644
--- a/lib/util/util_runcmd.c
+++ b/lib/util/util_runcmd.c
@@ -33,9 +33,10 @@
 struct samba_runcmd_state {
        int stdout_log_level;
        int stderr_log_level;
+       struct tevent_fd *fde_stdin;
        struct tevent_fd *fde_stdout;
        struct tevent_fd *fde_stderr;
-       int fd_stdout, fd_stderr;
+       int fd_stdin, fd_stdout, fd_stderr;
        char *arg0;
        pid_t pid;
        char buf[1024];
@@ -72,7 +73,7 @@ struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
 {
        struct tevent_req *req;
        struct samba_runcmd_state *state;
-       int p1[2], p2[2];
+       int p1[2], p2[2], p3[2];
        char **argv;
        va_list ap;
 
@@ -100,6 +101,14 @@ struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
                tevent_req_error(req, errno);
                return tevent_req_post(req, ev);
        }
+       if (pipe(p3) != 0) {
+               close(p1[0]);
+               close(p1[1]);
+               close(p2[0]);
+               close(p2[1]);
+               tevent_req_error(req, errno);
+               return tevent_req_post(req, ev);
+       }
 
        state->pid = fork();
        if (state->pid == (pid_t)-1) {
@@ -107,6 +116,8 @@ struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
                close(p1[1]);
                close(p2[0]);
                close(p2[1]);
+               close(p3[0]);
+               close(p3[1]);
                tevent_req_error(req, errno);
                return tevent_req_post(req, ev);
        }
@@ -115,10 +126,18 @@ struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
                /* the parent */
                close(p1[1]);
                close(p2[1]);
+               close(p3[0]);
                state->fd_stdout = p1[0];
                state->fd_stderr = p2[0];
+               state->fd_stdin  = p3[1];
+
                set_blocking(state->fd_stdout, false);
                set_blocking(state->fd_stderr, false);
+               set_blocking(state->fd_stdin,  false);
+
+               smb_set_close_on_exec(state->fd_stdin);
+               smb_set_close_on_exec(state->fd_stdout);
+               smb_set_close_on_exec(state->fd_stderr);
 
                talloc_set_destructor(state, samba_runcmd_state_destructor);
 
@@ -128,8 +147,9 @@ struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
                                                  samba_runcmd_io_handler,
                                                  req);
                if (tevent_req_nomem(state->fde_stdout, req)) {
-                       close(p1[0]);
-                       close(p2[0]);
+                       close(state->fd_stdout);
+                       close(state->fd_stderr);
+                       close(state->fd_stdin);
                        return tevent_req_post(req, ev);
                }
                tevent_fd_set_auto_close(state->fde_stdout);
@@ -140,11 +160,23 @@ struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
                                                  samba_runcmd_io_handler,
                                                  req);
                if (tevent_req_nomem(state->fde_stdout, req)) {
-                       close(p2[0]);
+                       close(state->fd_stderr);
+                       close(state->fd_stdin);
                        return tevent_req_post(req, ev);
                }
                tevent_fd_set_auto_close(state->fde_stderr);
 
+               state->fde_stdin = tevent_add_fd(ev, state,
+                                                state->fd_stdin,
+                                                0,
+                                                samba_runcmd_io_handler,
+                                                req);
+               if (tevent_req_nomem(state->fde_stdin, req)) {
+                       close(state->fd_stdin);
+                       return tevent_req_post(req, ev);
+               }
+               tevent_fd_set_auto_close(state->fde_stdin);
+
                if (!timeval_is_zero(&endtime)) {
                        tevent_req_set_endtime(req, ev, endtime);
                }
@@ -155,6 +187,7 @@ struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
        /* the child */
        close(p1[0]);
        close(p2[0]);
+       close(p3[1]);
        close(0);
        close(1);
        close(2);
@@ -164,10 +197,14 @@ struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
        tevent_re_initialise(ev);
 
        /* setup for logging to go to the parents debug log */
-       open("/dev/null", O_RDONLY); /* for stdin */
+       dup2(p3[0], 0);
        dup2(p1[1], 1);
        dup2(p2[1], 2);
 
+       close(p1[1]);
+       close(p2[1]);
+       close(p3[0]);
+
        argv = str_list_copy(state, discard_const_p(const char *, argv0));
        if (!argv) {
                fprintf(stderr, "Out of memory in child\n");
@@ -211,9 +248,19 @@ static void samba_runcmd_io_handler(struct tevent_context 
*ev,
        if (fde == state->fde_stdout) {
                level = state->stdout_log_level;
                fd = state->fd_stdout;
-       } else {
+       } else if (fde == state->fde_stderr) {
                level = state->stderr_log_level;
                fd = state->fd_stderr;
+       } else if (fde == state->fde_stdin) {
+               char c;
+               if (read(state->fd_stdin, &c, 1) != 1) {
+                       /* the child has closed its stdin */
+                       talloc_free(fde);
+                       state->fde_stdin = NULL;
+                       return;
+               }
+       } else {
+               return;
        }
 
        if (!(flags & TEVENT_FD_READ)) {


-- 
Samba Shared Repository

Reply via email to