|  | run-command API | 
|  | =============== | 
|  |  | 
|  | The run-command API offers a versatile tool to run sub-processes with | 
|  | redirected input and output as well as with a modified environment | 
|  | and an alternate current directory. | 
|  |  | 
|  | A similar API offers the capability to run a function asynchronously, | 
|  | which is primarily used to capture the output that the function | 
|  | produces in the caller in order to process it. | 
|  |  | 
|  |  | 
|  | Functions | 
|  | --------- | 
|  |  | 
|  | `start_command`:: | 
|  |  | 
|  | Start a sub-process. Takes a pointer to a `struct child_process` | 
|  | that specifies the details and returns pipe FDs (if requested). | 
|  | See below for details. | 
|  |  | 
|  | `finish_command`:: | 
|  |  | 
|  | Wait for the completion of a sub-process that was started with | 
|  | start_command(). | 
|  |  | 
|  | `run_command`:: | 
|  |  | 
|  | A convenience function that encapsulates a sequence of | 
|  | start_command() followed by finish_command(). Takes a pointer | 
|  | to a `struct child_process` that specifies the details. | 
|  |  | 
|  | `run_command_v_opt`, `run_command_v_opt_cd_env`:: | 
|  |  | 
|  | Convenience functions that encapsulate a sequence of | 
|  | start_command() followed by finish_command(). The argument argv | 
|  | specifies the program and its arguments. The argument opt is zero | 
|  | or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`, | 
|  | `RUN_COMMAND_STDOUT_TO_STDERR`, or `RUN_SILENT_EXEC_FAILURE` | 
|  | that correspond to the members .no_stdin, .git_cmd, | 
|  | .stdout_to_stderr, .silent_exec_failure of `struct child_process`. | 
|  | The argument dir corresponds the member .dir. The argument env | 
|  | corresponds to the member .env. | 
|  |  | 
|  | The functions above do the following: | 
|  |  | 
|  | . If a system call failed, errno is set and -1 is returned. A diagnostic | 
|  | is printed. | 
|  |  | 
|  | . If the program was not found, then -1 is returned and errno is set to | 
|  | ENOENT; a diagnostic is printed only if .silent_exec_failure is 0. | 
|  |  | 
|  | . Otherwise, the program is run. If it terminates regularly, its exit | 
|  | code is returned. No diagnostic is printed, even if the exit code is | 
|  | non-zero. | 
|  |  | 
|  | . If the program terminated due to a signal, then the return value is the | 
|  | signal number + 128, ie. the same value that a POSIX shell's $? would | 
|  | report. A diagnostic is printed. | 
|  |  | 
|  |  | 
|  | `start_async`:: | 
|  |  | 
|  | Run a function asynchronously. Takes a pointer to a `struct | 
|  | async` that specifies the details and returns a set of pipe FDs | 
|  | for communication with the function. See below for details. | 
|  |  | 
|  | `finish_async`:: | 
|  |  | 
|  | Wait for the completion of an asynchronous function that was | 
|  | started with start_async(). | 
|  |  | 
|  | `run_hook`:: | 
|  |  | 
|  | Run a hook. | 
|  | The first argument is a pathname to an index file, or NULL | 
|  | if the hook uses the default index file or no index is needed. | 
|  | The second argument is the name of the hook. | 
|  | The further arguments correspond to the hook arguments. | 
|  | The last argument has to be NULL to terminate the arguments list. | 
|  | If the hook does not exist or is not executable, the return | 
|  | value will be zero. | 
|  | If it is executable, the hook will be executed and the exit | 
|  | status of the hook is returned. | 
|  | On execution, .stdout_to_stderr and .no_stdin will be set. | 
|  | (See below.) | 
|  |  | 
|  |  | 
|  | Data structures | 
|  | --------------- | 
|  |  | 
|  | * `struct child_process` | 
|  |  | 
|  | This describes the arguments, redirections, and environment of a | 
|  | command to run in a sub-process. | 
|  |  | 
|  | The caller: | 
|  |  | 
|  | 1. allocates and clears (memset(&chld, 0, sizeof(chld));) a | 
|  | struct child_process variable; | 
|  | 2. initializes the members; | 
|  | 3. calls start_command(); | 
|  | 4. processes the data; | 
|  | 5. closes file descriptors (if necessary; see below); | 
|  | 6. calls finish_command(). | 
|  |  | 
|  | The .argv member is set up as an array of string pointers (NULL | 
|  | terminated), of which .argv[0] is the program name to run (usually | 
|  | without a path). If the command to run is a git command, set argv[0] to | 
|  | the command name without the 'git-' prefix and set .git_cmd = 1. | 
|  |  | 
|  | The members .in, .out, .err are used to redirect stdin, stdout, | 
|  | stderr as follows: | 
|  |  | 
|  | . Specify 0 to request no special redirection. No new file descriptor | 
|  | is allocated. The child process simply inherits the channel from the | 
|  | parent. | 
|  |  | 
|  | . Specify -1 to have a pipe allocated; start_command() replaces -1 | 
|  | by the pipe FD in the following way: | 
|  |  | 
|  | .in: Returns the writable pipe end into which the caller writes; | 
|  | the readable end of the pipe becomes the child's stdin. | 
|  |  | 
|  | .out, .err: Returns the readable pipe end from which the caller | 
|  | reads; the writable end of the pipe end becomes child's | 
|  | stdout/stderr. | 
|  |  | 
|  | The caller of start_command() must close the so returned FDs | 
|  | after it has completed reading from/writing to it! | 
|  |  | 
|  | . Specify a file descriptor > 0 to be used by the child: | 
|  |  | 
|  | .in: The FD must be readable; it becomes child's stdin. | 
|  | .out: The FD must be writable; it becomes child's stdout. | 
|  | .err: The FD must be writable; it becomes child's stderr. | 
|  |  | 
|  | The specified FD is closed by start_command(), even if it fails to | 
|  | run the sub-process! | 
|  |  | 
|  | . Special forms of redirection are available by setting these members | 
|  | to 1: | 
|  |  | 
|  | .no_stdin, .no_stdout, .no_stderr: The respective channel is | 
|  | redirected to /dev/null. | 
|  |  | 
|  | .stdout_to_stderr: stdout of the child is redirected to its | 
|  | stderr. This happens after stderr is itself redirected. | 
|  | So stdout will follow stderr to wherever it is | 
|  | redirected. | 
|  |  | 
|  | To modify the environment of the sub-process, specify an array of | 
|  | string pointers (NULL terminated) in .env: | 
|  |  | 
|  | . If the string is of the form "VAR=value", i.e. it contains '=' | 
|  | the variable is added to the child process's environment. | 
|  |  | 
|  | . If the string does not contain '=', it names an environment | 
|  | variable that will be removed from the child process's environment. | 
|  |  | 
|  | To specify a new initial working directory for the sub-process, | 
|  | specify it in the .dir member. | 
|  |  | 
|  | If the program cannot be found, the functions return -1 and set | 
|  | errno to ENOENT. Normally, an error message is printed, but if | 
|  | .silent_exec_failure is set to 1, no message is printed for this | 
|  | special error condition. | 
|  |  | 
|  |  | 
|  | * `struct async` | 
|  |  | 
|  | This describes a function to run asynchronously, whose purpose is | 
|  | to produce output that the caller reads. | 
|  |  | 
|  | The caller: | 
|  |  | 
|  | 1. allocates and clears (memset(&asy, 0, sizeof(asy));) a | 
|  | struct async variable; | 
|  | 2. initializes .proc and .data; | 
|  | 3. calls start_async(); | 
|  | 4. processes communicates with proc through .in and .out; | 
|  | 5. closes .in and .out; | 
|  | 6. calls finish_async(). | 
|  |  | 
|  | The members .in, .out are used to provide a set of fd's for | 
|  | communication between the caller and the callee as follows: | 
|  |  | 
|  | . Specify 0 to have no file descriptor passed. The callee will | 
|  | receive -1 in the corresponding argument. | 
|  |  | 
|  | . Specify < 0 to have a pipe allocated; start_async() replaces | 
|  | with the pipe FD in the following way: | 
|  |  | 
|  | .in: Returns the writable pipe end into which the caller | 
|  | writes; the readable end of the pipe becomes the function's | 
|  | in argument. | 
|  |  | 
|  | .out: Returns the readable pipe end from which the caller | 
|  | reads; the writable end of the pipe becomes the function's | 
|  | out argument. | 
|  |  | 
|  | The caller of start_async() must close the returned FDs after it | 
|  | has completed reading from/writing from them. | 
|  |  | 
|  | . Specify a file descriptor > 0 to be used by the function: | 
|  |  | 
|  | .in: The FD must be readable; it becomes the function's in. | 
|  | .out: The FD must be writable; it becomes the function's out. | 
|  |  | 
|  | The specified FD is closed by start_async(), even if it fails to | 
|  | run the function. | 
|  |  | 
|  | The function pointer in .proc has the following signature: | 
|  |  | 
|  | int proc(int in, int out, void *data); | 
|  |  | 
|  | . in, out specifies a set of file descriptors to which the function | 
|  | must read/write the data that it needs/produces. The function | 
|  | *must* close these descriptors before it returns. A descriptor | 
|  | may be -1 if the caller did not configure a descriptor for that | 
|  | direction. | 
|  |  | 
|  | . data is the value that the caller has specified in the .data member | 
|  | of struct async. | 
|  |  | 
|  | . The return value of the function is 0 on success and non-zero | 
|  | on failure. If the function indicates failure, finish_async() will | 
|  | report failure as well. | 
|  |  | 
|  |  | 
|  | There are serious restrictions on what the asynchronous function can do | 
|  | because this facility is implemented by a thread in the same address | 
|  | space on most platforms (when pthreads is available), but by a pipe to | 
|  | a forked process otherwise: | 
|  |  | 
|  | . It cannot change the program's state (global variables, environment, | 
|  | etc.) in a way that the caller notices; in other words, .in and .out | 
|  | are the only communication channels to the caller. | 
|  |  | 
|  | . It must not change the program's state that the caller of the | 
|  | facility also uses. |