Josef Weidendorfer | b1bf95b | 2005-07-31 21:17:43 +0200 | [diff] [blame] | 1 | #ifndef RUN_COMMAND_H |
| 2 | #define RUN_COMMAND_H |
| 3 | |
Nguyễn Thái Ngọc Duy | 10bc232 | 2018-11-03 09:48:38 +0100 | [diff] [blame] | 4 | #include "thread-utils.h" |
Johannes Sixt | 200a76b | 2010-03-06 16:40:42 +0100 | [diff] [blame] | 5 | |
Jeff King | c460c0e | 2014-05-15 04:33:26 -0400 | [diff] [blame] | 6 | #include "argv-array.h" |
| 7 | |
Shawn O. Pearce | f100089 | 2007-03-10 03:28:00 -0500 | [diff] [blame] | 8 | struct child_process { |
| 9 | const char **argv; |
Jeff King | c460c0e | 2014-05-15 04:33:26 -0400 | [diff] [blame] | 10 | struct argv_array args; |
René Scharfe | 19a583d | 2014-10-19 13:13:55 +0200 | [diff] [blame] | 11 | struct argv_array env_array; |
Shawn O. Pearce | ebcb5d1 | 2007-03-10 03:28:05 -0500 | [diff] [blame] | 12 | pid_t pid; |
Jeff Hostetler | ee4512e | 2019-02-22 14:25:01 -0800 | [diff] [blame] | 13 | |
| 14 | int trace2_child_id; |
| 15 | uint64_t trace2_child_us_start; |
| 16 | const char *trace2_child_class; |
| 17 | const char *trace2_hook_name; |
| 18 | |
Johannes Sixt | c20181e | 2008-02-21 23:42:56 +0100 | [diff] [blame] | 19 | /* |
| 20 | * Using .in, .out, .err: |
| 21 | * - Specify 0 for no redirections (child inherits stdin, stdout, |
| 22 | * stderr from parent). |
| 23 | * - Specify -1 to have a pipe allocated as follows: |
| 24 | * .in: returns the writable pipe end; parent writes to it, |
| 25 | * the readable pipe end becomes child's stdin |
| 26 | * .out, .err: returns the readable pipe end; parent reads from |
| 27 | * it, the writable pipe end becomes child's stdout/stderr |
| 28 | * The caller of start_command() must close the returned FDs |
| 29 | * after it has completed reading from/writing to it! |
| 30 | * - Specify > 0 to set a channel to a particular FD as follows: |
| 31 | * .in: a readable FD, becomes child's stdin |
| 32 | * .out: a writable FD, becomes child's stdout/stderr |
Shawn O. Pearce | 4f41b61 | 2010-02-05 12:57:37 -0800 | [diff] [blame] | 33 | * .err: a writable FD, becomes child's stderr |
Johannes Sixt | c20181e | 2008-02-21 23:42:56 +0100 | [diff] [blame] | 34 | * The specified FD is closed by start_command(), even in case |
| 35 | * of errors! |
| 36 | */ |
Shawn O. Pearce | 4919bf0 | 2007-03-10 03:28:08 -0500 | [diff] [blame] | 37 | int in; |
Shawn O. Pearce | f4bba25 | 2007-03-12 14:37:45 -0400 | [diff] [blame] | 38 | int out; |
Johannes Sixt | f3b33f1 | 2007-10-19 21:47:58 +0200 | [diff] [blame] | 39 | int err; |
Alex Riesen | 1568fea | 2007-05-22 23:48:23 +0200 | [diff] [blame] | 40 | const char *dir; |
Alex Riesen | ee49314 | 2007-05-22 23:48:47 +0200 | [diff] [blame] | 41 | const char *const *env; |
Shawn O. Pearce | f100089 | 2007-03-10 03:28:00 -0500 | [diff] [blame] | 42 | unsigned no_stdin:1; |
Shawn O. Pearce | e4507ae | 2007-03-12 14:37:55 -0400 | [diff] [blame] | 43 | unsigned no_stdout:1; |
Shawn O. Pearce | b73a439 | 2007-11-11 02:29:37 -0500 | [diff] [blame] | 44 | unsigned no_stderr:1; |
Shawn O. Pearce | f100089 | 2007-03-10 03:28:00 -0500 | [diff] [blame] | 45 | unsigned git_cmd:1; /* if this is to be git sub-command */ |
Johannes Sixt | c024beb | 2009-07-04 21:26:42 +0200 | [diff] [blame] | 46 | unsigned silent_exec_failure:1; |
Shawn O. Pearce | f100089 | 2007-03-10 03:28:00 -0500 | [diff] [blame] | 47 | unsigned stdout_to_stderr:1; |
Jeff King | 8dba1e6 | 2009-12-30 05:53:16 -0500 | [diff] [blame] | 48 | unsigned use_shell:1; |
Jeff King | afe19ff | 2012-01-07 12:42:43 +0100 | [diff] [blame] | 49 | unsigned clean_on_exit:1; |
Jeff King | 46df690 | 2017-01-06 20:22:23 -0500 | [diff] [blame] | 50 | unsigned wait_after_clean:1; |
Lars Schneider | ac2fbaa | 2016-10-16 16:20:28 -0700 | [diff] [blame] | 51 | void (*clean_on_exit_handler)(struct child_process *process); |
| 52 | void *clean_on_exit_handler_cbdata; |
Shawn O. Pearce | f100089 | 2007-03-10 03:28:00 -0500 | [diff] [blame] | 53 | }; |
| 54 | |
René Scharfe | 19a583d | 2014-10-19 13:13:55 +0200 | [diff] [blame] | 55 | #define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT, ARGV_ARRAY_INIT } |
René Scharfe | 483bbd4 | 2014-08-19 21:10:48 +0200 | [diff] [blame] | 56 | void child_process_init(struct child_process *); |
René Scharfe | 2d71608 | 2015-10-24 14:11:27 +0200 | [diff] [blame] | 57 | void child_process_clear(struct child_process *); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 58 | int is_executable(const char *name); |
René Scharfe | d318027 | 2014-08-19 21:09:35 +0200 | [diff] [blame] | 59 | |
Shawn O. Pearce | ebcb5d1 | 2007-03-10 03:28:05 -0500 | [diff] [blame] | 60 | int start_command(struct child_process *); |
| 61 | int finish_command(struct child_process *); |
Takashi Iwai | 507d780 | 2015-09-04 11:35:57 +0200 | [diff] [blame] | 62 | int finish_command_in_signal(struct child_process *); |
Shawn O. Pearce | f100089 | 2007-03-10 03:28:00 -0500 | [diff] [blame] | 63 | int run_command(struct child_process *); |
| 64 | |
Jeff King | 03f2c77 | 2015-08-10 05:37:45 -0400 | [diff] [blame] | 65 | /* |
| 66 | * Returns the path to the hook file, or NULL if the hook is missing |
| 67 | * or disabled. Note that this points to static storage that will be |
| 68 | * overwritten by further calls to find_hook and run_hook_*. |
| 69 | */ |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 70 | const char *find_hook(const char *name); |
Ramsay Jones | 9fe3edc | 2013-07-18 21:02:12 +0100 | [diff] [blame] | 71 | LAST_ARG_MUST_BE_NULL |
Denton Liu | b199d71 | 2019-04-29 04:28:20 -0400 | [diff] [blame] | 72 | int run_hook_le(const char *const *env, const char *name, ...); |
Denton Liu | 5545442 | 2019-04-29 04:28:14 -0400 | [diff] [blame] | 73 | int run_hook_ve(const char *const *env, const char *name, va_list args); |
Benoit Pierre | 15048f8 | 2014-03-18 11:00:53 +0100 | [diff] [blame] | 74 | |
Shawn O. Pearce | 95d3c4f | 2006-12-30 21:55:22 -0500 | [diff] [blame] | 75 | #define RUN_COMMAND_NO_STDIN 1 |
Michal Ostrowski | 77cb17e | 2006-01-10 21:12:17 -0500 | [diff] [blame] | 76 | #define RUN_GIT_CMD 2 /*If this is to be git sub-command */ |
Shawn O. Pearce | cd83c74 | 2006-12-30 21:55:19 -0500 | [diff] [blame] | 77 | #define RUN_COMMAND_STDOUT_TO_STDERR 4 |
Johannes Sixt | c024beb | 2009-07-04 21:26:42 +0200 | [diff] [blame] | 78 | #define RUN_SILENT_EXEC_FAILURE 8 |
Jeff King | 8dba1e6 | 2009-12-30 05:53:16 -0500 | [diff] [blame] | 79 | #define RUN_USING_SHELL 16 |
Clemens Buchacher | 10c6cdd | 2012-01-08 21:41:09 +0100 | [diff] [blame] | 80 | #define RUN_CLEAN_ON_EXIT 32 |
Shawn O. Pearce | 9b0b509 | 2006-12-30 21:55:15 -0500 | [diff] [blame] | 81 | int run_command_v_opt(const char **argv, int opt); |
Jeff Hostetler | ee4512e | 2019-02-22 14:25:01 -0800 | [diff] [blame] | 82 | int run_command_v_opt_tr2(const char **argv, int opt, const char *tr2_class); |
Alex Riesen | 3427b37 | 2007-05-23 22:21:39 +0200 | [diff] [blame] | 83 | /* |
| 84 | * env (the environment) is to be formatted like environ: "VAR=VALUE". |
| 85 | * To unset an environment variable use just "VAR". |
| 86 | */ |
Alex Riesen | ee49314 | 2007-05-22 23:48:47 +0200 | [diff] [blame] | 87 | int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env); |
Jeff Hostetler | ee4512e | 2019-02-22 14:25:01 -0800 | [diff] [blame] | 88 | int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir, |
| 89 | const char *const *env, const char *tr2_class); |
Josef Weidendorfer | b1bf95b | 2005-07-31 21:17:43 +0200 | [diff] [blame] | 90 | |
Jeff King | 911ec99 | 2015-03-22 23:53:43 -0400 | [diff] [blame] | 91 | /** |
Jeff King | 96335bc | 2016-06-17 19:38:47 -0400 | [diff] [blame] | 92 | * Execute the given command, sending "in" to its stdin, and capturing its |
| 93 | * stdout and stderr in the "out" and "err" strbufs. Any of the three may |
| 94 | * be NULL to skip processing. |
| 95 | * |
Jeff King | 911ec99 | 2015-03-22 23:53:43 -0400 | [diff] [blame] | 96 | * Returns -1 if starting the command fails or reading fails, and otherwise |
Jeff King | 96335bc | 2016-06-17 19:38:47 -0400 | [diff] [blame] | 97 | * returns the exit code of the command. Any output collected in the |
| 98 | * buffers is kept even if the command returns a non-zero exit. The hint fields |
| 99 | * gives starting sizes for the strbuf allocations. |
Jeff King | 911ec99 | 2015-03-22 23:53:43 -0400 | [diff] [blame] | 100 | * |
| 101 | * The fields of "cmd" should be set up as they would for a normal run_command |
Jeff King | 96335bc | 2016-06-17 19:38:47 -0400 | [diff] [blame] | 102 | * invocation. But note that there is no need to set the in, out, or err |
| 103 | * fields; pipe_command handles that automatically. |
Jeff King | 911ec99 | 2015-03-22 23:53:43 -0400 | [diff] [blame] | 104 | */ |
Jeff King | 96335bc | 2016-06-17 19:38:47 -0400 | [diff] [blame] | 105 | int pipe_command(struct child_process *cmd, |
| 106 | const char *in, size_t in_len, |
| 107 | struct strbuf *out, size_t out_hint, |
| 108 | struct strbuf *err, size_t err_hint); |
| 109 | |
| 110 | /** |
| 111 | * Convenience wrapper around pipe_command for the common case |
| 112 | * of capturing only stdout. |
| 113 | */ |
| 114 | static inline int capture_command(struct child_process *cmd, |
| 115 | struct strbuf *out, |
| 116 | size_t hint) |
| 117 | { |
| 118 | return pipe_command(cmd, NULL, 0, out, hint, NULL, 0); |
| 119 | } |
Jeff King | 911ec99 | 2015-03-22 23:53:43 -0400 | [diff] [blame] | 120 | |
Johannes Sixt | 2d22c20 | 2007-10-19 21:48:00 +0200 | [diff] [blame] | 121 | /* |
| 122 | * The purpose of the following functions is to feed a pipe by running |
| 123 | * a function asynchronously and providing output that the caller reads. |
| 124 | * |
| 125 | * It is expected that no synchronization and mutual exclusion between |
| 126 | * the caller and the feed function is necessary so that the function |
| 127 | * can run in a thread without interfering with the caller. |
| 128 | */ |
| 129 | struct async { |
| 130 | /* |
Erik Faye-Lund | ae6a560 | 2010-02-05 12:57:38 -0800 | [diff] [blame] | 131 | * proc reads from in; closes it before return |
| 132 | * proc writes to out; closes it before return |
Johannes Sixt | 2d22c20 | 2007-10-19 21:48:00 +0200 | [diff] [blame] | 133 | * returns 0 on success, non-zero on failure |
| 134 | */ |
Erik Faye-Lund | ae6a560 | 2010-02-05 12:57:38 -0800 | [diff] [blame] | 135 | int (*proc)(int in, int out, void *data); |
Johannes Sixt | 2d22c20 | 2007-10-19 21:48:00 +0200 | [diff] [blame] | 136 | void *data; |
Erik Faye-Lund | ae6a560 | 2010-02-05 12:57:38 -0800 | [diff] [blame] | 137 | int in; /* caller writes here and closes it */ |
Johannes Sixt | 2d22c20 | 2007-10-19 21:48:00 +0200 | [diff] [blame] | 138 | int out; /* caller reads from here and closes it */ |
Johannes Sixt | f6b6098 | 2010-03-09 21:00:36 +0100 | [diff] [blame] | 139 | #ifdef NO_PTHREADS |
Johannes Sixt | 2d22c20 | 2007-10-19 21:48:00 +0200 | [diff] [blame] | 140 | pid_t pid; |
Johannes Sixt | 618ebe9 | 2007-12-08 22:19:14 +0100 | [diff] [blame] | 141 | #else |
Johannes Sixt | 200a76b | 2010-03-06 16:40:42 +0100 | [diff] [blame] | 142 | pthread_t tid; |
Erik Faye-Lund | ae6a560 | 2010-02-05 12:57:38 -0800 | [diff] [blame] | 143 | int proc_in; |
| 144 | int proc_out; |
Johannes Sixt | 618ebe9 | 2007-12-08 22:19:14 +0100 | [diff] [blame] | 145 | #endif |
Jeff King | c792d7b | 2016-04-19 18:49:41 -0400 | [diff] [blame] | 146 | int isolate_sigpipe; |
Johannes Sixt | 2d22c20 | 2007-10-19 21:48:00 +0200 | [diff] [blame] | 147 | }; |
| 148 | |
| 149 | int start_async(struct async *async); |
| 150 | int finish_async(struct async *async); |
Jeff King | 661a8cf | 2015-09-01 16:22:43 -0400 | [diff] [blame] | 151 | int in_async(void); |
Nguyễn Thái Ngọc Duy | c0e40a2 | 2018-11-03 09:48:39 +0100 | [diff] [blame] | 152 | int async_with_fork(void); |
Lars Schneider | b992fe1 | 2016-10-16 16:20:27 -0700 | [diff] [blame] | 153 | void check_pipe(int err); |
Johannes Sixt | 2d22c20 | 2007-10-19 21:48:00 +0200 | [diff] [blame] | 154 | |
Stefan Beller | c553c72 | 2015-12-15 16:04:10 -0800 | [diff] [blame] | 155 | /** |
| 156 | * This callback should initialize the child process and preload the |
| 157 | * error channel if desired. The preloading of is useful if you want to |
| 158 | * have a message printed directly before the output of the child process. |
| 159 | * pp_cb is the callback cookie as passed to run_processes_parallel. |
| 160 | * You can store a child process specific callback cookie in pp_task_cb. |
| 161 | * |
| 162 | * Even after returning 0 to indicate that there are no more processes, |
| 163 | * this function will be called again until there are no more running |
| 164 | * child processes. |
| 165 | * |
| 166 | * Return 1 if the next child is ready to run. |
| 167 | * Return 0 if there are currently no more tasks to be processed. |
| 168 | * To send a signal to other child processes for abortion, |
| 169 | * return the negative signal number. |
| 170 | */ |
| 171 | typedef int (*get_next_task_fn)(struct child_process *cp, |
Stefan Beller | aa71049 | 2016-02-29 18:07:16 -0800 | [diff] [blame] | 172 | struct strbuf *out, |
Stefan Beller | c553c72 | 2015-12-15 16:04:10 -0800 | [diff] [blame] | 173 | void *pp_cb, |
| 174 | void **pp_task_cb); |
| 175 | |
| 176 | /** |
| 177 | * This callback is called whenever there are problems starting |
| 178 | * a new process. |
| 179 | * |
| 180 | * You must not write to stdout or stderr in this function. Add your |
Stefan Beller | aa71049 | 2016-02-29 18:07:16 -0800 | [diff] [blame] | 181 | * message to the strbuf out instead, which will be printed without |
Stefan Beller | c553c72 | 2015-12-15 16:04:10 -0800 | [diff] [blame] | 182 | * messing up the output of the other parallel processes. |
| 183 | * |
| 184 | * pp_cb is the callback cookie as passed into run_processes_parallel, |
| 185 | * pp_task_cb is the callback cookie as passed into get_next_task_fn. |
| 186 | * |
| 187 | * Return 0 to continue the parallel processing. To abort return non zero. |
| 188 | * To send a signal to other child processes for abortion, return |
| 189 | * the negative signal number. |
| 190 | */ |
Stefan Beller | aa71049 | 2016-02-29 18:07:16 -0800 | [diff] [blame] | 191 | typedef int (*start_failure_fn)(struct strbuf *out, |
Stefan Beller | c553c72 | 2015-12-15 16:04:10 -0800 | [diff] [blame] | 192 | void *pp_cb, |
| 193 | void *pp_task_cb); |
| 194 | |
| 195 | /** |
| 196 | * This callback is called on every child process that finished processing. |
| 197 | * |
| 198 | * You must not write to stdout or stderr in this function. Add your |
Stefan Beller | aa71049 | 2016-02-29 18:07:16 -0800 | [diff] [blame] | 199 | * message to the strbuf out instead, which will be printed without |
Stefan Beller | c553c72 | 2015-12-15 16:04:10 -0800 | [diff] [blame] | 200 | * messing up the output of the other parallel processes. |
| 201 | * |
| 202 | * pp_cb is the callback cookie as passed into run_processes_parallel, |
| 203 | * pp_task_cb is the callback cookie as passed into get_next_task_fn. |
| 204 | * |
| 205 | * Return 0 to continue the parallel processing. To abort return non zero. |
| 206 | * To send a signal to other child processes for abortion, return |
| 207 | * the negative signal number. |
| 208 | */ |
| 209 | typedef int (*task_finished_fn)(int result, |
Stefan Beller | aa71049 | 2016-02-29 18:07:16 -0800 | [diff] [blame] | 210 | struct strbuf *out, |
Stefan Beller | c553c72 | 2015-12-15 16:04:10 -0800 | [diff] [blame] | 211 | void *pp_cb, |
| 212 | void *pp_task_cb); |
| 213 | |
| 214 | /** |
| 215 | * Runs up to n processes at the same time. Whenever a process can be |
| 216 | * started, the callback get_next_task_fn is called to obtain the data |
| 217 | * required to start another child process. |
| 218 | * |
| 219 | * The children started via this function run in parallel. Their output |
| 220 | * (both stdout and stderr) is routed to stderr in a manner that output |
| 221 | * from different tasks does not interleave. |
| 222 | * |
Stefan Beller | 2a73b3d | 2016-02-29 13:57:06 -0800 | [diff] [blame] | 223 | * start_failure_fn and task_finished_fn can be NULL to omit any |
| 224 | * special handling. |
Stefan Beller | c553c72 | 2015-12-15 16:04:10 -0800 | [diff] [blame] | 225 | */ |
| 226 | int run_processes_parallel(int n, |
| 227 | get_next_task_fn, |
| 228 | start_failure_fn, |
| 229 | task_finished_fn, |
| 230 | void *pp_cb); |
Jeff Hostetler | ee4512e | 2019-02-22 14:25:01 -0800 | [diff] [blame] | 231 | int run_processes_parallel_tr2(int n, get_next_task_fn, start_failure_fn, |
| 232 | task_finished_fn, void *pp_cb, |
| 233 | const char *tr2_category, const char *tr2_label); |
Stefan Beller | c553c72 | 2015-12-15 16:04:10 -0800 | [diff] [blame] | 234 | |
Josef Weidendorfer | b1bf95b | 2005-07-31 21:17:43 +0200 | [diff] [blame] | 235 | #endif |