libpipeline (1.5.7)

(root)/
include/
pipeline.h
       1  /* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2002
       2   * Free Software Foundation, Inc.
       3   * Copyright (C) 2003-2017 Colin Watson.
       4   *   Written for groff by James Clark (jjc@jclark.com)
       5   *   Adapted for man-db by Colin Watson.
       6   *
       7   * This file is part of libpipeline.
       8   *
       9   * libpipeline is free software; you can redistribute it and/or modify
      10   * it under the terms of the GNU General Public License as published by
      11   * the Free Software Foundation; either version 2 of the License, or (at
      12   * your option) any later version.
      13   *
      14   * libpipeline is distributed in the hope that it will be useful, but
      15   * WITHOUT ANY WARRANTY; without even the implied warranty of
      16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17   * General Public License for more details.
      18   *
      19   * You should have received a copy of the GNU General Public License
      20   * along with libpipeline; if not, write to the Free Software
      21   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
      22   * USA.
      23   */
      24  
      25  #ifndef PIPELINE_H
      26  #define PIPELINE_H
      27  
      28  #ifdef __cplusplus
      29  extern "C" {
      30  #endif
      31  
      32  #include <stdarg.h>
      33  #include <stdio.h>
      34  #include <sys/types.h>
      35  
      36  /* GCC version checking borrowed from glibc. */
      37  #if defined(__GNUC__) && defined(__GNUC_MINOR__)
      38  #  define PIPELINE_GNUC_PREREQ(maj, min)                                      \
      39      ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
      40  #else
      41  #  define PIPELINE_GNUC_PREREQ(maj, min) 0
      42  #endif
      43  
      44  /* Does this compiler support format string checking? */
      45  #if PIPELINE_GNUC_PREREQ(2, 0)
      46  #  define PIPELINE_ATTR_FORMAT_PRINTF(a, b)                                   \
      47      __attribute__ ((__format__ (__printf__, a, b)))
      48  #else
      49  #  define PIPELINE_ATTR_FORMAT_PRINTF(a, b)
      50  #endif
      51  
      52  /* Does this compiler support marking variables as unused? */
      53  /* This is no longer used internally and isn't documented as part of
      54   * libpipeline's public API, but is preserved just in case somebody used it
      55   * anyway.
      56   */
      57  #if PIPELINE_GNUC_PREREQ(2, 4)
      58  #  define PIPELINE_ATTR_UNUSED __attribute__ ((__unused__))
      59  #else
      60  #  define PIPELINE_ATTR_UNUSED
      61  #endif
      62  
      63  /* Does this compiler support marking functions as non-returning? */
      64  #if PIPELINE_GNUC_PREREQ(2, 5)
      65  #  define PIPELINE_ATTR_NORETURN __attribute__ ((__noreturn__))
      66  #else
      67  #  define PIPELINE_ATTR_NORETURN
      68  #endif
      69  
      70  /* Does this compiler support unused result checking? */
      71  #if PIPELINE_GNUC_PREREQ(3, 4)
      72  #  define PIPELINE_ATTR_WARN_UNUSED_RESULT                                    \
      73      __attribute__ ((__warn_unused_result__))
      74  #else
      75  #  define PIPELINE_ATTR_WARN_UNUSED_RESULT
      76  #endif
      77  
      78  /* Does this compiler support sentinel checking? */
      79  #if PIPELINE_GNUC_PREREQ(4, 0)
      80  #  define PIPELINE_ATTR_SENTINEL __attribute__ ((__sentinel__))
      81  #else
      82  #  define PIPELINE_ATTR_SENTINEL
      83  #endif
      84  
      85  typedef void pipecmd_function_type (void *);
      86  typedef void pipecmd_function_free_type (void *);
      87  
      88  struct pipecmd;
      89  typedef struct pipecmd pipecmd;
      90  
      91  struct pipeline;
      92  typedef struct pipeline pipeline;
      93  
      94  /* ---------------------------------------------------------------------- */
      95  
      96  /* Functions to build individual commands. */
      97  
      98  /* Construct a new command. */
      99  pipecmd *pipecmd_new (const char *name);
     100  
     101  /* Convenience constructors wrapping pipecmd_new() and pipecmd_arg().
     102   * Terminate arguments with NULL.
     103   */
     104  pipecmd *pipecmd_new_argv (const char *name, va_list argv);
     105  pipecmd *pipecmd_new_args (const char *name, ...) PIPELINE_ATTR_SENTINEL;
     106  
     107  /* Split argstr on whitespace to construct a command and arguments,
     108   * honouring shell-style single-quoting, double-quoting, and backslashes,
     109   * but not other shell evil like wildcards, semicolons, or backquotes. This
     110   * is a backward-compatibility hack to support old configuration file
     111   * directives; please try to avoid using it in new code.
     112   */
     113  pipecmd *pipecmd_new_argstr (const char *argstr);
     114  
     115  /* Construct a new command that calls a given function rather than executing
     116   * a process. The data argument is passed as the function's only argument,
     117   * and will be freed before returning using free_func (if non-NULL).
     118   *
     119   * pipecmd_* functions that deal with arguments cannot be used with the
     120   * command returned by this function.
     121   */
     122  pipecmd *pipecmd_new_function (const char *name, pipecmd_function_type *func,
     123                                 pipecmd_function_free_type *free_func,
     124                                 void *data);
     125  
     126  /* Construct a new command that runs a sequence of commands. The commands
     127   * will be executed in forked children; if any exits non-zero then it will
     128   * terminate the sequence, as with "&&" in shell.
     129   *
     130   * pipecmd_* functions that deal with arguments cannot be used with the
     131   * command returned by this function.
     132   */
     133  pipecmd *pipecmd_new_sequencev (const char *name, va_list cmdv);
     134  pipecmd *pipecmd_new_sequence (const char *name, ...) PIPELINE_ATTR_SENTINEL;
     135  
     136  /* Return a new command that just passes data from its input to its output. */
     137  pipecmd *pipecmd_new_passthrough (void);
     138  
     139  /* Return a duplicate of a command. */
     140  pipecmd *pipecmd_dup (pipecmd *cmd);
     141  
     142  /* Add an argument to a command. */
     143  void pipecmd_arg (pipecmd *cmd, const char *arg);
     144  
     145  /* Convenience function to add an argument with printf substitutions. */
     146  void pipecmd_argf (pipecmd *cmd, const char *format, ...)
     147          PIPELINE_ATTR_FORMAT_PRINTF (2, 3);
     148  
     149  /* Convenience functions wrapping pipecmd_arg().
     150   * Terminate arguments with NULL.
     151   */
     152  void pipecmd_argv (pipecmd *cmd, va_list argv);
     153  void pipecmd_args (pipecmd *cmd, ...) PIPELINE_ATTR_SENTINEL;
     154  
     155  /* Split argstr on whitespace to add a list of arguments, honouring
     156   * shell-style single-quoting, double-quoting, and backslashes, but not
     157   * other shell evil like wildcards, semicolons, or backquotes. This is a
     158   * backward-compatibility hack to support old configuration file directives;
     159   * please try to avoid using it in new code.
     160   */
     161  void pipecmd_argstr (pipecmd *cmd, const char *argstr);
     162  
     163  /* Return the number of arguments to this command.  Note that this includes
     164   * the command name as the first argument, so the command 'echo foo bar' is
     165   * counted as having three arguments.
     166   */
     167  int pipecmd_get_nargs (pipecmd *cmd);
     168  
     169  /* Set the nice(3) value for this command.  Defaults to 0.  Errors while
     170   * attempting to set the nice value are ignored, aside from emitting a debug
     171   * message.
     172   */
     173  void pipecmd_nice (pipecmd *cmd, int nice);
     174  
     175  /* If discard_err is non-zero, redirect this command's standard error to
     176   * /dev/null.  Otherwise, and by default, pass it through.
     177   */
     178  void pipecmd_discard_err (pipecmd *cmd, int discard_err);
     179  
     180  /* Change to this directory while running this command. */
     181  void pipecmd_chdir (pipecmd *cmd, const char *directory);
     182  
     183  /* Change to the directory given by this open file descriptor while running
     184   * this command. */
     185  void pipecmd_fchdir (pipecmd *cmd, int directory_fd);
     186  
     187  /* Set an environment variable while running this command. */
     188  void pipecmd_setenv (pipecmd *cmd, const char *name, const char *value);
     189  
     190  /* Unset an environment variable while running this command. */
     191  void pipecmd_unsetenv (pipecmd *cmd, const char *name);
     192  
     193  /* Clear the environment while running this command.  (Note that environment
     194   * operations work in sequence; pipecmd_clearenv followed by pipecmd_setenv
     195   * causes the command to have just a single environment variable set.)
     196   * Beware that this may cause unexpected failures, for example if some of
     197   * the contents of the environment are necessary to execute programs at all
     198   * (say, PATH).
     199   */
     200  void pipecmd_clearenv (pipecmd *cmd);
     201  
     202  /* Install a pre-exec handler.  This will be run immediately before
     203   * executing the command's payload (process or function).  Pass NULL to
     204   * clear any existing pre-exec handler.  The data argument is passed as the
     205   * function's only argument, and will be freed before returning using
     206   * free_func (if non-NULL).
     207   *
     208   * This is similar to pipeline_install_post_fork, except that is specific to
     209   * a single command rather than installing a global handler, and it runs
     210   * slightly later (immediately before exec rather than immediately after
     211   * fork).
     212   */
     213  void pipecmd_pre_exec (pipecmd *cmd, pipecmd_function_type *func,
     214                         pipecmd_function_free_type *free_func, void *data);
     215  
     216  /* Add a command to a sequence. */
     217  void pipecmd_sequence_command (pipecmd *cmd, pipecmd *child);
     218  
     219  /* Dump a string representation of a command to stream. */
     220  void pipecmd_dump (pipecmd *cmd, FILE *stream);
     221  
     222  /* Return a string representation of a command. The caller should free the
     223   * result.
     224   */
     225  char *pipecmd_tostring (pipecmd *cmd);
     226  
     227  /* Execute a single command, replacing the current process.  Never returns,
     228   * instead exiting non-zero on failure.
     229   */
     230  void pipecmd_exec (pipecmd *cmd) PIPELINE_ATTR_NORETURN;
     231  
     232  /* Destroy a command. Safely does nothing on NULL. */
     233  void pipecmd_free (pipecmd *cmd);
     234  
     235  /* ---------------------------------------------------------------------- */
     236  
     237  /* Functions to build pipelines. */
     238  
     239  /* Construct a new pipeline. */
     240  pipeline *pipeline_new (void);
     241  
     242  /* Convenience constructors wrapping pipeline_new() and pipeline_command().
     243   * Terminate commands with NULL.
     244   */
     245  pipeline *pipeline_new_commandv (pipecmd *cmd1, va_list cmdv);
     246  pipeline *pipeline_new_commands (pipecmd *cmd1, ...) PIPELINE_ATTR_SENTINEL;
     247  
     248  /* Construct a new pipeline and add a single command to it. */
     249  pipeline *pipeline_new_command_argv (const char *name, va_list argv);
     250  pipeline *pipeline_new_command_args (const char *name,
     251                                       ...) PIPELINE_ATTR_SENTINEL;
     252  
     253  /* Joins two pipelines, neither of which are allowed to be started. Discards
     254   * want_out, want_outfile, and outfd from p1, and want_in, want_infile, and
     255   * infd from p2.
     256   */
     257  pipeline *pipeline_join (pipeline *p1, pipeline *p2);
     258  
     259  /* Connect the input of one or more sink pipelines to the output of a source
     260   * pipeline. The source pipeline may be started, but in that case want_out
     261   * must be negative; otherwise, discards want_out from source. In any event,
     262   * discards want_in from all sinks, none of which are allowed to be started.
     263   * Terminate arguments with NULL.
     264   *
     265   * This is an application-level connection; data may be intercepted between
     266   * the pipelines by the program before calling pipeline_pump(), which sets
     267   * data flowing from the source to the sinks. It is primarily useful when
     268   * more than one sink pipeline is involved, in which case the pipelines
     269   * cannot simply be concatenated into one.
     270   */
     271  void pipeline_connect (pipeline *source, pipeline *sink,
     272                         ...) PIPELINE_ATTR_SENTINEL;
     273  
     274  /* Add a command to a pipeline. */
     275  void pipeline_command (pipeline *p, pipecmd *cmd);
     276  
     277  /* Construct a new command and add it to a pipeline in one go. */
     278  void pipeline_command_argv (pipeline *p, const char *name, va_list argv);
     279  void pipeline_command_args (pipeline *p, const char *name,
     280                              ...) PIPELINE_ATTR_SENTINEL;
     281  
     282  /* Construct a new command from a shell-quoted string and add it to a
     283   * pipeline in one go. See the comment against pipecmd_new_argstr() above if
     284   * you're tempted to use this function.
     285   */
     286  void pipeline_command_argstr (pipeline *p, const char *argstr);
     287  
     288  /* Convenience functions wrapping pipeline_command().
     289   * Terminate commands with NULL.
     290   */
     291  void pipeline_commandv (pipeline *p, va_list cmdv);
     292  void pipeline_commands (pipeline *p, ...) PIPELINE_ATTR_SENTINEL;
     293  
     294  /* Return the number of commands in this pipeline. */
     295  int pipeline_get_ncommands (pipeline *p);
     296  
     297  /* Return command number n from this pipeline, counting from zero, or NULL
     298   * if n is out of range.
     299   */
     300  pipecmd *pipeline_get_command (pipeline *p, int n);
     301  
     302  /* Set command number n in this pipeline, counting from zero, to cmd, and
     303   * return the previous command in that position.  Do nothing and return NULL
     304   * if n is out of range.
     305   */
     306  pipecmd *pipeline_set_command (pipeline *p, int n, pipecmd *cmd);
     307  
     308  /* Return the process ID of command number n from this pipeline, counting
     309   * from zero.  The pipeline must be started.  Return -1 if n is out of range
     310   * or if the command has already exited and been reaped.
     311   */
     312  pid_t pipeline_get_pid (pipeline *p, int n);
     313  
     314  /* Set file descriptors to use as the input and output of the whole
     315   * pipeline.  If non-negative, fd is used directly as a file descriptor.  If
     316   * negative, pipeline_start will create pipes and store the input writing
     317   * half and the output reading half in the pipeline's infd or outfd field as
     318   * appropriate.  The default is to leave input and output as stdin and
     319   * stdout unless pipeline_want_infile or pipeline_want_outfile respectively
     320   * has been called.
     321   *
     322   * Calling these functions supersedes any previous call to
     323   * pipeline_want_infile or pipeline_want_outfile respectively.
     324   */
     325  void pipeline_want_in (pipeline *p, int fd);
     326  void pipeline_want_out (pipeline *p, int fd);
     327  
     328  /* Set file names to open and use as the input and output of the whole
     329   * pipeline.  This may be more convenient than supplying file descriptors,
     330   * and guarantees that the files are opened with the same privileges under
     331   * which the pipeline is run.
     332   *
     333   * Calling these functions (even with NULL, which returns to the default of
     334   * leaving input and output as stdin and stdout) supersedes any previous
     335   * call to pipeline_want_in or pipeline_want_outfile respectively.
     336   *
     337   * The given files will be opened when the pipeline is started.  If an
     338   * output file does not already exist, it is created (with mode 0666
     339   * modified in the usual way by umask); if it does exist, then it is
     340   * truncated.
     341   */
     342  void pipeline_want_infile (pipeline *p, const char *file);
     343  void pipeline_want_outfile (pipeline *p, const char *file);
     344  
     345  /* If ignore_signals is non-zero (which is the default), ignore SIGINT and
     346   * SIGQUIT while the pipeline is running, like system().  Otherwise, leave
     347   * their dispositions unchanged.
     348   */
     349  void pipeline_ignore_signals (pipeline *p, int ignore_signals);
     350  
     351  /* Get streams corresponding to infd and outfd respectively. The pipeline
     352   * must be started.
     353   */
     354  FILE *pipeline_get_infile (pipeline *p);
     355  FILE *pipeline_get_outfile (pipeline *p);
     356  
     357  /* Dump a string representation of p to stream. */
     358  void pipeline_dump (pipeline *p, FILE *stream);
     359  
     360  /* Return a string representation of p. The caller should free the result. */
     361  char *pipeline_tostring (pipeline *p);
     362  
     363  /* Destroy a pipeline and all its commands. Safely does nothing on NULL.
     364   * May wait for the pipeline to complete if it has not already done so.
     365   */
     366  void pipeline_free (pipeline *p);
     367  
     368  /* ---------------------------------------------------------------------- */
     369  
     370  /* Functions to run pipelines and handle signals. */
     371  
     372  typedef void pipeline_post_fork_fn (void);
     373  
     374  /* Install a post-fork handler.  This will be run in any child process
     375   * immediately after it is forked.  For instance, this may be used for
     376   * cleaning up application-specific signal handlers.  Pass NULL to clear any
     377   * existing post-fork handler.
     378   *
     379   * See pipecmd_pre_exec for a similar facility limited to a single command
     380   * rather than global to the calling process.
     381   */
     382  void pipeline_install_post_fork (pipeline_post_fork_fn *fn);
     383  
     384  /* Start the processes in a pipeline.  Installs this library's SIGCHLD
     385   * handler if not already installed.  Calls error(FATAL) on error.
     386   *
     387   * The standard file descriptors (0, 1, and 2) must be open before calling
     388   * this function.
     389   */
     390  void pipeline_start (pipeline *p);
     391  
     392  /* Wait for a pipeline to complete.  Set *statuses to a newly-allocated
     393   * array of wait statuses, as returned by waitpid, and *n_statuses to the
     394   * length of that array.  The return value is similar to the exit status
     395   * that a shell would return, with some modifications.  If the last command
     396   * exits with a signal (other than SIGPIPE, which is considered equivalent
     397   * to exiting zero), then the return value is 128 plus the signal number; if
     398   * the last command exits normally but non-zero, then the return value is
     399   * its exit status; if any other command exits non-zero, then the return
     400   * value is 127; otherwise, the return value is 0.  This means that the
     401   * return value is only 0 if all commands in the pipeline exit successfully.
     402   */
     403  int pipeline_wait_all (pipeline *p, int **statuses, int *n_statuses);
     404  
     405  /* Wait for a pipeline to complete and return its combined exit status,
     406   * calculated as for pipeline_wait_all().
     407   */
     408  int pipeline_wait (pipeline *p);
     409  
     410  /* Start a pipeline, wait for it to complete, and free it, all in one go. */
     411  int pipeline_run (pipeline *p);
     412  
     413  /* Pump data among one or more pipelines connected using pipeline_connect()
     414   * until all source pipelines have reached end-of-file and all data has been
     415   * written to all sinks (or failed). All relevant pipelines must be
     416   * supplied: that is, no pipeline that has been connected to a source
     417   * pipeline may be supplied unless that source pipeline is also supplied.
     418   * Automatically starts all pipelines if they are not already started, but
     419   * does not wait for them. Terminate arguments with NULL.
     420   */
     421  void pipeline_pump (pipeline *p, ...) PIPELINE_ATTR_SENTINEL;
     422  
     423  /* ---------------------------------------------------------------------- */
     424  
     425  /* Functions to read output from pipelines. */
     426  
     427  /* Read len bytes of data from the pipeline, returning the data block. len
     428   * is updated with the number of bytes read.
     429   */
     430  const char *pipeline_read (pipeline *p, size_t *len);
     431  
     432  /* Look ahead in the pipeline's output for len bytes of data, returning the
     433   * data block. len is updated with the number of bytes read. The starting
     434   * position of the next read or peek is not affected by this call.
     435   */
     436  const char *pipeline_peek (pipeline *p, size_t *len);
     437  
     438  /* Return the number of bytes of data that can be read using pipeline_read
     439   * or pipeline_peek solely from the peek cache, without having to read from
     440   * the pipeline itself (and thus potentially block).
     441   */
     442  size_t pipeline_peek_size (pipeline *p);
     443  
     444  /* Skip over and discard len bytes of data from the peek cache. Asserts that
     445   * enough data is available to skip, so you may want to check using
     446   * pipeline_peek_size first.
     447   */
     448  void pipeline_peek_skip (pipeline *p, size_t len);
     449  
     450  /* Read a line of data from the pipeline, returning it. */
     451  const char *pipeline_readline (pipeline *p);
     452  
     453  /* Look ahead in the pipeline's output for a line of data, returning it. The
     454   * starting position of the next read or peek is not affected by this call.
     455   */
     456  const char *pipeline_peekline (pipeline *p);
     457  
     458  #ifdef __cplusplus
     459  }
     460  #endif
     461  
     462  #endif /* PIPELINE_H */