64435c8709f85a481ae55ab6ef76639fc7becba8
markd
  Thu Apr 6 12:09:05 2023 -0700
don't close stdin/stdout of pipeline if they were not opened by by the pipeline

diff --git src/lib/pipeline.c src/lib/pipeline.c
index 5060dd7..c313e77 100644
--- src/lib/pipeline.c
+++ src/lib/pipeline.c
@@ -36,32 +36,32 @@
 };
 
 struct pipeline
 /* Object for a process pipeline and associated open file.  Pipeline process
  * consist of a process group leader and then all of the child process.  The
  * group leader does no work, just wait on processes to complete and report
  * errors to the top level process.  This object is create in the calling
  * process, and then passed down, but not shared, via forks.
  */
 {
     struct plProc *procs;      /* list of processes */
     int numRunning;            /* number of processes running */
     pid_t groupLeader;         /* process group id, or -1 if not set. This is pid of group leader */
     unsigned int timeout;      /* timeout, in seconds, or zero */
     char *procName;            /* name to use in error messages. */
-    int pipeFd;                /* fd of pipe to/from process, -1 if none */
     unsigned options;          /* options */
+    int pipeFd;                /* fd of pipe to/from process, -1 if none */
     FILE* pipeFh;              /* optional stdio around pipe */
     char* stdioBuf;            /* optional stdio buffer */
     struct lineFile *pipeLf;   /* optional lineFile around pipe */
 };
 
 /* file buffer size */
 #define FILE_BUF_SIZE 64*1024
 
 static int pipeCreate(int *writeFd)
 /* create a pipe or die, return readFd */
 {
 int pipeFds[2];
 if (pipe(pipeFds) < 0)
     errnoAbort("can't create pipe");
 *writeFd = pipeFds[1];
@@ -565,30 +565,31 @@
                               char *otherEndFile, char *stderrFile,
                               unsigned int timeout)
 /* Create a pipeline from an array of commands.  See pipeline.h for
  * full documentation */
 {
 int otherEndFd;
 int stderrFd = (stderrFile == NULL) ? STDERR_FILENO : openWrite(stderrFile, FALSE);
 
 checkOpts(opts);
 boolean append = ((opts & pipelineAppend) != 0);
 if (opts & pipelineRead)
     otherEndFd = (otherEndFile == NULL) ? STDIN_FILENO : openRead(otherEndFile);
 else
     otherEndFd = (otherEndFile == NULL) ? STDOUT_FILENO : openWrite(otherEndFile, append);
 struct pipeline *pl = pipelineOpenFd(cmds, opts, otherEndFd, stderrFd, timeout);
+if (otherEndFile != NULL)
     safeClose(&otherEndFd);
 if (stderrFile != NULL)
     safeClose(&stderrFd);
 return pl;
 }
 
 struct pipeline *pipelineOpenMem(char ***cmds, unsigned opts,
                                  void *otherEndBuf, size_t otherEndBufSize,
                                  int stderrFd, unsigned int timeout)
 /* Create a pipeline from an array of commands, with the pipeline input/output
  * in a memory buffer.  See pipeline.h for full documentation.  Currently only
  * input to a read pipeline is supported  */
 {
 struct pipeline *pl;
 checkOpts(opts);