Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef RUN_COMMAND_H |
2 | | #define RUN_COMMAND_H |
3 | | |
4 | | #include "thread-utils.h" |
5 | | |
6 | | #include "strvec.h" |
7 | | |
8 | | /** |
9 | | * The run-command API offers a versatile tool to run sub-processes with |
10 | | * redirected input and output as well as with a modified environment |
11 | | * and an alternate current directory. |
12 | | * |
13 | | * A similar API offers the capability to run a function asynchronously, |
14 | | * which is primarily used to capture the output that the function |
15 | | * produces in the caller in order to process it. |
16 | | */ |
17 | | |
18 | | |
19 | | /** |
20 | | * This describes the arguments, redirections, and environment of a |
21 | | * command to run in a sub-process. |
22 | | * |
23 | | * The caller: |
24 | | * |
25 | | * 1. allocates and clears (using child_process_init() or |
26 | | * CHILD_PROCESS_INIT) a struct child_process variable; |
27 | | * 2. initializes the members; |
28 | | * 3. calls start_command(); |
29 | | * 4. processes the data; |
30 | | * 5. closes file descriptors (if necessary; see below); |
31 | | * 6. calls finish_command(). |
32 | | * |
33 | | * Special forms of redirection are available by setting these members |
34 | | * to 1: |
35 | | * |
36 | | * .no_stdin, .no_stdout, .no_stderr: The respective channel is |
37 | | * redirected to /dev/null. |
38 | | * |
39 | | * .stdout_to_stderr: stdout of the child is redirected to its |
40 | | * stderr. This happens after stderr is itself redirected. |
41 | | * So stdout will follow stderr to wherever it is |
42 | | * redirected. |
43 | | */ |
44 | | struct child_process { |
45 | | |
46 | | /** |
47 | | * The .args is a `struct strvec', use that API to manipulate |
48 | | * it, e.g. strvec_pushv() to add an existing "const char **" |
49 | | * vector. |
50 | | * |
51 | | * If the command to run is a git command, set the first |
52 | | * element in the strvec to the command name without the |
53 | | * 'git-' prefix and set .git_cmd = 1. |
54 | | * |
55 | | * The memory in .args will be cleaned up automatically during |
56 | | * `finish_command` (or during `start_command` when it is unsuccessful). |
57 | | */ |
58 | | struct strvec args; |
59 | | |
60 | | /** |
61 | | * Like .args the .env is a `struct strvec'. |
62 | | * |
63 | | * To modify the environment of the sub-process, specify an array of |
64 | | * environment settings. Each string in the array manipulates the |
65 | | * environment. |
66 | | * |
67 | | * - If the string is of the form "VAR=value", i.e. it contains '=' |
68 | | * the variable is added to the child process's environment. |
69 | | * |
70 | | * - If the string does not contain '=', it names an environment |
71 | | * variable that will be removed from the child process's environment. |
72 | | * |
73 | | * The memory in .env will be cleaned up automatically during |
74 | | * `finish_command` (or during `start_command` when it is unsuccessful). |
75 | | */ |
76 | | struct strvec env; |
77 | | pid_t pid; |
78 | | |
79 | | int trace2_child_id; |
80 | | uint64_t trace2_child_us_start; |
81 | | const char *trace2_child_class; |
82 | | const char *trace2_hook_name; |
83 | | |
84 | | /* |
85 | | * Using .in, .out, .err: |
86 | | * - Specify 0 for no redirections. No new file descriptor is allocated. |
87 | | * (child inherits stdin, stdout, stderr from parent). |
88 | | * - Specify -1 to have a pipe allocated as follows: |
89 | | * .in: returns the writable pipe end; parent writes to it, |
90 | | * the readable pipe end becomes child's stdin |
91 | | * .out, .err: returns the readable pipe end; parent reads from |
92 | | * it, the writable pipe end becomes child's stdout/stderr |
93 | | * The caller of start_command() must close the returned FDs |
94 | | * after it has completed reading from/writing to it! |
95 | | * - Specify > 0 to set a channel to a particular FD as follows: |
96 | | * .in: a readable FD, becomes child's stdin |
97 | | * .out: a writable FD, becomes child's stdout/stderr |
98 | | * .err: a writable FD, becomes child's stderr |
99 | | * The specified FD is closed by start_command(), even in case |
100 | | * of errors! |
101 | | */ |
102 | | int in; |
103 | | int out; |
104 | | int err; |
105 | | |
106 | | /** |
107 | | * To specify a new initial working directory for the sub-process, |
108 | | * specify it in the .dir member. |
109 | | */ |
110 | | const char *dir; |
111 | | |
112 | | unsigned no_stdin:1; |
113 | | unsigned no_stdout:1; |
114 | | unsigned no_stderr:1; |
115 | | unsigned git_cmd:1; /* if this is to be git sub-command */ |
116 | | |
117 | | /** |
118 | | * If the program cannot be found, the functions return -1 and set |
119 | | * errno to ENOENT. Normally, an error message is printed, but if |
120 | | * .silent_exec_failure is set to 1, no message is printed for this |
121 | | * special error condition. |
122 | | */ |
123 | | unsigned silent_exec_failure:1; |
124 | | |
125 | | /** |
126 | | * Run the command from argv[0] using a shell (but note that we may |
127 | | * still optimize out the shell call if the command contains no |
128 | | * metacharacters). Note that further arguments to the command in |
129 | | * argv[1], etc, do not need to be shell-quoted. |
130 | | */ |
131 | | unsigned use_shell:1; |
132 | | |
133 | | /** |
134 | | * Release any open file handles to the object store before running |
135 | | * the command; This is necessary e.g. when the spawned process may |
136 | | * want to repack because that would delete `.pack` files (and on |
137 | | * Windows, you cannot delete files that are still in use). |
138 | | */ |
139 | | unsigned close_object_store:1; |
140 | | |
141 | | unsigned stdout_to_stderr:1; |
142 | | unsigned clean_on_exit:1; |
143 | | unsigned wait_after_clean:1; |
144 | | void (*clean_on_exit_handler)(struct child_process *process); |
145 | | }; |
146 | | |
147 | 0 | #define CHILD_PROCESS_INIT { \ |
148 | 0 | .args = STRVEC_INIT, \ |
149 | 0 | .env = STRVEC_INIT, \ |
150 | 0 | } |
151 | | |
152 | | /** |
153 | | * The functions: start_command, finish_command, run_command do the following: |
154 | | * |
155 | | * - If a system call failed, errno is set and -1 is returned. A diagnostic |
156 | | * is printed. |
157 | | * |
158 | | * - If the program was not found, then -1 is returned and errno is set to |
159 | | * ENOENT; a diagnostic is printed only if .silent_exec_failure is 0. |
160 | | * |
161 | | * - Otherwise, the program is run. If it terminates regularly, its exit |
162 | | * code is returned. No diagnostic is printed, even if the exit code is |
163 | | * non-zero. |
164 | | * |
165 | | * - If the program terminated due to a signal, then the return value is the |
166 | | * signal number + 128, ie. the same value that a POSIX shell's $? would |
167 | | * report. A diagnostic is printed. |
168 | | * |
169 | | */ |
170 | | |
171 | | /** |
172 | | * Initialize a struct child_process variable. |
173 | | */ |
174 | | void child_process_init(struct child_process *); |
175 | | |
176 | | /** |
177 | | * Release the memory associated with the struct child_process. |
178 | | * Most users of the run-command API don't need to call this |
179 | | * function explicitly because `start_command` invokes it on |
180 | | * failure and `finish_command` calls it automatically already. |
181 | | */ |
182 | | void child_process_clear(struct child_process *); |
183 | | |
184 | | int is_executable(const char *name); |
185 | | |
186 | | /** |
187 | | * Check if the command exists on $PATH. This emulates the path search that |
188 | | * execvp would perform, without actually executing the command so it |
189 | | * can be used before fork() to prepare to run a command using |
190 | | * execve() or after execvp() to diagnose why it failed. |
191 | | * |
192 | | * The caller should ensure that command contains no directory separators. |
193 | | * |
194 | | * Returns 1 if it is found in $PATH or 0 if the command could not be found. |
195 | | */ |
196 | | int exists_in_PATH(const char *command); |
197 | | |
198 | | /** |
199 | | * Return the path that is used to execute Unix shell command-lines. |
200 | | */ |
201 | | char *git_shell_path(void); |
202 | | |
203 | | /** |
204 | | * Start a sub-process. Takes a pointer to a `struct child_process` |
205 | | * that specifies the details and returns pipe FDs (if requested). |
206 | | * See below for details. |
207 | | */ |
208 | | int start_command(struct child_process *); |
209 | | |
210 | | /** |
211 | | * Wait for the completion of a sub-process that was started with |
212 | | * start_command(). |
213 | | */ |
214 | | int finish_command(struct child_process *); |
215 | | |
216 | | int finish_command_in_signal(struct child_process *); |
217 | | |
218 | | /** |
219 | | * A convenience function that encapsulates a sequence of |
220 | | * start_command() followed by finish_command(). Takes a pointer |
221 | | * to a `struct child_process` that specifies the details. |
222 | | */ |
223 | | int run_command(struct child_process *); |
224 | | |
225 | | /* |
226 | | * Prepare a `struct child_process` to run auto-maintenance. Returns 1 if the |
227 | | * process has been prepared and is ready to run, or 0 in case auto-maintenance |
228 | | * should be skipped. |
229 | | */ |
230 | | int prepare_auto_maintenance(int quiet, struct child_process *maint); |
231 | | |
232 | | /* |
233 | | * Trigger an auto-gc |
234 | | */ |
235 | | int run_auto_maintenance(int quiet); |
236 | | |
237 | | /** |
238 | | * Execute the given command, sending "in" to its stdin, and capturing its |
239 | | * stdout and stderr in the "out" and "err" strbufs. Any of the three may |
240 | | * be NULL to skip processing. |
241 | | * |
242 | | * Returns -1 if starting the command fails or reading fails, and otherwise |
243 | | * returns the exit code of the command. Any output collected in the |
244 | | * buffers is kept even if the command returns a non-zero exit. The hint fields |
245 | | * gives starting sizes for the strbuf allocations. |
246 | | * |
247 | | * The fields of "cmd" should be set up as they would for a normal run_command |
248 | | * invocation. But note that there is no need to set the in, out, or err |
249 | | * fields; pipe_command handles that automatically. |
250 | | */ |
251 | | int pipe_command(struct child_process *cmd, |
252 | | const char *in, size_t in_len, |
253 | | struct strbuf *out, size_t out_hint, |
254 | | struct strbuf *err, size_t err_hint); |
255 | | |
256 | | /** |
257 | | * Convenience wrapper around pipe_command for the common case |
258 | | * of capturing only stdout. |
259 | | */ |
260 | | static inline int capture_command(struct child_process *cmd, |
261 | | struct strbuf *out, |
262 | | size_t hint) |
263 | 0 | { |
264 | 0 | return pipe_command(cmd, NULL, 0, out, hint, NULL, 0); |
265 | 0 | } Unexecuted instantiation: add.c:capture_command Unexecuted instantiation: am.c:capture_command Unexecuted instantiation: archive.c:capture_command Unexecuted instantiation: bisect.c:capture_command Unexecuted instantiation: clone.c:capture_command Unexecuted instantiation: commit.c:capture_command Unexecuted instantiation: credential-cache.c:capture_command Unexecuted instantiation: describe.c:capture_command Unexecuted instantiation: difftool.c:capture_command Unexecuted instantiation: fast-import.c:capture_command Unexecuted instantiation: fetch.c:capture_command Unexecuted instantiation: for-each-repo.c:capture_command Unexecuted instantiation: fsck.c:capture_command Unexecuted instantiation: fsmonitor--daemon.c:capture_command Unexecuted instantiation: gc.c:capture_command Unexecuted instantiation: grep.c:capture_command Unexecuted instantiation: help.c:capture_command Unexecuted instantiation: ls-remote.c:capture_command Unexecuted instantiation: merge-index.c:capture_command Unexecuted instantiation: merge.c:capture_command Unexecuted instantiation: notes.c:capture_command Unexecuted instantiation: pull.c:capture_command Unexecuted instantiation: push.c:capture_command Unexecuted instantiation: rebase.c:capture_command Unexecuted instantiation: receive-pack.c:capture_command Unexecuted instantiation: remote-ext.c:capture_command Unexecuted instantiation: remote-fd.c:capture_command Unexecuted instantiation: remote.c:capture_command Unexecuted instantiation: repack.c:capture_command Unexecuted instantiation: replace.c:capture_command Unexecuted instantiation: send-pack.c:capture_command Unexecuted instantiation: stash.c:capture_command Unexecuted instantiation: submodule--helper.c:capture_command Unexecuted instantiation: upload-archive.c:capture_command Unexecuted instantiation: var.c:capture_command Unexecuted instantiation: verify-pack.c:capture_command Unexecuted instantiation: worktree.c:capture_command Unexecuted instantiation: git.c:capture_command Unexecuted instantiation: add-interactive.c:capture_command Unexecuted instantiation: add-patch.c:capture_command Unexecuted instantiation: branch.c:capture_command Unexecuted instantiation: bundle-uri.c:capture_command Unexecuted instantiation: bundle.c:capture_command Unexecuted instantiation: column.c:capture_command Unexecuted instantiation: terminal.c:capture_command Unexecuted instantiation: connect.c:capture_command Unexecuted instantiation: connected.c:capture_command Unexecuted instantiation: convert.c:capture_command Unexecuted instantiation: credential.c:capture_command Unexecuted instantiation: diff.c:capture_command Unexecuted instantiation: editor.c:capture_command Unexecuted instantiation: exec-cmd.c:capture_command Unexecuted instantiation: fetch-pack.c:capture_command Unexecuted instantiation: fsmonitor.c:capture_command Unexecuted instantiation: fsmonitor-ipc.c:capture_command Unexecuted instantiation: gpg-interface.c:capture_command Unexecuted instantiation: hook.c:capture_command Unexecuted instantiation: merge-ll.c:capture_command Unexecuted instantiation: midx-write.c:capture_command Unexecuted instantiation: object-file.c:capture_command Unexecuted instantiation: pager.c:capture_command Unexecuted instantiation: parallel-checkout.c:capture_command Unexecuted instantiation: pkt-line.c:capture_command Unexecuted instantiation: pretty.c:capture_command Unexecuted instantiation: promisor-remote.c:capture_command Unexecuted instantiation: prompt.c:capture_command Unexecuted instantiation: range-diff.c:capture_command Unexecuted instantiation: reachable.c:capture_command Unexecuted instantiation: ref-filter.c:capture_command Unexecuted instantiation: refs.c:capture_command Unexecuted instantiation: run-command.c:capture_command Unexecuted instantiation: sequencer.c:capture_command Unexecuted instantiation: sub-process.c:capture_command Unexecuted instantiation: submodule.c:capture_command Unexecuted instantiation: trace2.c:capture_command Unexecuted instantiation: tr2_tgt_event.c:capture_command Unexecuted instantiation: tr2_tgt_normal.c:capture_command Unexecuted instantiation: tr2_tgt_perf.c:capture_command Unexecuted instantiation: trailer.c:capture_command Unexecuted instantiation: transport-helper.c:capture_command Unexecuted instantiation: transport.c:capture_command Unexecuted instantiation: upload-pack.c:capture_command Unexecuted instantiation: write-or-die.c:capture_command Unexecuted instantiation: wt-status.c:capture_command Unexecuted instantiation: archive-tar.c:capture_command |
266 | | |
267 | | /* |
268 | | * The purpose of the following functions is to feed a pipe by running |
269 | | * a function asynchronously and providing output that the caller reads. |
270 | | * |
271 | | * It is expected that no synchronization and mutual exclusion between |
272 | | * the caller and the feed function is necessary so that the function |
273 | | * can run in a thread without interfering with the caller. |
274 | | * |
275 | | * The caller: |
276 | | * |
277 | | * 1. allocates and clears (memset(&asy, 0, sizeof(asy));) a |
278 | | * struct async variable; |
279 | | * 2. initializes .proc and .data; |
280 | | * 3. calls start_async(); |
281 | | * 4. processes communicates with proc through .in and .out; |
282 | | * 5. closes .in and .out; |
283 | | * 6. calls finish_async(). |
284 | | * |
285 | | * There are serious restrictions on what the asynchronous function can do |
286 | | * because this facility is implemented by a thread in the same address |
287 | | * space on most platforms (when pthreads is available), but by a pipe to |
288 | | * a forked process otherwise: |
289 | | * |
290 | | * - It cannot change the program's state (global variables, environment, |
291 | | * etc.) in a way that the caller notices; in other words, .in and .out |
292 | | * are the only communication channels to the caller. |
293 | | * |
294 | | * - It must not change the program's state that the caller of the |
295 | | * facility also uses. |
296 | | * |
297 | | */ |
298 | | struct async { |
299 | | |
300 | | /** |
301 | | * The function pointer in .proc has the following signature: |
302 | | * |
303 | | * int proc(int in, int out, void *data); |
304 | | * |
305 | | * - in, out specifies a set of file descriptors to which the function |
306 | | * must read/write the data that it needs/produces. The function |
307 | | * *must* close these descriptors before it returns. A descriptor |
308 | | * may be -1 if the caller did not configure a descriptor for that |
309 | | * direction. |
310 | | * |
311 | | * - data is the value that the caller has specified in the .data member |
312 | | * of struct async. |
313 | | * |
314 | | * - The return value of the function is 0 on success and non-zero |
315 | | * on failure. If the function indicates failure, finish_async() will |
316 | | * report failure as well. |
317 | | * |
318 | | */ |
319 | | int (*proc)(int in, int out, void *data); |
320 | | |
321 | | void *data; |
322 | | |
323 | | /** |
324 | | * The members .in, .out are used to provide a set of fd's for |
325 | | * communication between the caller and the callee as follows: |
326 | | * |
327 | | * - Specify 0 to have no file descriptor passed. The callee will |
328 | | * receive -1 in the corresponding argument. |
329 | | * |
330 | | * - Specify < 0 to have a pipe allocated; start_async() replaces |
331 | | * with the pipe FD in the following way: |
332 | | * |
333 | | * .in: Returns the writable pipe end into which the caller |
334 | | * writes; the readable end of the pipe becomes the function's |
335 | | * in argument. |
336 | | * |
337 | | * .out: Returns the readable pipe end from which the caller |
338 | | * reads; the writable end of the pipe becomes the function's |
339 | | * out argument. |
340 | | * |
341 | | * The caller of start_async() must close the returned FDs after it |
342 | | * has completed reading from/writing from them. |
343 | | * |
344 | | * - Specify a file descriptor > 0 to be used by the function: |
345 | | * |
346 | | * .in: The FD must be readable; it becomes the function's in. |
347 | | * .out: The FD must be writable; it becomes the function's out. |
348 | | * |
349 | | * The specified FD is closed by start_async(), even if it fails to |
350 | | * run the function. |
351 | | */ |
352 | | int in; /* caller writes here and closes it */ |
353 | | int out; /* caller reads from here and closes it */ |
354 | | #ifdef NO_PTHREADS |
355 | | pid_t pid; |
356 | | #else |
357 | | pthread_t tid; |
358 | | int proc_in; |
359 | | int proc_out; |
360 | | #endif |
361 | | int isolate_sigpipe; |
362 | | }; |
363 | | |
364 | | /** |
365 | | * Run a function asynchronously. Takes a pointer to a `struct |
366 | | * async` that specifies the details and returns a set of pipe FDs |
367 | | * for communication with the function. See below for details. |
368 | | */ |
369 | | int start_async(struct async *async); |
370 | | |
371 | | /** |
372 | | * Wait for the completion of an asynchronous function that was |
373 | | * started with start_async(). |
374 | | */ |
375 | | int finish_async(struct async *async); |
376 | | |
377 | | int in_async(void); |
378 | | int async_with_fork(void); |
379 | | void check_pipe(int err); |
380 | | |
381 | | /** |
382 | | * This callback should initialize the child process and preload the |
383 | | * error channel if desired. The preloading of is useful if you want to |
384 | | * have a message printed directly before the output of the child process. |
385 | | * pp_cb is the callback cookie as passed to run_processes_parallel. |
386 | | * You can store a child process specific callback cookie in pp_task_cb. |
387 | | * |
388 | | * See run_processes_parallel() below for a discussion of the "struct |
389 | | * strbuf *out" parameter. |
390 | | * |
391 | | * Even after returning 0 to indicate that there are no more processes, |
392 | | * this function will be called again until there are no more running |
393 | | * child processes. |
394 | | * |
395 | | * Return 1 if the next child is ready to run. |
396 | | * Return 0 if there are currently no more tasks to be processed. |
397 | | * To send a signal to other child processes for abortion, |
398 | | * return the negative signal number. |
399 | | */ |
400 | | typedef int (*get_next_task_fn)(struct child_process *cp, |
401 | | struct strbuf *out, |
402 | | void *pp_cb, |
403 | | void **pp_task_cb); |
404 | | |
405 | | /** |
406 | | * This callback is called whenever there are problems starting |
407 | | * a new process. |
408 | | * |
409 | | * See run_processes_parallel() below for a discussion of the "struct |
410 | | * strbuf *out" parameter. |
411 | | * |
412 | | * pp_cb is the callback cookie as passed into run_processes_parallel, |
413 | | * pp_task_cb is the callback cookie as passed into get_next_task_fn. |
414 | | * |
415 | | * Return 0 to continue the parallel processing. To abort return non zero. |
416 | | * To send a signal to other child processes for abortion, return |
417 | | * the negative signal number. |
418 | | */ |
419 | | typedef int (*start_failure_fn)(struct strbuf *out, |
420 | | void *pp_cb, |
421 | | void *pp_task_cb); |
422 | | |
423 | | /** |
424 | | * This callback is called on every child process that finished processing. |
425 | | * |
426 | | * See run_processes_parallel() below for a discussion of the "struct |
427 | | * strbuf *out" parameter. |
428 | | * |
429 | | * pp_cb is the callback cookie as passed into run_processes_parallel, |
430 | | * pp_task_cb is the callback cookie as passed into get_next_task_fn. |
431 | | * |
432 | | * Return 0 to continue the parallel processing. To abort return non zero. |
433 | | * To send a signal to other child processes for abortion, return |
434 | | * the negative signal number. |
435 | | */ |
436 | | typedef int (*task_finished_fn)(int result, |
437 | | struct strbuf *out, |
438 | | void *pp_cb, |
439 | | void *pp_task_cb); |
440 | | |
441 | | /** |
442 | | * Option used by run_processes_parallel(), { 0 }-initialized means no |
443 | | * options. |
444 | | */ |
445 | | struct run_process_parallel_opts |
446 | | { |
447 | | /** |
448 | | * tr2_category & tr2_label: sets the trace2 category and label for |
449 | | * logging. These must either be unset, or both of them must be set. |
450 | | */ |
451 | | const char *tr2_category; |
452 | | const char *tr2_label; |
453 | | |
454 | | /** |
455 | | * processes: see 'processes' in run_processes_parallel() below. |
456 | | */ |
457 | | size_t processes; |
458 | | |
459 | | /** |
460 | | * ungroup: see 'ungroup' in run_processes_parallel() below. |
461 | | */ |
462 | | unsigned int ungroup:1; |
463 | | |
464 | | /** |
465 | | * get_next_task: See get_next_task_fn() above. This must be |
466 | | * specified. |
467 | | */ |
468 | | get_next_task_fn get_next_task; |
469 | | |
470 | | /** |
471 | | * start_failure: See start_failure_fn() above. This can be |
472 | | * NULL to omit any special handling. |
473 | | */ |
474 | | start_failure_fn start_failure; |
475 | | |
476 | | /** |
477 | | * task_finished: See task_finished_fn() above. This can be |
478 | | * NULL to omit any special handling. |
479 | | */ |
480 | | task_finished_fn task_finished; |
481 | | |
482 | | /** |
483 | | * data: user data, will be passed as "pp_cb" to the callback |
484 | | * parameters. |
485 | | */ |
486 | | void *data; |
487 | | }; |
488 | | |
489 | | /** |
490 | | * Options are passed via the "struct run_process_parallel_opts" above. |
491 | | * |
492 | | * Runs N 'processes' at the same time. Whenever a process can be |
493 | | * started, the callback opts.get_next_task is called to obtain the data |
494 | | * required to start another child process. |
495 | | * |
496 | | * The children started via this function run in parallel. Their output |
497 | | * (both stdout and stderr) is routed to stderr in a manner that output |
498 | | * from different tasks does not interleave (but see "ungroup" below). |
499 | | * |
500 | | * If the "ungroup" option isn't specified, the API will set the |
501 | | * "stdout_to_stderr" parameter in "struct child_process" and provide |
502 | | * the callbacks with a "struct strbuf *out" parameter to write output |
503 | | * to. In this case the callbacks must not write to stdout or |
504 | | * stderr as such output will mess up the output of the other parallel |
505 | | * processes. If "ungroup" option is specified callbacks will get a |
506 | | * NULL "struct strbuf *out" parameter, and are responsible for |
507 | | * emitting their own output, including dealing with any race |
508 | | * conditions due to writing in parallel to stdout and stderr. |
509 | | */ |
510 | | void run_processes_parallel(const struct run_process_parallel_opts *opts); |
511 | | |
512 | | /** |
513 | | * Convenience function which prepares env for a command to be run in a |
514 | | * new repo. This adds all GIT_* environment variables to env with the |
515 | | * exception of GIT_CONFIG_PARAMETERS and GIT_CONFIG_COUNT (which cause the |
516 | | * corresponding environment variables to be unset in the subprocess) and adds |
517 | | * an environment variable pointing to new_git_dir. See local_repo_env in |
518 | | * environment.h for more information. |
519 | | */ |
520 | | void prepare_other_repo_env(struct strvec *env, const char *new_git_dir); |
521 | | |
522 | | /** |
523 | | * Possible return values for start_bg_command(). |
524 | | */ |
525 | | enum start_bg_result { |
526 | | /* child process is "ready" */ |
527 | | SBGR_READY = 0, |
528 | | |
529 | | /* child process could not be started */ |
530 | | SBGR_ERROR, |
531 | | |
532 | | /* callback error when testing for "ready" */ |
533 | | SBGR_CB_ERROR, |
534 | | |
535 | | /* timeout expired waiting for child to become "ready" */ |
536 | | SBGR_TIMEOUT, |
537 | | |
538 | | /* child process exited or was signalled before becomming "ready" */ |
539 | | SBGR_DIED, |
540 | | }; |
541 | | |
542 | | /** |
543 | | * Callback used by start_bg_command() to ask whether the |
544 | | * child process is ready or needs more time to become "ready". |
545 | | * |
546 | | * The callback will receive the cmd and cb_data arguments given to |
547 | | * start_bg_command(). |
548 | | * |
549 | | * Returns 1 is child needs more time (subject to the requested timeout). |
550 | | * Returns 0 if child is "ready". |
551 | | * Returns -1 on any error and cause start_bg_command() to also error out. |
552 | | */ |
553 | | typedef int(start_bg_wait_cb)(const struct child_process *cmd, void *cb_data); |
554 | | |
555 | | /** |
556 | | * Start a command in the background. Wait long enough for the child |
557 | | * to become "ready" (as defined by the provided callback). Capture |
558 | | * immediate errors (like failure to start) and any immediate exit |
559 | | * status (such as a shutdown/signal before the child became "ready") |
560 | | * and return this like start_command(). |
561 | | * |
562 | | * We run a custom wait loop using the provided callback to wait for |
563 | | * the child to start and become "ready". This is limited by the given |
564 | | * timeout value. |
565 | | * |
566 | | * If the child does successfully start and become "ready", we orphan |
567 | | * it into the background. |
568 | | * |
569 | | * The caller must not call finish_command(). |
570 | | * |
571 | | * The opaque cb_data argument will be forwarded to the callback for |
572 | | * any instance data that it might require. This may be NULL. |
573 | | */ |
574 | | enum start_bg_result start_bg_command(struct child_process *cmd, |
575 | | start_bg_wait_cb *wait_cb, |
576 | | void *cb_data, |
577 | | unsigned int timeout_sec); |
578 | | |
579 | | int sane_execvp(const char *file, char *const argv[]); |
580 | | |
581 | | #endif |