root/maint/gnulib/lib/pipe-filter.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


   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 */

/* [previous][next][first][last][top][bottom][index][help] */