summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2023-03-27 17:31:51 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2023-05-17 13:11:46 +0100
commit5e75cac9fa7bf9c7bd4141c3f2a56b7c3c2a3101 (patch)
treec9a3fac3c4f7429f332c526e6bea0ba2b2b6b42b
parent8d63fa36b4f411ced93b996a4ce270a06a0a9591 (diff)
downloadlibgit2-5e75cac9fa7bf9c7bd4141c3f2a56b7c3c2a3101.tar.gz
process: test SIGTERM detection
We can't reliably detect SIGPIPE on close because of platform differences. Track `pid` and send `SIGTERM` to a function and ensure that we can detect it.
-rw-r--r--src/util/process.h15
-rw-r--r--src/util/unix/process.c13
-rw-r--r--src/util/win32/process.c13
-rw-r--r--tests/util/process/start.c39
4 files changed, 79 insertions, 1 deletions
diff --git a/src/util/process.h b/src/util/process.h
index 59ea52d91..0f8bc2269 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
@@ -81,6 +87,15 @@ extern int git_process__cmdline(
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 16171aec9..3d734ffb5 100644
--- a/src/util/unix/process.c
+++ b/src/util/unix/process.c
@@ -356,6 +356,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 6a1dd658c..d29969dd3 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_info.dwProcessId) {
+ git_error_set(GIT_ERROR_INVALID, "process not running");
+ return -1;
+ }
+
+ *out = process->process_info.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..f7a34c0e2 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,9 +138,38 @@ 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[] = { "/bin/cat" };
+
+ 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;