Documentation / technical / api-run-command.txton commit Merge branch 'mh/maint-sendmail-cc-doc' (c123b7c)
   1run-command API
   2===============
   3
   4The run-command API offers a versatile tool to run sub-processes with
   5redirected input and output as well as with a modified environment
   6and an alternate current directory.
   7
   8A similar API offers the capability to run a function asynchronously,
   9which is primarily used to capture the output that the function
  10produces in the caller in order to process it.
  11
  12
  13Functions
  14---------
  15
  16`start_command`::
  17
  18        Start a sub-process. Takes a pointer to a `struct child_process`
  19        that specifies the details and returns pipe FDs (if requested).
  20        See below for details.
  21
  22`finish_command`::
  23
  24        Wait for the completion of a sub-process that was started with
  25        start_command().
  26
  27`run_command`::
  28
  29        A convenience function that encapsulates a sequence of
  30        start_command() followed by finish_command(). Takes a pointer
  31        to a `struct child_process` that specifies the details.
  32
  33`run_command_v_opt`, `run_command_v_opt_cd_env`::
  34
  35        Convenience functions that encapsulate a sequence of
  36        start_command() followed by finish_command(). The argument argv
  37        specifies the program and its arguments. The argument opt is zero
  38        or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`, or
  39        `RUN_COMMAND_STDOUT_TO_STDERR` that correspond to the members
  40        .no_stdin, .git_cmd, .stdout_to_stderr of `struct child_process`.
  41        The argument dir corresponds the member .dir. The argument env
  42        corresponds to the member .env.
  43
  44`start_async`::
  45
  46        Run a function asynchronously. Takes a pointer to a `struct
  47        async` that specifies the details and returns a pipe FD
  48        from which the caller reads. See below for details.
  49
  50`finish_async`::
  51
  52        Wait for the completion of an asynchronous function that was
  53        started with start_async().
  54
  55
  56Data structures
  57---------------
  58
  59* `struct child_process`
  60
  61This describes the arguments, redirections, and environment of a
  62command to run in a sub-process.
  63
  64The caller:
  65
  661. allocates and clears (memset(&chld, 0, sizeof(chld));) a
  67   struct child_process variable;
  682. initializes the members;
  693. calls start_command();
  704. processes the data;
  715. closes file descriptors (if necessary; see below);
  726. calls finish_command().
  73
  74The .argv member is set up as an array of string pointers (NULL
  75terminated), of which .argv[0] is the program name to run (usually
  76without a path). If the command to run is a git command, set argv[0] to
  77the command name without the 'git-' prefix and set .git_cmd = 1.
  78
  79The members .in, .out, .err are used to redirect stdin, stdout,
  80stderr as follows:
  81
  82. Specify 0 to request no special redirection. No new file descriptor
  83  is allocated. The child process simply inherits the channel from the
  84  parent.
  85
  86. Specify -1 to have a pipe allocated; start_command() replaces -1
  87  by the pipe FD in the following way:
  88
  89        .in: Returns the writable pipe end into which the caller writes;
  90                the readable end of the pipe becomes the child's stdin.
  91
  92        .out, .err: Returns the readable pipe end from which the caller
  93                reads; the writable end of the pipe end becomes child's
  94                stdout/stderr.
  95
  96  The caller of start_command() must close the so returned FDs
  97  after it has completed reading from/writing to it!
  98
  99. Specify a file descriptor > 0 to be used by the child:
 100
 101        .in: The FD must be readable; it becomes child's stdin.
 102        .out: The FD must be writable; it becomes child's stdout.
 103        .err > 0 is not supported.
 104
 105  The specified FD is closed by start_command(), even if it fails to
 106  run the sub-process!
 107
 108. Special forms of redirection are available by setting these members
 109  to 1:
 110
 111        .no_stdin, .no_stdout, .no_stderr: The respective channel is
 112                redirected to /dev/null.
 113
 114        .stdout_to_stderr: stdout of the child is redirected to its
 115                stderr. This happens after stderr is itself redirected.
 116                So stdout will follow stderr to wherever it is
 117                redirected.
 118
 119To modify the environment of the sub-process, specify an array of
 120string pointers (NULL terminated) in .env:
 121
 122. If the string is of the form "VAR=value", i.e. it contains '='
 123  the variable is added to the child process's environment.
 124
 125. If the string does not contain '=', it names an environment
 126  variable that will be removed from the child process's environment.
 127
 128To specify a new initial working directory for the sub-process,
 129specify it in the .dir member.
 130
 131
 132* `struct async`
 133
 134This describes a function to run asynchronously, whose purpose is
 135to produce output that the caller reads.
 136
 137The caller:
 138
 1391. allocates and clears (memset(&asy, 0, sizeof(asy));) a
 140   struct async variable;
 1412. initializes .proc and .data;
 1423. calls start_async();
 1434. processes the data by reading from the fd in .out;
 1445. closes .out;
 1456. calls finish_async().
 146
 147The function pointer in .proc has the following signature:
 148
 149        int proc(int fd, void *data);
 150
 151. fd specifies a writable file descriptor to which the function must
 152  write the data that it produces. The function *must* close this
 153  descriptor before it returns.
 154
 155. data is the value that the caller has specified in the .data member
 156  of struct async.
 157
 158. The return value of the function is 0 on success and non-zero
 159  on failure. If the function indicates failure, finish_async() will
 160  report failure as well.
 161
 162
 163There are serious restrictions on what the asynchronous function can do
 164because this facility is implemented by a pipe to a forked process on
 165UNIX, but by a thread in the same address space on Windows:
 166
 167. It cannot change the program's state (global variables, environment,
 168  etc.) in a way that the caller notices; in other words, .out is the
 169  only communication channel to the caller.
 170
 171. It must not change the program's state that the caller of the
 172  facility also uses.