X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fpipecmd%2Fpipecmd.c;h=c2b514df5e97189230dbc282f3b673293a77028c;hp=32772a83bc7b69c96cff57747aa779771f2e7604;hb=d3d2242ba8d975f8d7ddaa0348953dfd6f45ffce;hpb=440efa555b08324386fa15488cefaed68a791d6e diff --git a/ccan/pipecmd/pipecmd.c b/ccan/pipecmd/pipecmd.c index 32772a83..c2b514df 100644 --- a/ccan/pipecmd/pipecmd.c +++ b/ccan/pipecmd/pipecmd.c @@ -6,6 +6,8 @@ #include #include +int pipecmd_preserve; + static char **gather_args(const char *arg0, va_list ap) { size_t n = 1; @@ -26,7 +28,7 @@ static char **gather_args(const char *arg0, va_list ap) return arr; } -pid_t pipecmdv(int *fd_fromchild, int *fd_tochild, int *fd_errfromchild, +pid_t pipecmdv(int *fd_tochild, int *fd_fromchild, int *fd_errfromchild, const char *cmd, va_list ap) { char **arr = gather_args(cmd, ap); @@ -36,12 +38,12 @@ pid_t pipecmdv(int *fd_fromchild, int *fd_tochild, int *fd_errfromchild, errno = ENOMEM; return -1; } - ret = pipecmdarr(fd_fromchild, fd_tochild, fd_errfromchild, arr); + ret = pipecmdarr(fd_tochild, fd_fromchild, fd_errfromchild, arr); free_noerr(arr); return ret; } -pid_t pipecmdarr(int *fd_fromchild, int *fd_tochild, int *fd_errfromchild, +pid_t pipecmdarr(int *fd_tochild, int *fd_fromchild, int *fd_errfromchild, char *const *arr) { int tochild[2], fromchild[2], errfromchild[2], execfail[2]; @@ -49,7 +51,10 @@ pid_t pipecmdarr(int *fd_fromchild, int *fd_tochild, int *fd_errfromchild, int err; if (fd_tochild) { - if (pipe(tochild) != 0) + if (fd_tochild == &pipecmd_preserve) { + tochild[0] = STDIN_FILENO; + fd_tochild = NULL; + } else if (pipe(tochild) != 0) goto fail; } else { tochild[0] = open("/dev/null", O_RDONLY); @@ -57,7 +62,10 @@ pid_t pipecmdarr(int *fd_fromchild, int *fd_tochild, int *fd_errfromchild, goto fail; } if (fd_fromchild) { - if (pipe(fromchild) != 0) + if (fd_fromchild == &pipecmd_preserve) { + fromchild[1] = STDOUT_FILENO; + fd_fromchild = NULL; + } else if (pipe(fromchild) != 0) goto close_tochild_fail; } else { fromchild[1] = open("/dev/null", O_WRONLY); @@ -65,7 +73,10 @@ pid_t pipecmdarr(int *fd_fromchild, int *fd_tochild, int *fd_errfromchild, goto close_tochild_fail; } if (fd_errfromchild) { - if (fd_errfromchild == fd_fromchild) { + if (fd_errfromchild == &pipecmd_preserve) { + errfromchild[1] = STDERR_FILENO; + fd_errfromchild = NULL; + } else if (fd_errfromchild == fd_fromchild) { errfromchild[0] = fromchild[0]; errfromchild[1] = fromchild[1]; } else { @@ -77,7 +88,7 @@ pid_t pipecmdarr(int *fd_fromchild, int *fd_tochild, int *fd_errfromchild, if (errfromchild[1] < 0) goto close_fromchild_fail; } - + if (pipe(execfail) != 0) goto close_errfromchild_fail; @@ -168,14 +179,14 @@ fail: return -1; } -pid_t pipecmd(int *fd_fromchild, int *fd_tochild, int *fd_errfromchild, +pid_t pipecmd(int *fd_tochild, int *fd_fromchild, int *fd_errfromchild, const char *cmd, ...) { pid_t childpid; va_list ap; va_start(ap, cmd); - childpid = pipecmdv(fd_fromchild, fd_tochild, fd_errfromchild, cmd, ap); + childpid = pipecmdv(fd_tochild, fd_fromchild, fd_errfromchild, cmd, ap); va_end(ap); return childpid;