summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2023-03-27 17:31:51 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2023-04-11 10:18:16 +0100
commitb9aa10efcb03c08a4a655ea2b5559bb069de3fb1 (patch)
treefdffd9f1ab006a58a0208e160887954b75baf721
parent8b6d910d330394f2480e3e17dd3eb58685c78768 (diff)
downloadlibgit2-b9aa10efcb03c08a4a655ea2b5559bb069de3fb1.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 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;