]>
Commit | Line | Data |
---|---|---|
530e741c JH |
1 | run-command API |
2 | =============== | |
3 | ||
b9dfe51c JS |
4 | The run-command API offers a versatile tool to run sub-processes with |
5 | redirected input and output as well as with a modified environment | |
6 | and an alternate current directory. | |
530e741c | 7 | |
b9dfe51c JS |
8 | A similar API offers the capability to run a function asynchronously, |
9 | which is primarily used to capture the output that the function | |
10 | produces in the caller in order to process it. | |
530e741c | 11 | |
b9dfe51c JS |
12 | |
13 | Functions | |
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 | ||
7996ff33 | 33 | `run_command_v_opt`, `run_command_v_opt_cd_env`:: |
b9dfe51c JS |
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 | |
0b913223 JS |
38 | or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`, |
39 | `RUN_COMMAND_STDOUT_TO_STDERR`, or `RUN_SILENT_EXEC_FAILURE` | |
40 | that correspond to the members .no_stdin, .git_cmd, | |
41 | .stdout_to_stderr, .silent_exec_failure of `struct child_process`. | |
b9dfe51c JS |
42 | The argument dir corresponds the member .dir. The argument env |
43 | corresponds to the member .env. | |
44 | ||
0b913223 JS |
45 | The functions above do the following: |
46 | ||
47 | . If a system call failed, errno is set and -1 is returned. A diagnostic | |
48 | is printed. | |
49 | ||
50 | . If the program was not found, then -1 is returned and errno is set to | |
51 | ENOENT; a diagnostic is printed only if .silent_exec_failure is 0. | |
52 | ||
53 | . Otherwise, the program is run. If it terminates regularly, its exit | |
6a5d0b0a | 54 | code is returned. No diagnostic is printed, even if the exit code is |
0b913223 JS |
55 | non-zero. |
56 | ||
57 | . If the program terminated due to a signal, then the return value is the | |
58 | signal number - 128, ie. it is negative and so indicates an unusual | |
59 | condition; a diagnostic is printed. This return value can be passed to | |
60 | exit(2), which will report the same code to the parent process that a | |
61 | POSIX shell's $? would report for a program that died from the signal. | |
62 | ||
63 | ||
b9dfe51c JS |
64 | `start_async`:: |
65 | ||
66 | Run a function asynchronously. Takes a pointer to a `struct | |
ae6a5609 EFL |
67 | async` that specifies the details and returns a set of pipe FDs |
68 | for communication with the function. See below for details. | |
b9dfe51c JS |
69 | |
70 | `finish_async`:: | |
71 | ||
34cd62eb | 72 | Wait for the completion of an asynchronous function that was |
b9dfe51c JS |
73 | started with start_async(). |
74 | ||
35d5ae67 SB |
75 | `run_hook`:: |
76 | ||
77 | Run a hook. | |
78 | The first argument is a pathname to an index file, or NULL | |
79 | if the hook uses the default index file or no index is needed. | |
80 | The second argument is the name of the hook. | |
14e6298f | 81 | The further arguments correspond to the hook arguments. |
35d5ae67 SB |
82 | The last argument has to be NULL to terminate the arguments list. |
83 | If the hook does not exist or is not executable, the return | |
84 | value will be zero. | |
85 | If it is executable, the hook will be executed and the exit | |
86 | status of the hook is returned. | |
87 | On execution, .stdout_to_stderr and .no_stdin will be set. | |
88 | (See below.) | |
89 | ||
b9dfe51c JS |
90 | |
91 | Data structures | |
92 | --------------- | |
93 | ||
94 | * `struct child_process` | |
95 | ||
96 | This describes the arguments, redirections, and environment of a | |
97 | command to run in a sub-process. | |
98 | ||
99 | The caller: | |
100 | ||
9e185223 | 101 | 1. allocates and clears (memset(&chld, 0, sizeof(chld));) a |
b9dfe51c JS |
102 | struct child_process variable; |
103 | 2. initializes the members; | |
104 | 3. calls start_command(); | |
105 | 4. processes the data; | |
106 | 5. closes file descriptors (if necessary; see below); | |
107 | 6. calls finish_command(). | |
108 | ||
109 | The .argv member is set up as an array of string pointers (NULL | |
110 | terminated), of which .argv[0] is the program name to run (usually | |
111 | without a path). If the command to run is a git command, set argv[0] to | |
112 | the command name without the 'git-' prefix and set .git_cmd = 1. | |
113 | ||
114 | The members .in, .out, .err are used to redirect stdin, stdout, | |
115 | stderr as follows: | |
116 | ||
117 | . Specify 0 to request no special redirection. No new file descriptor | |
118 | is allocated. The child process simply inherits the channel from the | |
119 | parent. | |
120 | ||
121 | . Specify -1 to have a pipe allocated; start_command() replaces -1 | |
122 | by the pipe FD in the following way: | |
123 | ||
124 | .in: Returns the writable pipe end into which the caller writes; | |
125 | the readable end of the pipe becomes the child's stdin. | |
126 | ||
127 | .out, .err: Returns the readable pipe end from which the caller | |
128 | reads; the writable end of the pipe end becomes child's | |
129 | stdout/stderr. | |
130 | ||
131 | The caller of start_command() must close the so returned FDs | |
132 | after it has completed reading from/writing to it! | |
133 | ||
134 | . Specify a file descriptor > 0 to be used by the child: | |
135 | ||
136 | .in: The FD must be readable; it becomes child's stdin. | |
137 | .out: The FD must be writable; it becomes child's stdout. | |
4f41b611 | 138 | .err: The FD must be writable; it becomes child's stderr. |
b9dfe51c JS |
139 | |
140 | The specified FD is closed by start_command(), even if it fails to | |
141 | run the sub-process! | |
142 | ||
143 | . Special forms of redirection are available by setting these members | |
144 | to 1: | |
145 | ||
146 | .no_stdin, .no_stdout, .no_stderr: The respective channel is | |
147 | redirected to /dev/null. | |
148 | ||
ce2cf27a CC |
149 | .stdout_to_stderr: stdout of the child is redirected to its |
150 | stderr. This happens after stderr is itself redirected. | |
151 | So stdout will follow stderr to wherever it is | |
152 | redirected. | |
b9dfe51c JS |
153 | |
154 | To modify the environment of the sub-process, specify an array of | |
155 | string pointers (NULL terminated) in .env: | |
156 | ||
157 | . If the string is of the form "VAR=value", i.e. it contains '=' | |
158 | the variable is added to the child process's environment. | |
159 | ||
34cd62eb RW |
160 | . If the string does not contain '=', it names an environment |
161 | variable that will be removed from the child process's environment. | |
b9dfe51c JS |
162 | |
163 | To specify a new initial working directory for the sub-process, | |
164 | specify it in the .dir member. | |
165 | ||
0b913223 JS |
166 | If the program cannot be found, the functions return -1 and set |
167 | errno to ENOENT. Normally, an error message is printed, but if | |
168 | .silent_exec_failure is set to 1, no message is printed for this | |
169 | special error condition. | |
170 | ||
b9dfe51c JS |
171 | |
172 | * `struct async` | |
173 | ||
174 | This describes a function to run asynchronously, whose purpose is | |
175 | to produce output that the caller reads. | |
176 | ||
177 | The caller: | |
178 | ||
9e185223 | 179 | 1. allocates and clears (memset(&asy, 0, sizeof(asy));) a |
b9dfe51c JS |
180 | struct async variable; |
181 | 2. initializes .proc and .data; | |
182 | 3. calls start_async(); | |
ae6a5609 EFL |
183 | 4. processes communicates with proc through .in and .out; |
184 | 5. closes .in and .out; | |
b9dfe51c JS |
185 | 6. calls finish_async(). |
186 | ||
ae6a5609 EFL |
187 | The members .in, .out are used to provide a set of fd's for |
188 | communication between the caller and the callee as follows: | |
189 | ||
190 | . Specify 0 to have no file descriptor passed. The callee will | |
191 | receive -1 in the corresponding argument. | |
192 | ||
193 | . Specify < 0 to have a pipe allocated; start_async() replaces | |
194 | with the pipe FD in the following way: | |
195 | ||
196 | .in: Returns the writable pipe end into which the caller | |
197 | writes; the readable end of the pipe becomes the function's | |
198 | in argument. | |
199 | ||
200 | .out: Returns the readable pipe end from which the caller | |
201 | reads; the writable end of the pipe becomes the function's | |
202 | out argument. | |
203 | ||
204 | The caller of start_async() must close the returned FDs after it | |
205 | has completed reading from/writing from them. | |
206 | ||
207 | . Specify a file descriptor > 0 to be used by the function: | |
208 | ||
209 | .in: The FD must be readable; it becomes the function's in. | |
210 | .out: The FD must be writable; it becomes the function's out. | |
211 | ||
212 | The specified FD is closed by start_async(), even if it fails to | |
213 | run the function. | |
214 | ||
b9dfe51c JS |
215 | The function pointer in .proc has the following signature: |
216 | ||
ae6a5609 | 217 | int proc(int in, int out, void *data); |
b9dfe51c | 218 | |
ae6a5609 EFL |
219 | . in, out specifies a set of file descriptors to which the function |
220 | must read/write the data that it needs/produces. The function | |
221 | *must* close these descriptors before it returns. A descriptor | |
222 | may be -1 if the caller did not configure a descriptor for that | |
223 | direction. | |
b9dfe51c JS |
224 | |
225 | . data is the value that the caller has specified in the .data member | |
226 | of struct async. | |
227 | ||
228 | . The return value of the function is 0 on success and non-zero | |
229 | on failure. If the function indicates failure, finish_async() will | |
230 | report failure as well. | |
231 | ||
232 | ||
233 | There are serious restrictions on what the asynchronous function can do | |
f6b60983 JS |
234 | because this facility is implemented by a thread in the same address |
235 | space on most platforms (when pthreads is available), but by a pipe to | |
236 | a forked process otherwise: | |
b9dfe51c JS |
237 | |
238 | . It cannot change the program's state (global variables, environment, | |
ae6a5609 EFL |
239 | etc.) in a way that the caller notices; in other words, .in and .out |
240 | are the only communication channels to the caller. | |
b9dfe51c JS |
241 | |
242 | . It must not change the program's state that the caller of the | |
243 | facility also uses. |