| Josef Weidendorfer | b1bf95b | 2005-07-31 19:17:43 | [diff] [blame] | 1 | #ifndef RUN_COMMAND_H |
| 2 | #define RUN_COMMAND_H |
| 3 | |
| Josef Weidendorfer | b1bf95b | 2005-07-31 19:17:43 | [diff] [blame] | 4 | enum { |
| 5 | ERR_RUN_COMMAND_FORK = 10000, |
| 6 | ERR_RUN_COMMAND_EXEC, |
| Shawn O. Pearce | 4919bf0 | 2007-03-10 08:28:08 | [diff] [blame] | 7 | ERR_RUN_COMMAND_PIPE, |
| Josef Weidendorfer | b1bf95b | 2005-07-31 19:17:43 | [diff] [blame] | 8 | ERR_RUN_COMMAND_WAITPID, |
| 9 | ERR_RUN_COMMAND_WAITPID_WRONG_PID, |
| 10 | ERR_RUN_COMMAND_WAITPID_SIGNAL, |
| 11 | ERR_RUN_COMMAND_WAITPID_NOEXIT, |
| 12 | }; |
| Jeff King | fd94836 | 2009-03-31 12:29:23 | [diff] [blame] | 13 | #define IS_RUN_COMMAND_ERR(x) (-(x) >= ERR_RUN_COMMAND_FORK) |
| Josef Weidendorfer | b1bf95b | 2005-07-31 19:17:43 | [diff] [blame] | 14 | |
| Shawn O. Pearce | f100089 | 2007-03-10 08:28:00 | [diff] [blame] | 15 | struct child_process { |
| 16 | const char **argv; |
| Shawn O. Pearce | ebcb5d1 | 2007-03-10 08:28:05 | [diff] [blame] | 17 | pid_t pid; |
| Johannes Sixt | c20181e | 2008-02-21 22:42:56 | [diff] [blame] | 18 | /* |
| 19 | * Using .in, .out, .err: |
| 20 | * - Specify 0 for no redirections (child inherits stdin, stdout, |
| 21 | * stderr from parent). |
| 22 | * - Specify -1 to have a pipe allocated as follows: |
| 23 | * .in: returns the writable pipe end; parent writes to it, |
| 24 | * the readable pipe end becomes child's stdin |
| 25 | * .out, .err: returns the readable pipe end; parent reads from |
| 26 | * it, the writable pipe end becomes child's stdout/stderr |
| 27 | * The caller of start_command() must close the returned FDs |
| 28 | * after it has completed reading from/writing to it! |
| 29 | * - Specify > 0 to set a channel to a particular FD as follows: |
| 30 | * .in: a readable FD, becomes child's stdin |
| 31 | * .out: a writable FD, becomes child's stdout/stderr |
| 32 | * .err > 0 not supported |
| 33 | * The specified FD is closed by start_command(), even in case |
| 34 | * of errors! |
| 35 | */ |
| Shawn O. Pearce | 4919bf0 | 2007-03-10 08:28:08 | [diff] [blame] | 36 | int in; |
| Shawn O. Pearce | f4bba25 | 2007-03-12 18:37:45 | [diff] [blame] | 37 | int out; |
| Johannes Sixt | f3b33f1 | 2007-10-19 19:47:58 | [diff] [blame] | 38 | int err; |
| Alex Riesen | 1568fea | 2007-05-22 21:48:23 | [diff] [blame] | 39 | const char *dir; |
| Alex Riesen | ee49314 | 2007-05-22 21:48:47 | [diff] [blame] | 40 | const char *const *env; |
| Shawn O. Pearce | f100089 | 2007-03-10 08:28:00 | [diff] [blame] | 41 | unsigned no_stdin:1; |
| Shawn O. Pearce | e4507ae | 2007-03-12 18:37:55 | [diff] [blame] | 42 | unsigned no_stdout:1; |
| Shawn O. Pearce | b73a439 | 2007-11-11 07:29:37 | [diff] [blame] | 43 | unsigned no_stderr:1; |
| Shawn O. Pearce | f100089 | 2007-03-10 08:28:00 | [diff] [blame] | 44 | unsigned git_cmd:1; /* if this is to be git sub-command */ |
| 45 | unsigned stdout_to_stderr:1; |
| Jeff King | ccf08bc | 2008-07-22 07:12:46 | [diff] [blame] | 46 | void (*preexec_cb)(void); |
| Shawn O. Pearce | f100089 | 2007-03-10 08:28:00 | [diff] [blame] | 47 | }; |
| 48 | |
| Shawn O. Pearce | ebcb5d1 | 2007-03-10 08:28:05 | [diff] [blame] | 49 | int start_command(struct child_process *); |
| 50 | int finish_command(struct child_process *); |
| Shawn O. Pearce | f100089 | 2007-03-10 08:28:00 | [diff] [blame] | 51 | int run_command(struct child_process *); |
| 52 | |
| Stephan Beyer | ae98a00 | 2009-01-16 19:09:59 | [diff] [blame] | 53 | extern int run_hook(const char *index_file, const char *name, ...); |
| 54 | |
| Shawn O. Pearce | 95d3c4f | 2006-12-31 02:55:22 | [diff] [blame] | 55 | #define RUN_COMMAND_NO_STDIN 1 |
| Michal Ostrowski | 77cb17e | 2006-01-11 02:12:17 | [diff] [blame] | 56 | #define RUN_GIT_CMD 2 /*If this is to be git sub-command */ |
| Shawn O. Pearce | cd83c74 | 2006-12-31 02:55:19 | [diff] [blame] | 57 | #define RUN_COMMAND_STDOUT_TO_STDERR 4 |
| Shawn O. Pearce | 9b0b509 | 2006-12-31 02:55:15 | [diff] [blame] | 58 | int run_command_v_opt(const char **argv, int opt); |
| Alex Riesen | 3427b37 | 2007-05-23 20:21:39 | [diff] [blame] | 59 | |
| 60 | /* |
| 61 | * env (the environment) is to be formatted like environ: "VAR=VALUE". |
| 62 | * To unset an environment variable use just "VAR". |
| 63 | */ |
| Alex Riesen | ee49314 | 2007-05-22 21:48:47 | [diff] [blame] | 64 | int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env); |
| Josef Weidendorfer | b1bf95b | 2005-07-31 19:17:43 | [diff] [blame] | 65 | |
| Johannes Sixt | 2d22c20 | 2007-10-19 19:48:00 | [diff] [blame] | 66 | /* |
| 67 | * The purpose of the following functions is to feed a pipe by running |
| 68 | * a function asynchronously and providing output that the caller reads. |
| 69 | * |
| 70 | * It is expected that no synchronization and mutual exclusion between |
| 71 | * the caller and the feed function is necessary so that the function |
| 72 | * can run in a thread without interfering with the caller. |
| 73 | */ |
| 74 | struct async { |
| 75 | /* |
| 76 | * proc writes to fd and closes it; |
| 77 | * returns 0 on success, non-zero on failure |
| 78 | */ |
| 79 | int (*proc)(int fd, void *data); |
| 80 | void *data; |
| 81 | int out; /* caller reads from here and closes it */ |
| Johannes Sixt | 618ebe9 | 2007-12-08 21:19:14 | [diff] [blame] | 82 | #ifndef __MINGW32__ |
| Johannes Sixt | 2d22c20 | 2007-10-19 19:48:00 | [diff] [blame] | 83 | pid_t pid; |
| Johannes Sixt | 618ebe9 | 2007-12-08 21:19:14 | [diff] [blame] | 84 | #else |
| 85 | HANDLE tid; |
| 86 | int fd_for_proc; |
| 87 | #endif |
| Johannes Sixt | 2d22c20 | 2007-10-19 19:48:00 | [diff] [blame] | 88 | }; |
| 89 | |
| 90 | int start_async(struct async *async); |
| 91 | int finish_async(struct async *async); |
| 92 | |
| Josef Weidendorfer | b1bf95b | 2005-07-31 19:17:43 | [diff] [blame] | 93 | #endif |