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