From: claudio Date: Wed, 9 Oct 2024 12:59:59 +0000 (+0000) Subject: Add regress test that sends a SIGSTOP to a child whit its mainproc gone. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=53b677a8a339f16b5136c6ea4600f5279ead9fbc;p=openbsd Add regress test that sends a SIGSTOP to a child whit its mainproc gone. Right now this fails since dowait6() depends on ps_mainproc for this. --- diff --git a/regress/sys/kern/signal/sig-stop3/Makefile b/regress/sys/kern/signal/sig-stop3/Makefile new file mode 100644 index 00000000000..a3fdcc30e76 --- /dev/null +++ b/regress/sys/kern/signal/sig-stop3/Makefile @@ -0,0 +1,7 @@ +# $OpenBSD: Makefile,v 1.1 2024/10/09 12:59:59 claudio Exp $ + +PROG= sig-stop3 + +LDADD= -lpthread + +.include diff --git a/regress/sys/kern/signal/sig-stop3/sig-stop3.c b/regress/sys/kern/signal/sig-stop3/sig-stop3.c new file mode 100644 index 00000000000..088765c37f6 --- /dev/null +++ b/regress/sys/kern/signal/sig-stop3/sig-stop3.c @@ -0,0 +1,108 @@ +/* $OpenBSD: sig-stop3.c,v 1.1 2024/10/09 12:59:59 claudio Exp $ */ +/* + * Written by Artur Grabowski 2007 Public Domain. + * Written by Claudio Jeker 2024 Public Domain. + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define THREAD_COUNT 4 + +volatile sig_atomic_t tstp_count, cont_count; +pid_t child; + +static void +alrm_handler(int sig) +{ + kill(child, SIGKILL); + dprintf(STDERR_FILENO, "timeout\n"); + _exit(2); +} + + +static void * +thread(void *arg) +{ + struct timespec ts = { .tv_sec = 2 }; + + while (nanosleep(&ts, &ts) != 0) + ; + + return NULL; +} + +static int +child_main(void) +{ + pthread_t self, pthread[THREAD_COUNT]; + sigset_t set; + int i, r; + + for (i = 0; i < THREAD_COUNT; i++) { + if ((r = pthread_create(&pthread[i], NULL, thread, NULL))) { + warnc(r, "could not create thread"); + pthread[i] = self; + } + } + + /* terminate main process */ + pthread_exit(NULL); +} + +int +main(int argc, char **argv) +{ + struct timespec ts = { .tv_nsec = 200 * 1000 * 1000 }; + int status; + + switch((child = fork())) { + case -1: + err(1, "fork"); + case 0: + exit(child_main()); + default: + break; + } + + signal(SIGALRM, alrm_handler); + alarm(5); + + nanosleep(&ts, NULL); + + printf("sending SIGSTOP\n"); + if (kill(child, SIGSTOP) == -1) + err(1, "kill"); + + printf("waiting...\n"); + if (waitpid(child, &status, WCONTINUED|WUNTRACED) <= 0) + err(1, "waitpid"); + + if (!WIFSTOPPED(status)) + errx(1, "bad status, not stopped: %d", status); + printf("got stopped notification\n"); + + nanosleep(&ts, NULL); + + printf("killing child\n"); + if (kill(child, SIGKILL) == -1) + err(1, "kill"); + + if (waitpid(child, &status, 0) <= 0) + err(1, "waitpid"); + + if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGKILL) + errx(1, "bad status: %d", status); + + printf("OK\n"); + return 0; +}