00001 /* pipeline.h - create a process pipeline that can be used for reading or 00002 * writing. These pipeline objects don't go through the shell, so they 00003 * avoid many of the obscure problems associated with system() and popen(). 00004 * 00005 * Read pipelines are pipelines where a program reads output written by the 00006 * pipeline, and write pipelines are where the program writes data to the 00007 * pipeline. The type of pipeline is specified in the set of option flags 00008 * passed to pipelineOpen(). The file at the other end of the pipeline is 00009 * specified in the otherEndFile argument of pipelineOpen(), as shown here: 00010 * 00011 * pipelineRead: 00012 * 00013 * otherEndFile --> cmd[0] --> ... --> cmd[n] --> pipelineLf() etc. 00014 * 00015 * pipelineWrite: 00016 * 00017 * pipeLineFile() --> cmd[0] --> ... --> cmd[n] --> otherEndFile 00018 * 00019 * Specify otherEndFile as "/dev/null" for no input or no output (or to 00020 * discard output). If otherEndFile is NULL, then either stdin or stdout are 00021 * inherited from the current process. 00022 * 00023 * I/O to the pipeline is done by using the result of pipelineFd(), 00024 * pipelineFile(), or pipelineLineFile(). 00025 * 00026 * An example that reads a compressed file, sorting it numerically by the 00027 * first column: 00028 * 00029 * static char *cmd1[] = {"gzip", "-dc", NULL}; 00030 * static char *cmd2[] = {"sort", "-k", "1,1n", NULL}; 00031 * static char **cmds[] = {cmd1, cmd2, NULL}; 00032 * 00033 * struct pipeline *pl = pipelineOpen(cmds, pipelineRead, inFilePath); 00034 * struct lineFile *lf = pipelineLineFile(pl); 00035 * char *line; 00036 * 00037 * while (lineFileNext(lf, &line, NULL)) 00038 * { 00039 * ... 00040 * } 00041 * pipelineWait(pl); 00042 * pipelineFree(&pl); 00043 * 00044 * A similar example that generates data and writes a compressed file, sorting 00045 * it numerically by the first column: 00046 * 00047 * 00048 * static char *cmd1[] = {"sort", "-k", "1,1n", NULL}; 00049 * static char *cmd2[] = {"gzip", "-c3", NULL}; 00050 * static char **cmds[] = {cmd1, cmd2, NULL}; 00051 * 00052 * struct pipeline *pl = pipelineOpen(cmds, pipelineWrite, outFilePath); 00053 * char *line; 00054 * 00055 * while ((line = makeNextRow()) != NULL) 00056 * fprintf(fh, "%s\n", line); 00057 * 00058 * pipelineWait(pl); 00059 * pipelineFree(&pl); 00060 * 00061 */ 00062 #ifndef PIPELINE_H 00063 #define PIPELINE_H 00064 #include <stdio.h> 00065 struct linefile; 00066 struct pipeline; 00067 00068 enum pipelineOpts 00069 /* pipeline options bitset */ 00070 { 00071 pipelineRead = 0x01, /* read from pipeline */ 00072 pipelineWrite = 0x02, /* write to pipeline */ 00073 pipelineNoAbort = 0x04, /* don't abort if a process exits non-zero, 00074 * wait will return exit code instead. 00075 * Still aborts if process signals. */ 00076 /* these are internal options */ 00077 pipelineMemInput = 0x08 /* pipeline takes input from memory */ 00078 }; 00079 00080 struct pipeline *pipelineOpenFd(char ***cmds, unsigned opts, 00081 int otherEndFd, int stderrFd); 00082 /* Create a pipeline from an array of commands. Each command is an array of 00083 * arguments. Shell expansion is not done on the arguments. If pipelineRead 00084 * is specified, the output of the pipeline is readable from the pipeline 00085 * object. If pipelineWrite is specified, the input of the pipeline is 00086 * writable from the pipeline object. */ 00087 00088 struct pipeline *pipelineOpen(char ***cmds, unsigned opts, 00089 char *otherEndFile, char *stderrFile); 00090 /* Create a pipeline from an array of commands. Each command is an array of 00091 * arguments. Shell expansion is not done on the arguments. If pipelineRead 00092 * is specified, the output of the pipeline is readable from the pipeline 00093 * object. If pipelineWrite is specified, the input of the pipeline is 00094 * writable from the pipeline object. If stderrFile is NULL, stderr is inherited, 00095 * otherwise it is redirected to this file. 00096 */ 00097 00098 void pipelineDumpCmds(char ***cmds); 00099 /* Dump out pipeline-formatted commands to stdout for debugging. */ 00100 00101 struct pipeline *pipelineOpenMem(char ***cmds, unsigned opts, 00102 void *otherEndBuf, size_t otherEndBufSize, 00103 int stderrFd); 00104 /* Create a pipeline from an array of commands, with the pipeline input/output 00105 * in a memory buffer. See pipeline.h for full documentation. Currently only 00106 * input to a read pipeline is supported */ 00107 00108 struct pipeline *pipelineOpenFd1(char **cmd, unsigned opts, 00109 int otherEndFd, int stderrFd); 00110 /* like pipelineOpenFd(), only takes a single command */ 00111 00112 struct pipeline *pipelineOpen1(char **cmd, unsigned opts, 00113 char *otherEndFile, char *stderrFile); 00114 /* like pipelineOpen(), only takes a single command */ 00115 00116 struct pipeline *pipelineOpenMem1(char **cmd, unsigned opts, 00117 void *otherEndBuf, size_t otherEndBufSize, 00118 int stderrFd); 00119 /* like pipelineOpenMem(), only takes a single command */ 00120 00121 char *pipelineDesc(struct pipeline *pl); 00122 /* Get the desciption of a pipeline for use in error messages */ 00123 00124 int pipelineFd(struct pipeline *pl); 00125 /* Get the file descriptor for a pipeline */ 00126 00127 FILE *pipelineFile(struct pipeline *pl); 00128 /* Get a FILE object wrapped around the pipeline. Do not close the FILE, is 00129 * owned by the pipeline object. A FILE is created on first call to this 00130 * function. Subsequent calls return the same FILE.*/ 00131 00132 struct lineFile *pipelineLineFile(struct pipeline *pl); 00133 /* Get a lineFile object wrapped around the pipeline. Do not close the 00134 * lineFile, is owned by the pipeline object. A lineFile is created on first 00135 * call to this function. Subsequent calls return the same object.*/ 00136 00137 int pipelineWait(struct pipeline *pl); 00138 /* Wait for processes in a pipeline to complete; normally aborts if any 00139 * process exists non-zero. If pipelineNoAbort was specified, return the exit 00140 * code of the first process exit non-zero, or zero if none failed. */ 00141 00142 void pipelineFree(struct pipeline **plPtr); 00143 /* free a pipeline object */ 00144 00145 #endif 00146 /* 00147 * Local Variables: 00148 * c-file-style: "jkent-c" 00149 * End: 00150 */
1.5.2