1 /* Filtering of data through a subprocess. -*- coding: utf-8 -*- 2 Copyright (C) 2009-2021 Free Software Foundation, Inc. 3 Written by Bruno Haible <haible@clisp.cons.org>, 2009, 4 and Paolo Bonzini <bonzini@gnu.org>, 2009. 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 18 19 #ifndef _PIPE_FILTER_H 20 #define _PIPE_FILTER_H 21 22 #include <stdbool.h> 23 #include <stddef.h> 24 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 31 /* Piping data through a subprocess in the naïve way - write data to the 32 subprocess and read from the subprocess when you expect it to have 33 produced results - is subject to two kinds of deadlocks: 34 1) If you write more than PIPE_MAX bytes or, more generally, if you write 35 more bytes than the subprocess can handle at once, the subprocess 36 may write its data and wait on you to read it, but you are currently 37 busy writing. 38 2) When you don't know ahead of time how many bytes the subprocess 39 will produce, the usual technique of calling read (fd, buf, BUFSIZ) 40 with a fixed BUFSIZ will, on Linux 2.2.17 and on BSD systems, cause 41 the read() call to block until *all* of the buffer has been filled. 42 But the subprocess cannot produce more data until you gave it more 43 input. But you are currently busy reading from it. 44 45 This header file declares four set of functions that pipes data through 46 the subprocess, without risking these deadlocks. 47 48 The side that writes data to the subprocess can be seen as a "generator", 49 that is, as a subroutine that produces and writes a piece of data here and 50 there, see <https://en.wikipedia.org/wiki/Generator_(computer_science)>. 51 But often, it can be written in the form of an "iterator", that is, as a 52 function that, each time it is invoked, produces and writes one more piece 53 of data. 54 55 Similarly, the side that reads data from the subprocess can be seen as 56 a "generator", that is, as a subroutine that consumes a piece of data here 57 and there. Often, it can be written in the form of an "iterator", that 58 is, as a function that, each time it is invoked, consumes one more piece 59 of data. 60 61 This header file declares four set of functions: 62 63 | writer | reader | 64 ----------------+------------+------------+ 65 pipe_filter_ii | iterator | iterator | 66 pipe_filter_ig | iterator | generator | 67 pipe_filter_gi | generator | iterator | 68 pipe_filter_gg | generator | generator | 69 ----------------+------------+------------+ 70 71 The last one uses threads in order to implement two generators running at 72 the same time. (For the relation between generators, coroutines, and 73 threads, see <https://en.wikipedia.org/wiki/Generator_(computer_science)> 74 and <https://en.wikipedia.org/wiki/Coroutine>.) It is therefore only 75 portable to platforms with kernel-based POSIX threads. */ 76 77 /* These two functions together describe the side that writes data to the 78 subprocess when it has the form of an iterator. 79 - prepare_write (&num_bytes, p) must either return a pointer to data that 80 is ready to be written and set num_bytes to the number of bytes ready to 81 be written, or return NULL when no more bytes are to be written. 82 - done_write (data_written, num_bytes_written) is called after 83 num_bytes_written bytes were written. It is guaranteed that 84 num_bytes_written > 0. 85 Here p is always the private_data argument passed to the main function. */ 86 typedef const void * (*prepare_write_fn) (size_t *num_bytes_p, 87 void *private_data); 88 typedef void (*done_write_fn) (void *data_written, size_t num_bytes_written, 89 void *private_data); 90 91 /* These two functions together describe the side that reads data from the 92 subprocess when it has the form of an iterator. 93 - prepare_read (&num_bytes, p) must return a pointer to a buffer for data 94 that can be read and set num_bytes to the size of that buffer 95 (must be > 0). 96 - done_read (data_read, num_bytes_read, p) is called after num_bytes_read 97 bytes were read into the buffer. 98 Here p is always the private_data argument passed to the main function. */ 99 typedef void * (*prepare_read_fn) (size_t *num_bytes_p, 100 void *private_data); 101 typedef void (*done_read_fn) (void *data_read, size_t num_bytes_read, 102 void *private_data); 103 104 105 /* ============================ pipe_filter_ii ============================ */ 106 107 /* Create a subprocess and pipe some data through it. 108 Arguments: 109 - progname is the program name used in error messages. 110 - prog_path is the file name of the program to invoke. 111 - prog_argv is a NULL terminated argument list, starting with prog_path as 112 first element. 113 - If null_stderr is true, the subprocess' stderr will be redirected to 114 /dev/null, and the usual error message to stderr will be omitted. 115 This is suitable when the subprocess does not fulfill an important task. 116 - If exit_on_error is true, any error will cause the main process to exit 117 with an error status. 118 If the subprocess does not terminate correctly, exit if exit_on_error is 119 true, otherwise return 127. 120 Callback arguments are as described above. 121 122 Data is alternately written to the subprocess, through the functions 123 prepare_write and done_write, and read from the subprocess, through the 124 functions prepare_read and done_read. 125 126 Note that the prepare_write/done_write functions and the 127 prepare_read/done_read functions may be called in different threads than 128 the current thread (depending on the platform). But they will not be 129 called after the pipe_filter_ii_execute function has returned. 130 131 Return 0 upon success, or (only if exit_on_error is false): 132 - -1 with errno set upon failure, 133 - the positive exit code of the subprocess if that failed. */ 134 extern int 135 pipe_filter_ii_execute (const char *progname, 136 const char *prog_path, 137 const char * const *prog_argv, 138 bool null_stderr, bool exit_on_error, 139 prepare_write_fn prepare_write, 140 done_write_fn done_write, 141 prepare_read_fn prepare_read, 142 done_read_fn done_read, 143 void *private_data); 144 145 146 /* ============================ pipe_filter_ig ============================ */ 147 148 struct pipe_filter_ig; 149 150 151 /* ============================ pipe_filter_gi ============================ */ 152 153 struct pipe_filter_gi; 154 155 /* Finish reading the output via the prepare_read/done_read functions 156 specified to pipe_filter_gi_create. 157 158 Note that the prepare_read/done_read functions may be called in a 159 different thread than the current thread (depending on the platform). 160 However, they will always be called before pipe_filter_gi_close has 161 returned. 162 163 The write side of the pipe is closed as soon as pipe_filter_gi_close 164 starts, while the read side will be closed just before it finishes. 165 166 Return 0 upon success, or (only if exit_on_error is false): 167 - -1 with errno set upon failure, 168 - the positive exit code of the subprocess if that failed. */ 169 extern int 170 pipe_filter_gi_close (struct pipe_filter_gi *filter); 171 172 /* Create a subprocess and pipe some data through it. 173 Arguments: 174 - progname is the program name used in error messages. 175 - prog_path is the file name of the program to invoke. 176 - prog_argv is a NULL terminated argument list, starting with 177 prog_path as first element. 178 - If null_stderr is true, the subprocess' stderr will be redirected 179 to /dev/null, and the usual error message to stderr will be 180 omitted. This is suitable when the subprocess does not fulfill an 181 important task. 182 - If exit_on_error is true, any error will cause the main process to 183 exit with an error status. 184 If the subprocess does not start correctly, exit if exit_on_error is 185 true, otherwise return NULL and set errno. 186 187 The caller will write to the subprocess through pipe_filter_gi_write 188 and finally call pipe_filter_gi_close. During such calls, the 189 prepare_read and done_read function may be called to process any data 190 that the subprocess has written. 191 192 Note that the prepare_read/done_read functions may be called in a 193 different thread than the current thread (depending on the platform). 194 But they will not be called after the pipe_filter_gi_close function has 195 returned. 196 197 Return the freshly created 'struct pipe_filter_gi'. */ 198 extern struct pipe_filter_gi * 199 pipe_filter_gi_create (const char *progname, 200 const char *prog_path, 201 const char * const *prog_argv, 202 bool null_stderr, bool exit_on_error, 203 prepare_read_fn prepare_read, 204 done_read_fn done_read, 205 void *private_data) 206 _GL_ATTRIBUTE_DEALLOC (pipe_filter_gi_close, 1); 207 208 /* Write size bytes starting at buf into the pipe and in the meanwhile 209 possibly call the prepare_read and done_read functions specified to 210 pipe_filter_gi_create. 211 212 Note that the prepare_read/done_read functions may be called in a 213 different thread than the current thread (depending on the platform). 214 However, they will always be called before pipe_filter_gi_write has 215 returned, or otherwise not sooner than the next call to 216 pipe_filter_gi_write or pipe_filter_gi_close. 217 218 Return only after all the entire buffer has been written to the pipe or 219 the subprocess has exited. 220 221 Return 0 upon success, or (only if exit_on_error is false): 222 - -1 with errno set upon failure, 223 - the positive exit code of the subprocess if that failed. */ 224 extern int 225 pipe_filter_gi_write (struct pipe_filter_gi *filter, 226 const void *buf, size_t size); 227 228 229 /* ============================ pipe_filter_gg ============================ */ 230 231 232 /* ======================================================================== */ 233 234 235 #ifdef __cplusplus 236 } 237 #endif 238 239 240 #endif /* _PIPE_FILTER_H */