Documentation / technical / api-run-command.txton commit Merge branch 'maint' (6d21667)
   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_dir`, `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 completeion 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 the
 115                parent's stderr (i.e. *not* to what .err or
 116                .no_stderr specify).
 117
 118To modify the environment of the sub-process, specify an array of
 119string pointers (NULL terminated) in .env:
 120
 121. If the string is of the form "VAR=value", i.e. it contains '='
 122  the variable is added to the child process's environment.
 123
 124. If the string does not contain '=', it names an environement
 125  variable that will be removed from the child process's envionment.
 126
 127To specify a new initial working directory for the sub-process,
 128specify it in the .dir member.
 129
 130
 131* `struct async`
 132
 133This describes a function to run asynchronously, whose purpose is
 134to produce output that the caller reads.
 135
 136The caller:
 137
 1381. allocates and clears (memset(&asy, '0', sizeof(asy));) a
 139   struct async variable;
 1402. initializes .proc and .data;
 1413. calls start_async();
 1424. processes the data by reading from the fd in .out;
 1435. closes .out;
 1446. calls finish_async().
 145
 146The function pointer in .proc has the following signature:
 147
 148        int proc(int fd, void *data);
 149
 150. fd specifies a writable file descriptor to which the function must
 151  write the data that it produces. The function *must* close this
 152  descriptor before it returns.
 153
 154. data is the value that the caller has specified in the .data member
 155  of struct async.
 156
 157. The return value of the function is 0 on success and non-zero
 158  on failure. If the function indicates failure, finish_async() will
 159  report failure as well.
 160
 161
 162There are serious restrictions on what the asynchronous function can do
 163because this facility is implemented by a pipe to a forked process on
 164UNIX, but by a thread in the same address space on Windows:
 165
 166. It cannot change the program's state (global variables, environment,
 167  etc.) in a way that the caller notices; in other words, .out is the
 168  only communication channel to the caller.
 169
 170. It must not change the program's state that the caller of the
 171  facility also uses.