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