#include "pipeline.h"#include "common.h"#include "sqlNum.h"#include "dystring.h"#include "errabort.h"#include "portable.h"#include "linefile.h"#include <sys/types.h>#include <unistd.h>#include <sys/wait.h>#include <signal.h>Include dependency graph for pipeline.c:

Go to the source code of this file.
Data Structures | |
| struct | plProc |
| struct | pipeline |
Defines | |
| #define | FILE_BUF_SIZE 64*1024 |
Functions | |
| static int | pipeCreate (int *writeFd) |
| static void | safeClose (int *fdPtr) |
| static char * | joinCmd (char **cmd) |
| static char * | joinCmds (char ***cmds) |
| static struct plProc * | plProcNew (char **cmd, struct pipeline *pl) |
| static void | plProcFree (struct plProc *proc) |
| static void | childAbortHandler () |
| static void | plProcSetup (struct plProc *proc, int stdinFd, int stdoutFd, int stderrFd) |
| static void | plProcExecChild (struct plProc *proc, int stdinFd, int stdoutFd, int stderrFd) |
| static void | plProcMemWrite (struct plProc *proc, int stdoutFd, int stderrFd, void *otherEndBuf, size_t otherEndBufSize) |
| static void | plProcWait (struct plProc *proc) |
| static struct pipeline * | pipelineNew (char ***cmds, unsigned options) |
| void | pipelineFree (struct pipeline **plPtr) |
| static int | pipelineExecProc (struct pipeline *pl, struct plProc *proc, int prevStdoutFd, int stdinFd, int stdoutFd, int stderrFd, void *otherEndBuf, size_t otherEndBufSize) |
| static void | pipelineExec (struct pipeline *pl, int stdinFd, int stdoutFd, int stderrFd, void *otherEndBuf, size_t otherEndBufSize) |
| static int | openRead (char *fname) |
| static int | openWrite (char *fname) |
| static void | pipelineStartRead (struct pipeline *pl, int stdinFd, int stderrFd, void *otherEndBuf, size_t otherEndBufSize) |
| static void | pipelineStartWrite (struct pipeline *pl, int stdoutFd, int stderrFd) |
| static void | checkOpts (unsigned opts) |
| pipeline * | pipelineOpenFd (char ***cmds, unsigned opts, int otherEndFd, int stderrFd) |
| pipeline * | pipelineOpen (char ***cmds, unsigned opts, char *otherEndFile, char *stderrFile) |
| pipeline * | pipelineOpenMem (char ***cmds, unsigned opts, void *otherEndBuf, size_t otherEndBufSize, int stderrFd) |
| pipeline * | pipelineOpenFd1 (char **cmd, unsigned opts, int otherEndFd, int stderrFd) |
| pipeline * | pipelineOpen1 (char **cmd, unsigned opts, char *otherEndFile, char *stderrFile) |
| pipeline * | pipelineOpenMem1 (char **cmd, unsigned opts, void *otherEndBuf, size_t otherEndBufSize, int stderrFd) |
| char * | pipelineDesc (struct pipeline *pl) |
| int | pipelineFd (struct pipeline *pl) |
| FILE * | pipelineFile (struct pipeline *pl) |
| lineFile * | pipelineLineFile (struct pipeline *pl) |
| static void | closePipelineFile (struct pipeline *pl) |
| static void | closePipeline (struct pipeline *pl) |
| int | pipelineWait (struct pipeline *pl) |
| void | pipelineDumpCmds (char ***cmds) |
| #define FILE_BUF_SIZE 64*1024 |
| static void checkOpts | ( | unsigned | opts | ) | [static] |
Definition at line 351 of file pipeline.c.
References errAbort(), pipelineRead, and pipelineWrite.
Referenced by pipelineOpen(), pipelineOpenFd(), and pipelineOpenMem().
00353 { 00354 if (((opts & (pipelineRead|pipelineWrite)) == 0) 00355 || ((opts & (pipelineRead|pipelineWrite)) == (pipelineRead|pipelineWrite))) 00356 errAbort("must specify one of pipelineRead or pipelineWrite to pipelineOpen"); 00357 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void childAbortHandler | ( | ) | [static] |
Definition at line 126 of file pipeline.c.
Referenced by plProcSetup().
Here is the caller graph for this function:

| static void closePipeline | ( | struct pipeline * | pl | ) | [static] |
Definition at line 510 of file pipeline.c.
References closePipelineFile(), errAbort(), lineFileClose(), pipeline::pipeFh, and lineFile::pl.
Referenced by pipelineWait().
00512 { 00513 if (pl->pipeFh != NULL) 00514 closePipelineFile(pl); 00515 else if (pl->pipeLf != NULL) 00516 lineFileClose(&pl->pipeLf); 00517 else 00518 { 00519 if (close(pl->pipeFd) < 0) 00520 errAbort("close failed on pipeline: %s ", pl->procName); 00521 } 00522 pl->pipeFd = -1; 00523 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void closePipelineFile | ( | struct pipeline * | pl | ) | [static] |
Definition at line 493 of file pipeline.c.
References errAbort(), pipeline::options, pipeline::pipeFh, pipelineWrite, lineFile::pl, and pipeline::procName.
Referenced by closePipeline().
00495 { 00496 if (pl->options & pipelineWrite) 00497 { 00498 fflush(pl->pipeFh); 00499 if (ferror(pl->pipeFh)) 00500 errAbort("write failed to pipeline: %s ", pl->procName); 00501 } 00502 else if (ferror(pl->pipeFh)) 00503 errAbort("read failed from pipeline: %s ", pl->procName); 00504 00505 if (fclose(pl->pipeFh) == EOF) 00506 errAbort("close failed on pipeline: %s ", pl->procName); 00507 pl->pipeFh = NULL; 00508 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static char* joinCmd | ( | char ** | cmd | ) | [static] |
Definition at line 65 of file pipeline.c.
References dyStringAppend(), dyStringCannibalize(), and dyStringNew.
Referenced by plProcWait().
00067 { 00068 struct dyString *str = dyStringNew(512); 00069 int i; 00070 for (i = 0; cmd[i] != NULL; i++) 00071 { 00072 if (i > 0) 00073 dyStringAppend(str, " "); 00074 dyStringAppend(str, cmd[i]); 00075 } 00076 return dyStringCannibalize(&str); 00077 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static char* joinCmds | ( | char *** | cmds | ) | [static] |
Definition at line 79 of file pipeline.c.
References dyStringAppend(), dyStringCannibalize(), and dyStringNew.
Referenced by pipelineNew().
00081 { 00082 struct dyString *str = dyStringNew(512); 00083 int i, j; 00084 for (i = 0; cmds[i] != NULL; i++) 00085 { 00086 if (i > 0) 00087 dyStringAppend(str, " | "); 00088 for (j = 0; cmds[i][j] != NULL; j++) 00089 { 00090 if (j > 0) 00091 dyStringAppend(str, " "); 00092 dyStringAppend(str, cmds[i][j]); 00093 } 00094 } 00095 return dyStringCannibalize(&str); 00096 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int openRead | ( | char * | fname | ) | [static] |
Definition at line 315 of file pipeline.c.
References errnoAbort().
Referenced by pipelineOpen().
00317 { 00318 int fd = open(fname, O_RDONLY); 00319 if (fd < 0) 00320 errnoAbort("can't open for read access: %s", fname); 00321 return fd; 00322 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int openWrite | ( | char * | fname | ) | [static] |
Definition at line 324 of file pipeline.c.
References errnoAbort().
Referenced by pipelineOpen().
00326 { 00327 int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); 00328 if (fd < 0) 00329 errnoAbort("can't open for write access: %s", fname); 00330 return fd; 00331 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int pipeCreate | ( | int * | writeFd | ) | [static] |
Definition at line 43 of file pipeline.c.
References errnoAbort().
Referenced by pipelineExecProc(), pipelineStartRead(), and pipelineStartWrite().
00045 { 00046 int pipeFds[2]; 00047 if (pipe(pipeFds) < 0) 00048 errnoAbort("can't create pipe"); 00049 *writeFd = pipeFds[1]; 00050 return pipeFds[0]; 00051 }
Here is the call graph for this function:

Here is the caller graph for this function:

| char* pipelineDesc | ( | struct pipeline * | pl | ) |
Definition at line 444 of file pipeline.c.
References pipeline::procName.
Referenced by pipelineLineFile().
00446 { 00447 return pl->procName; 00448 }
Here is the caller graph for this function:

| void pipelineDumpCmds | ( | char *** | cmds | ) |
Definition at line 552 of file pipeline.c.
References plProc::cmd, FALSE, and TRUE.
00554 { 00555 char **cmd; 00556 boolean first = TRUE; 00557 while ((cmd = *cmds++) != NULL) 00558 { 00559 char *word; 00560 if (first) 00561 first = FALSE; 00562 else 00563 printf("| "); 00564 while ((word = *cmd++) != NULL) 00565 printf("%s ", word); 00566 } 00567 printf("<BR>\n"); 00568 }
| static void pipelineExec | ( | struct pipeline * | pl, | |
| int | stdinFd, | |||
| int | stdoutFd, | |||
| int | stderrFd, | |||
| void * | otherEndBuf, | |||
| size_t | otherEndBufSize | |||
| ) | [static] |
Definition at line 298 of file pipeline.c.
References plProc::next, pipelineExecProc(), plProc::pl, and pipeline::procs.
Referenced by pipelineStartRead(), and pipelineStartWrite().
00302 { 00303 struct plProc *proc; 00304 int prevStdoutFd = -1; 00305 for (proc = pl->procs; proc != NULL; proc = proc->next) 00306 { 00307 prevStdoutFd = pipelineExecProc(pl, proc, prevStdoutFd, 00308 stdinFd, stdoutFd, stderrFd, 00309 otherEndBuf, otherEndBufSize); 00310 otherEndBuf = NULL; /* only for first process (read pipes) */ 00311 otherEndBufSize = 0; 00312 } 00313 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int pipelineExecProc | ( | struct pipeline * | pl, | |
| struct plProc * | proc, | |||
| int | prevStdoutFd, | |||
| int | stdinFd, | |||
| int | stdoutFd, | |||
| int | stderrFd, | |||
| void * | otherEndBuf, | |||
| size_t | otherEndBufSize | |||
| ) | [static] |
Definition at line 263 of file pipeline.c.
References errnoAbort(), plProc::next, plProc::pid, pipeCreate(), plProc::pl, plProcExecChild(), plProcMemWrite(), pipeline::procs, and safeClose().
Referenced by pipelineExec().
00267 { 00268 /* determine stdin/stdout to use */ 00269 int procStdinFd, procStdoutFd; 00270 if (proc == pl->procs) 00271 procStdinFd = stdinFd; /* first process in pipeline */ 00272 else 00273 procStdinFd = prevStdoutFd; 00274 if (proc->next == NULL) 00275 procStdoutFd = stdoutFd; /* last process in pipeline */ 00276 else 00277 prevStdoutFd = pipeCreate(&procStdoutFd); 00278 00279 /* start process */ 00280 if ((proc->pid = fork()) < 0) 00281 errnoAbort("can't fork"); 00282 if (proc->pid == 0) 00283 { 00284 if (otherEndBuf != NULL) 00285 plProcMemWrite(proc, procStdoutFd, stderrFd, otherEndBuf, otherEndBufSize); 00286 else 00287 plProcExecChild(proc, procStdinFd, procStdoutFd, stderrFd); 00288 } 00289 00290 /* don't leave intermediate pipes open in parent */ 00291 if (proc != pl->procs) 00292 safeClose(&procStdinFd); 00293 if (proc->next != NULL) 00294 safeClose(&procStdoutFd); 00295 return prevStdoutFd; 00296 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int pipelineFd | ( | struct pipeline * | pl | ) |
Definition at line 450 of file pipeline.c.
References pipeline::pipeFd.
Referenced by lineFileDecompress(), lineFileDecompressFd(), lineFileDecompressMem(), and textOutInit().
Here is the caller graph for this function:

| FILE* pipelineFile | ( | struct pipeline * | pl | ) |
Definition at line 456 of file pipeline.c.
References errAbort(), errnoAbort(), FILE_BUF_SIZE, needLargeMem(), pipeline::options, pipeline::pipeFd, pipeline::pipeFh, pipeline::pipeLf, pipelineRead, pipeline::procName, and pipeline::stdioBuf.
00460 { 00461 if (pl->pipeFh == NULL) 00462 { 00463 /* create FILE* on first access */ 00464 char *mode = (pl->options & pipelineRead) ? "r" : "w"; 00465 if (pl->pipeLf != NULL) 00466 errAbort("can't call pipelineFile after having associated a lineFile with a pipeline"); 00467 pl->pipeFh = fdopen(pl->pipeFd, mode); 00468 if (pl->pipeFh == NULL) 00469 errnoAbort("fdopen failed for: %s", pl->procName); 00470 pl->stdioBuf = needLargeMem(FILE_BUF_SIZE); 00471 setvbuf(pl->pipeFh, pl->stdioBuf, _IOFBF, FILE_BUF_SIZE); 00472 } 00473 return pl->pipeFh; 00474 }
Here is the call graph for this function:

| void pipelineFree | ( | struct pipeline ** | plPtr | ) |
Definition at line 244 of file pipeline.c.
References freez(), plProc::next, plProc::pl, plProcFree(), pipeline::procName, pipeline::procs, and pipeline::stdioBuf.
Referenced by lineFileClose(), and textOutClose().
00246 { 00247 struct pipeline *pl = *plPtr; 00248 if (pl != NULL) 00249 { 00250 struct plProc *proc = pl->procs; 00251 while (proc != NULL) 00252 { 00253 struct plProc *delProc = proc; 00254 proc = proc->next; 00255 plProcFree(delProc); 00256 } 00257 freez(&pl->procName); 00258 freez(&pl->stdioBuf); 00259 freez(plPtr); 00260 } 00261 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 476 of file pipeline.c.
References errAbort(), lineFileAttach(), pipeline::options, pipeline::pipeFd, pipeline::pipeFh, pipeline::pipeLf, pipelineDesc(), pipelineWrite, lineFile::pl, and TRUE.
00480 { 00481 if (pl->pipeLf == NULL) 00482 { 00483 /* create line on first acess */ 00484 if (pl->pipeFh != NULL) 00485 errAbort("can't call pipelineLineFile after having associated a FILE with a pipeline"); 00486 if (pl->options & pipelineWrite) 00487 errAbort("can't associated a lineFile with a write pipeline"); 00488 pl->pipeLf = lineFileAttach(pipelineDesc(pl), TRUE, pl->pipeFd); 00489 } 00490 return pl->pipeLf; 00491 }
Here is the call graph for this function:

| static struct pipeline* pipelineNew | ( | char *** | cmds, | |
| unsigned | options | |||
| ) | [static, read] |
Definition at line 217 of file pipeline.c.
References AllocVar, errAbort(), joinCmds(), pipeline::options, pipeline::pipeFd, pipelineMemInput, plProcNew(), pipeline::procName, pipeline::procs, and slAddTail().
Referenced by pipelineOpenFd(), and pipelineOpenMem().
00219 { 00220 static char *memPseudoCmd[] = {"[mem]", NULL}; 00221 struct pipeline *pl; 00222 int iCmd; 00223 00224 AllocVar(pl); 00225 pl->pipeFd = -1; 00226 pl->options = options; 00227 pl->procName = joinCmds(cmds); 00228 00229 if (cmds[0] == NULL) 00230 errAbort("no commands in pipeline"); 00231 00232 if (options & pipelineMemInput) 00233 { 00234 /* add proc for forked process to write memory to pipeline */ 00235 slAddTail(&pl->procs, plProcNew(memPseudoCmd, pl)); 00236 } 00237 00238 for(iCmd = 0; cmds[iCmd] != NULL; iCmd++) 00239 slAddTail(&pl->procs, plProcNew(cmds[iCmd], pl)); 00240 00241 return pl; 00242 }
Here is the call graph for this function:

Here is the caller graph for this function:

| struct pipeline* pipelineOpen | ( | char *** | cmds, | |
| unsigned | opts, | |||
| char * | otherEndFile, | |||
| char * | stderrFile | |||
| ) | [read] |
Definition at line 375 of file pipeline.c.
References checkOpts(), openRead(), openWrite(), pipelineOpenFd(), pipelineRead, and safeClose().
Referenced by pipelineOpen1().
00379 { 00380 int otherEndFd; 00381 int stderrFd = (stderrFile == NULL) ? STDERR_FILENO : openWrite(stderrFile); 00382 00383 checkOpts(opts); 00384 if (opts & pipelineRead) 00385 otherEndFd = (otherEndFile == NULL) ? STDIN_FILENO : openRead(otherEndFile); 00386 else 00387 otherEndFd = (otherEndFile == NULL) ? STDOUT_FILENO : openWrite(otherEndFile); 00388 struct pipeline *pl = pipelineOpenFd(cmds, opts, otherEndFd, stderrFd); 00389 safeClose(&otherEndFd); 00390 if (stderrFile != NULL) 00391 safeClose(&stderrFd); 00392 return pl; 00393 }
Here is the call graph for this function:

Here is the caller graph for this function:

| struct pipeline* pipelineOpen1 | ( | char ** | cmd, | |
| unsigned | opts, | |||
| char * | otherEndFile, | |||
| char * | stderrFile | |||
| ) | [read] |
Definition at line 423 of file pipeline.c.
References pipelineOpen().
Referenced by lineFileDecompress(), and textOutInit().
00426 { 00427 char **cmds[2]; 00428 cmds[0] = cmd; 00429 cmds[1] = NULL; 00430 return pipelineOpen(cmds, opts, otherEndFile, stderrFile); 00431 }
Here is the call graph for this function:

Here is the caller graph for this function:

| struct pipeline* pipelineOpenFd | ( | char *** | cmds, | |
| unsigned | opts, | |||
| int | otherEndFd, | |||
| int | stderrFd | |||
| ) | [read] |
Definition at line 359 of file pipeline.c.
References checkOpts(), pipelineNew(), pipelineRead, pipelineStartRead(), and pipelineStartWrite().
Referenced by pipelineOpen(), and pipelineOpenFd1().
00363 { 00364 struct pipeline *pl; 00365 00366 checkOpts(opts); 00367 pl = pipelineNew(cmds, opts); 00368 if (opts & pipelineRead) 00369 pipelineStartRead(pl, otherEndFd, stderrFd, NULL, 0); 00370 else 00371 pipelineStartWrite(pl, otherEndFd, stderrFd); 00372 return pl; 00373 }
Here is the call graph for this function:

Here is the caller graph for this function:

| struct pipeline* pipelineOpenFd1 | ( | char ** | cmd, | |
| unsigned | opts, | |||
| int | otherEndFd, | |||
| int | stderrFd | |||
| ) | [read] |
Definition at line 413 of file pipeline.c.
References pipelineOpenFd().
Referenced by lineFileDecompressFd().
00416 { 00417 char **cmds[2]; 00418 cmds[0] = cmd; 00419 cmds[1] = NULL; 00420 return pipelineOpenFd(cmds, opts, otherEndFd, stderrFd); 00421 }
Here is the call graph for this function:

Here is the caller graph for this function:

| struct pipeline* pipelineOpenMem | ( | char *** | cmds, | |
| unsigned | opts, | |||
| void * | otherEndBuf, | |||
| size_t | otherEndBufSize, | |||
| int | stderrFd | |||
| ) | [read] |
Definition at line 395 of file pipeline.c.
References checkOpts(), errAbort(), pipelineMemInput, pipelineNew(), pipelineStartRead(), and pipelineWrite.
Referenced by pipelineOpenMem1().
00401 { 00402 struct pipeline *pl; 00403 checkOpts(opts); 00404 if (opts & pipelineWrite) 00405 errAbort("pipelineOpenMem only supports read pipelines at this time"); 00406 opts |= pipelineMemInput; 00407 00408 pl = pipelineNew(cmds, opts); 00409 pipelineStartRead(pl, STDIN_FILENO, stderrFd, otherEndBuf, otherEndBufSize); 00410 return pl; 00411 }
Here is the call graph for this function:

Here is the caller graph for this function:

| struct pipeline* pipelineOpenMem1 | ( | char ** | cmd, | |
| unsigned | opts, | |||
| void * | otherEndBuf, | |||
| size_t | otherEndBufSize, | |||
| int | stderrFd | |||
| ) | [read] |
Definition at line 433 of file pipeline.c.
References pipelineOpenMem().
Referenced by lineFileDecompressMem().
00437 { 00438 char **cmds[2]; 00439 cmds[0] = cmd; 00440 cmds[1] = NULL; 00441 return pipelineOpenMem(cmds, opts, otherEndBuf, otherEndBufSize, stderrFd); 00442 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void pipelineStartRead | ( | struct pipeline * | pl, | |
| int | stdinFd, | |||
| int | stderrFd, | |||
| void * | otherEndBuf, | |||
| size_t | otherEndBufSize | |||
| ) | [static] |
Definition at line 333 of file pipeline.c.
References pipeCreate(), pipeline::pipeFd, pipelineExec(), plProc::pl, and safeClose().
Referenced by pipelineOpenFd(), and pipelineOpenMem().
00336 { 00337 int pipeWrFd; 00338 pl->pipeFd = pipeCreate(&pipeWrFd); 00339 pipelineExec(pl, stdinFd, pipeWrFd, stderrFd, otherEndBuf, otherEndBufSize); 00340 safeClose(&pipeWrFd); 00341 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void pipelineStartWrite | ( | struct pipeline * | pl, | |
| int | stdoutFd, | |||
| int | stderrFd | |||
| ) | [static] |
Definition at line 343 of file pipeline.c.
References pipeCreate(), pipeline::pipeFd, pipelineExec(), plProc::pl, and safeClose().
Referenced by pipelineOpenFd().
00345 { 00346 int pipeRdFd = pipeCreate(&pl->pipeFd); 00347 pipelineExec(pl, pipeRdFd, stdoutFd, stderrFd, NULL, 0); 00348 safeClose(&pipeRdFd); 00349 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int pipelineWait | ( | struct pipeline * | pl | ) |
Definition at line 525 of file pipeline.c.
References closePipeline(), plProc::next, pipeline::options, pipelineRead, pipelineWrite, plProc::pl, plProcWait(), plProc::status, and WEXITSTATUS.
Referenced by lineFileClose(), and textOutClose().
00529 { 00530 struct plProc *proc; 00531 int exitCode = 0; 00532 00533 /* must close before waits for output pipeline */ 00534 if (pl->options & pipelineWrite) 00535 closePipeline(pl); 00536 00537 /* wait on each process in order */ 00538 for (proc = pl->procs; proc != NULL; proc = proc->next) 00539 { 00540 plProcWait(proc); 00541 if ((WEXITSTATUS(proc->status) != 0) && (exitCode == 0)) 00542 exitCode = WEXITSTATUS(proc->status); 00543 } 00544 00545 /* must close after waits for input pipeline */ 00546 if (pl->options & pipelineRead) 00547 closePipeline(pl); 00548 00549 return exitCode; 00550 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void plProcExecChild | ( | struct plProc * | proc, | |
| int | stdinFd, | |||
| int | stdoutFd, | |||
| int | stderrFd | |||
| ) | [static] |
Definition at line 172 of file pipeline.c.
References plProc::cmd, errnoAbort(), and plProcSetup().
Referenced by pipelineExecProc().
00174 { 00175 plProcSetup(proc, stdinFd, stdoutFd, stderrFd); 00176 /* FIXME: add close-on-exec startup error reporting here */ 00177 execvp(proc->cmd[0], proc->cmd); 00178 errnoAbort("exec failed: %s", proc->cmd[0]); 00179 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void plProcFree | ( | struct plProc * | proc | ) | [static] |
Definition at line 116 of file pipeline.c.
References plProc::cmd, and freeMem().
Referenced by pipelineFree().
00118 { 00119 int i; 00120 for (i = 0; proc->cmd[i] != NULL; i++) 00121 freeMem(proc->cmd[i]); 00122 freeMem(proc->cmd); 00123 freeMem(proc); 00124 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void plProcMemWrite | ( | struct plProc * | proc, | |
| int | stdoutFd, | |||
| int | stderrFd, | |||
| void * | otherEndBuf, | |||
| size_t | otherEndBufSize | |||
| ) | [static] |
Definition at line 181 of file pipeline.c.
References errAbort(), errnoAbort(), and plProcSetup().
Referenced by pipelineExecProc().
00184 { 00185 ssize_t wrCnt; 00186 plProcSetup(proc, STDIN_FILENO, stdoutFd, stderrFd); 00187 wrCnt = write(STDOUT_FILENO, otherEndBuf, otherEndBufSize); 00188 if (wrCnt < 0) 00189 errnoAbort("pipeline input buffer write failed"); 00190 else if (wrCnt != otherEndBufSize) 00191 errAbort("pipeline input buffer short write %lld, expected %lld", 00192 (long long)wrCnt, (long long)otherEndBufSize); 00193 else 00194 { 00195 close(STDOUT_FILENO); 00196 exit(0); 00197 } 00198 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 98 of file pipeline.c.
References AllocVar, cloneString(), plProc::cmd, needMem(), and plProc::pl.
Referenced by pipelineNew().
00100 { 00101 int i, cmdLen = 0; 00102 struct plProc* proc; 00103 AllocVar(proc); 00104 proc->pl = pl; 00105 00106 for (i = 0; cmd[i] != NULL; i++) 00107 cmdLen++; 00108 proc->cmd = needMem((cmdLen+1)*sizeof(char*)); 00109 00110 for (i = 0; i < cmdLen; i++) 00111 proc->cmd[i] = cloneString(cmd[i]); 00112 proc->cmd[cmdLen] = NULL; 00113 return proc; 00114 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void plProcSetup | ( | struct plProc * | proc, | |
| int | stdinFd, | |||
| int | stdoutFd, | |||
| int | stderrFd | |||
| ) | [static] |
Definition at line 132 of file pipeline.c.
References childAbortHandler(), errnoAbort(), pushAbortHandler(), pushWarnAbort(), and ZeroVar.
Referenced by plProcExecChild(), and plProcMemWrite().
00134 { 00135 int fd; 00136 struct sigaction sigAct; 00137 00138 /* make sure abort handler exits */ 00139 pushWarnAbort(); 00140 pushAbortHandler(childAbortHandler); 00141 00142 /* treat a closed pipe as an EOF rather than getting SIGPIPE */ 00143 ZeroVar(&sigAct); 00144 sigAct.sa_handler = SIG_IGN; 00145 if (sigaction(SIGPIPE, &sigAct, NULL) != 0) 00146 errnoAbort("failed to set SIGPIPE to SIG_IGN"); 00147 00148 /* child, first setup stdio files */ 00149 if (stdinFd != STDIN_FILENO) 00150 { 00151 if (dup2(stdinFd, STDIN_FILENO) < 0) 00152 errnoAbort("can't dup2 to stdin"); 00153 } 00154 00155 if (stdoutFd != STDOUT_FILENO) 00156 { 00157 if (dup2(stdoutFd, STDOUT_FILENO) < 0) 00158 errnoAbort("can't dup2 to stdout"); 00159 } 00160 00161 if (stderrFd != STDERR_FILENO) 00162 { 00163 if (dup2(stderrFd, STDERR_FILENO) < 0) 00164 errnoAbort("can't dup2 to stderr"); 00165 } 00166 00167 /* close other file descriptors */ 00168 for (fd = STDERR_FILENO+1; fd < 64; fd++) 00169 close(fd); 00170 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void plProcWait | ( | struct plProc * | proc | ) | [static] |
Definition at line 200 of file pipeline.c.
References plProc::cmd, errAbort(), errnoAbort(), joinCmd(), pipeline::options, plProc::pid, pipelineNoAbort, plProc::pl, pipeline::procName, plProc::status, WEXITSTATUS, WIFEXITED, WIFSIGNALED, and WTERMSIG.
Referenced by pipelineWait().
00202 { 00203 if (waitpid(proc->pid, &proc->status, 0) < 0) 00204 errnoAbort("process lost for: \"%s\" in pipeline \"%s\"", joinCmd(proc->cmd), 00205 proc->pl->procName); 00206 if (WIFSIGNALED(proc->status)) 00207 errAbort("process terminated on signal %d: \"%s\" in pipeline \"%s\"", 00208 WTERMSIG(proc->status), joinCmd(proc->cmd), proc->pl->procName); 00209 assert(WIFEXITED(proc->status)); 00210 00211 if ((WEXITSTATUS(proc->status) != 0) && !(proc->pl->options & pipelineNoAbort)) 00212 errAbort("process exited with %d: \"%s\" in pipeline \"%s\"", 00213 WEXITSTATUS(proc->status), joinCmd(proc->cmd), proc->pl->procName); 00214 proc->pid = -1; 00215 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void safeClose | ( | int * | fdPtr | ) | [static] |
Definition at line 53 of file pipeline.c.
References errnoAbort(), and lineFile::fd.
Referenced by pipelineExecProc(), pipelineOpen(), pipelineStartRead(), and pipelineStartWrite().
00055 { 00056 int fd = *fdPtr; 00057 if (fd != -1) 00058 { 00059 if (close(fd) < 0) 00060 errnoAbort("close failed on fd %d", fd); 00061 *fdPtr = -1; 00062 } 00063 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.5.2