diff options
-rw-r--r-- | src/util/process.h | 15 | ||||
-rw-r--r-- | src/util/unix/process.c | 13 | ||||
-rw-r--r-- | src/util/win32/process.c | 13 | ||||
-rw-r--r-- | tests/util/process/start.c | 39 |
4 files changed, 79 insertions, 1 deletions
diff --git a/src/util/process.h b/src/util/process.h index 58c265430..595a0da3b 100644 --- a/src/util/process.h +++ b/src/util/process.h @@ -35,6 +35,12 @@ typedef struct { #define GIT_PROCESS_OPTIONS_INIT { 0 } +#ifdef GIT_WIN32 +# define p_pid_t DWORD +#else +# define p_pid_t pid_t +#endif + /** * Create a new process. The command to run should be specified as the * element of the `arg` array. If `setup_pipe` is true, then this @@ -71,6 +77,15 @@ extern int git_process_new( extern int git_process_start(git_process *process); /** + * Returns the process id of the process. + * + * @param out pointer to a pid_t to store the process id + * @param process the process to query + * @return 0 or an error code + */ +extern int git_process_id(p_pid_t *out, git_process *process); + +/** * Read from the process's stdout. The process must have been created with * `capture_out` set to true. * diff --git a/src/util/unix/process.c b/src/util/unix/process.c index b5e259977..ce28705a9 100644 --- a/src/util/unix/process.c +++ b/src/util/unix/process.c @@ -422,6 +422,19 @@ on_error: return -1; } +int git_process_id(p_pid_t *out, git_process *process) +{ + GIT_ASSERT(out && process); + + if (!process->pid) { + git_error_set(GIT_ERROR_INVALID, "process not running"); + return -1; + } + + *out = process->pid; + return 0; +} + ssize_t git_process_read(git_process *process, void *buf, size_t count) { ssize_t ret; diff --git a/src/util/win32/process.c b/src/util/win32/process.c index 092422d12..cda9b8dab 100644 --- a/src/util/win32/process.c +++ b/src/util/win32/process.c @@ -288,6 +288,19 @@ on_error: return -1; } +int git_process_id(p_pid_t *out, git_process *process) +{ + GIT_ASSERT(out && process); + + if (!process->process_information.dwProcessId) { + git_error_set(GIT_ERROR_INVALID, "process not running"); + return -1; + } + + *out = process->process_information.dwProcessId; + return 0; +} + ssize_t git_process_read(git_process *process, void *buf, size_t count) { DWORD ret; diff --git a/tests/util/process/start.c b/tests/util/process/start.c index cb43bf746..5de908776 100644 --- a/tests/util/process/start.c +++ b/tests/util/process/start.c @@ -2,6 +2,14 @@ #include "process.h" #include "vector.h" +#ifndef GIT_WIN32 +# include <signal.h> +#endif + +#ifndef SIGTERM +# define SIGTERM 42 +#endif + #ifndef SIGPIPE # define SIGPIPE 42 #endif @@ -130,7 +138,7 @@ void test_process_start__redirect_stdio(void) git_process_free(process); } -void test_process_start__catch_signal(void) +void test_process_start__catch_sigterm(void) { #ifndef GIT_WIN32 const char *args_array[] = { helloworld_cmd.ptr }; @@ -138,6 +146,35 @@ void test_process_start__catch_signal(void) git_process *process; git_process_options opts = GIT_PROCESS_OPTIONS_INIT; git_process_result result = GIT_PROCESS_RESULT_INIT; + p_pid_t pid; + + opts.capture_out = 1; + + cl_git_pass(git_process_new(&process, args_array, ARRAY_SIZE(args_array), NULL, 0, &opts)); + cl_git_pass(git_process_start(process)); + cl_git_pass(git_process_id(&pid, process)); + + cl_must_pass(kill(pid, SIGTERM)); + + cl_git_pass(git_process_wait(&result, process)); + + cl_assert_equal_i(GIT_PROCESS_STATUS_ERROR, result.status); + cl_assert_equal_i(0, result.exitcode); + cl_assert_equal_i(SIGTERM, result.signal); + + git_process_free(process); +#endif +} + +void test_process_start__catch_sigpipe(void) +{ + /* macOS SIGPIPEs here, but not every OS does. */ +#ifdef __APPLE__ + const char *args_array[] = { helloworld_cmd.ptr }; + + git_process *process; + git_process_options opts = GIT_PROCESS_OPTIONS_INIT; + git_process_result result = GIT_PROCESS_RESULT_INIT; opts.capture_out = 1; |