commit a74240b311a442acedb186d30f70edfe847de213 from: isaac date: Sat Jun 27 00:48:39 2026 UTC regress: tear down child processes on timeout instead of orphaning chat_test and compact_test fork a stub TLS server + the full fugu, then set alarm(90). on_alarm only _exit(97)d, orphaning both children -- the stub has no timeout of its own and blocks forever in accept()/tls_read(), so every stalled run leaked processes that ran until killed by hand. Track the child pids and SIGKILL them from on_alarm before exiting; also give the stub child its own alarm(60) + default SIGALRM so it self-terminates if orphaned by any other path. Verified: a forced stall (FUGU_BIN=/bin/cat) now leaves no live orphans. commit - c359dadcc35ab09cd72a45d0e87d4e5971efdb5b commit + a74240b311a442acedb186d30f70edfe847de213 blob - e1ae12a6ec0886e822d476c1a5790cde4d563aeb blob + 9eed4da39c55a42fc7a9ac987a817224725ab712 --- regress/chat/chat_test.c +++ regress/chat/chat_test.c @@ -193,11 +193,19 @@ write_config(const char *home) fclose(fp); } +/* Child pids, so the timeout handler can tear them down instead of orphaning. */ +static volatile sig_atomic_t stub_pid = -1; +static volatile sig_atomic_t fugu_pid = -1; + static void on_alarm(int sig) { (void)sig; dprintf(STDERR_FILENO, "chat_test: TIMED OUT\n"); + if (fugu_pid > 0) + kill((pid_t)fugu_pid, SIGKILL); + if (stub_pid > 0) + kill((pid_t)stub_pid, SIGKILL); _exit(97); } @@ -248,9 +256,12 @@ main(int argc, char *argv[]) if ((sp = fork()) == -1) err(1, "fork"); if (sp == 0) { + signal(SIGALRM, SIG_DFL); /* self-terminate if we block */ + alarm(60); stub_server(lfd, argv[1], argv[2]); _exit(0); } + stub_pid = sp; close(lfd); if (pipe(in_pipe) == -1 || pipe(out_pipe) == -1) @@ -279,6 +290,7 @@ main(int argc, char *argv[]) execl(fugu_bin, fugu_bin, (char *)NULL); _exit(127); } + fugu_pid = fp; close(in_pipe[0]); close(out_pipe[1]); blob - 38bf6abb445f3e36e9c450325af2af19a4317b52 blob + a63a5886ae0201616fa6f418980de563dc589aa8 --- regress/compact/compact_test.c +++ regress/compact/compact_test.c @@ -240,11 +240,19 @@ rm_sessions(const char *home) rmdir(path); } +/* Child pids, so the timeout handler can tear them down instead of orphaning. */ +static volatile sig_atomic_t stub_pid = -1; +static volatile sig_atomic_t fugu_pid = -1; + static void on_alarm(int sig) { (void)sig; dprintf(STDERR_FILENO, "compact_test: TIMED OUT\n"); + if (fugu_pid > 0) + kill((pid_t)fugu_pid, SIGKILL); + if (stub_pid > 0) + kill((pid_t)stub_pid, SIGKILL); _exit(97); } @@ -311,9 +319,12 @@ main(int argc, char *argv[]) if ((sp = fork()) == -1) err(1, "fork"); if (sp == 0) { + signal(SIGALRM, SIG_DFL); /* self-terminate if we block */ + alarm(60); stub_server(lfd, argv[1], argv[2]); _exit(0); } + stub_pid = sp; close(lfd); if (pipe(in_pipe) == -1 || pipe(out_pipe) == -1) @@ -342,6 +353,7 @@ main(int argc, char *argv[]) execl(fugu_bin, fugu_bin, (char *)NULL); _exit(127); } + fugu_pid = fp; close(in_pipe[0]); close(out_pipe[1]);