Mercurial > dropbear
diff dbutil.c @ 484:effb4a25b1ae
Don't capture stderr from spawned processes in proxycommand mode
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 17 Sep 2008 14:35:36 +0000 |
parents | 7ad49f34a122 |
children | d59f628e7baa |
line wrap: on
line diff
--- a/dbutil.c Mon Sep 15 14:40:30 2008 +0000 +++ b/dbutil.c Wed Sep 17 14:35:36 2008 +0000 @@ -146,7 +146,7 @@ } va_start(param, format); - fprintf(stderr, "TRACE: "); + fprintf(stderr, "TRACE (%d): ", getpid()); vfprintf(stderr, format, param); fprintf(stderr, "\n"); va_end(param); @@ -391,7 +391,9 @@ /* Sets up a pipe for a, returning three non-blocking file descriptors * and the pid. exec_fn is the function that will actually execute the child process, - * it will be run after the child has fork()ed, and is passed exec_data. */ + * it will be run after the child has fork()ed, and is passed exec_data. + * If ret_errfd == NULL then stderr will not be captured. + * ret_pid can be passed as NULL to discard the pid. */ int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid) { int infds[2]; @@ -403,12 +405,15 @@ const int FDOUT = 1; /* redirect stdin/stdout/stderr */ - if (pipe(infds) != 0) + if (pipe(infds) != 0) { + return DROPBEAR_FAILURE; + } + if (pipe(outfds) != 0) { return DROPBEAR_FAILURE; - if (pipe(outfds) != 0) + } + if (ret_errfd && pipe(errfds) != 0) { return DROPBEAR_FAILURE; - if (pipe(errfds) != 0) - return DROPBEAR_FAILURE; + } #ifdef __uClinux__ pid = vfork(); @@ -416,8 +421,9 @@ pid = fork(); #endif - if (pid < 0) + if (pid < 0) { return DROPBEAR_FAILURE; + } if (!pid) { /* child */ @@ -432,7 +438,7 @@ if ((dup2(infds[FDIN], STDIN_FILENO) < 0) || (dup2(outfds[FDOUT], STDOUT_FILENO) < 0) || - (dup2(errfds[FDOUT], STDERR_FILENO) < 0)) { + (ret_errfd && dup2(errfds[FDOUT], STDERR_FILENO) < 0)) { TRACE(("leave noptycommand: error redirecting FDs")) dropbear_exit("child dup2() failure"); } @@ -441,8 +447,11 @@ close(infds[FDIN]); close(outfds[FDIN]); close(outfds[FDOUT]); - close(errfds[FDIN]); - close(errfds[FDOUT]); + if (ret_errfd) + { + close(errfds[FDIN]); + close(errfds[FDOUT]); + } exec_fn(exec_data); /* not reached */ @@ -451,16 +460,24 @@ /* parent */ close(infds[FDIN]); close(outfds[FDOUT]); - close(errfds[FDOUT]); - setnonblocking(errfds[FDIN]); setnonblocking(outfds[FDIN]); setnonblocking(infds[FDOUT]); - *ret_pid = pid; + if (ret_errfd) { + close(errfds[FDOUT]); + setnonblocking(errfds[FDIN]); + } + + if (ret_pid) { + *ret_pid = pid; + } + *ret_writefd = infds[FDOUT]; *ret_readfd = outfds[FDIN]; - *ret_errfd = errfds[FDIN]; + if (ret_errfd) { + *ret_errfd = errfds[FDIN]; + } return DROPBEAR_SUCCESS; } }