Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
fix: properly terminate on SIGINT during fetch
Baptiste Daroussin committed 2 months ago
commit 42705067bdd597d5ecea3194e2eacecfebd4b9d3
parent c410105
2 files changed +24 -8
modified src/event.c
@@ -91,19 +91,24 @@ static const char *unit_SI[] = { " ", "k", "M", "G", "T", };
static void draw_progressbar(int64_t current, int64_t total);

static void
-
cleanup_handler(int dummy __unused)
+
cleanup_handler(int sig)
{
	static const char msg[] = "\nsignal received, cleaning up\n";
	struct cleanup *ev;

-
	if (cleanup_list.len == 0)
-
		_exit(1);
+
	if (cleanup_list.len == 0) {
+
		signal(sig, SIG_DFL);
+
		kill(getpid(), sig);
+
		_exit(128 + sig);
+
	}
	write(STDERR_FILENO, msg, sizeof(msg) - 1);
	vec_foreach(cleanup_list, i) {
		ev = cleanup_list.d[i];
		ev->cb(ev->data);
	}
-
	_exit(1);
+
	signal(sig, SIG_DFL);
+
	kill(getpid(), sig);
+
	_exit(128 + sig);
}

static void
modified src/main.c
@@ -402,20 +402,31 @@ start_process_worker(char *const *save_argv)
			if (child_pid == -1)
				err(EXIT_FAILURE, "Failed to fork worker process");

+
			/*
+
			 * Ignore SIGINT in the parent while the child
+
			 * is running: the child will handle it and we
+
			 * just need to collect its exit status.
+
			 */
+
			signal(SIGINT, SIG_IGN);
			while (waitpid(child_pid, &status, 0) == -1) {
				if (errno != EINTR)
					err(EXIT_FAILURE, "Child process pid=%d", (int)child_pid);
			}
+
			signal(SIGINT, SIG_DFL);

			ret = WEXITSTATUS(status);

			if (WIFEXITED(status) && ret != EX_NEEDRESTART)
				break;
			if (WIFSIGNALED(status)) {
-
				/* Process got some terminating signal, hence stop the loop */
-
				fprintf(stderr, "Child process pid=%d terminated abnormally: %s\n",
-
						(int)child_pid, strsignal (WTERMSIG(status)));
-
				ret = 128 + WTERMSIG(status);
+
				int sig = WTERMSIG(status);
+
				/*
+
				 * Re-signal ourselves so the parent shell
+
				 * sees the correct wait status instead of
+
				 * pkg appearing to continue in the background.
+
				 */
+
				signal(sig, SIG_DFL);
+
				kill(getpid(), sig);
				break;
			}
		}