summaryrefslogtreecommitdiff
path: root/lib/libc_r/TEST/test_fork.c
diff options
context:
space:
mode:
authorDavid Leonard <d@cvs.openbsd.org>1999-01-17 23:46:27 +0000
committerDavid Leonard <d@cvs.openbsd.org>1999-01-17 23:46:27 +0000
commit9ebd7c855719a914d8220cf8b7ab845bd006e6fc (patch)
tree5c1bbd0e96b6b2cff8e39b834dbc918a988a3c9b /lib/libc_r/TEST/test_fork.c
parent899c831eae6d973eed37aecb6bef358e00083afb (diff)
pthread_atfork()
Diffstat (limited to 'lib/libc_r/TEST/test_fork.c')
-rw-r--r--lib/libc_r/TEST/test_fork.c89
1 files changed, 80 insertions, 9 deletions
diff --git a/lib/libc_r/TEST/test_fork.c b/lib/libc_r/TEST/test_fork.c
index efaafb0a7ba..bf0cc583c80 100644
--- a/lib/libc_r/TEST/test_fork.c
+++ b/lib/libc_r/TEST/test_fork.c
@@ -20,25 +20,78 @@
void *
sleeper(void *arg)
{
+
pthread_set_name_np(pthread_self(), "slpr");
- printf("sleeper\n");
sleep(10);
PANIC("sleeper timed out");
}
+static pid_t parent_pid;
+
static void
sigchld(sig)
int sig;
{
int status;
+ /* we should have got a SIGCHLD */
ASSERT(sig == SIGCHLD);
+ /* We should be the parent */
+ ASSERT(getpid() == parent_pid);
+ /* wait for any child */
CHECKe(wait(&status));
+ /* the child should have called exit(0) */
ASSERT(WIFEXITED(status));
ASSERT(WEXITSTATUS(status) == 0);
+ printf("parent ok\n");
SUCCEED;
}
+static int atfork_state = 0;
+
+void
+atfork_child2()
+{
+ ASSERT(atfork_state++ == 3);
+ ASSERT(getpid() != parent_pid);
+}
+
+void
+atfork_parent2()
+{
+ ASSERT(atfork_state++ == 3);
+ ASSERT(getpid() == parent_pid);
+}
+
+void
+atfork_prepare2()
+{
+ ASSERT(atfork_state++ == 0);
+ ASSERT(getpid() == parent_pid);
+}
+
+
+void
+atfork_child1()
+{
+ ASSERT(atfork_state++ == 2);
+ ASSERT(getpid() != parent_pid);
+}
+
+void
+atfork_parent1()
+{
+ ASSERT(atfork_state++ == 2);
+ ASSERT(getpid() == parent_pid);
+}
+
+void
+atfork_prepare1()
+{
+ ASSERT(atfork_state++ == 1);
+ ASSERT(getpid() == parent_pid);
+}
+
int
main()
{
@@ -46,6 +99,8 @@ main()
pid_t pid;
pthread_t sleeper_thread;
+ parent_pid = getpid();
+
CHECKe(flags = fcntl(STDOUT_FILENO, F_GETFL));
if ((flags & (O_NONBLOCK | O_NDELAY))) {
CHECKe(fcntl(STDOUT_FILENO, F_SETFL,
@@ -57,21 +112,37 @@ main()
CHECKe(signal(SIGCHLD, sigchld));
+ /* Install some atfork handlers */
+
+ CHECKr(pthread_atfork(&atfork_prepare1, &atfork_parent1,
+ &atfork_child1));
+ CHECKr(pthread_atfork(&atfork_prepare2, &atfork_parent2,
+ &atfork_child2));
+
printf("forking\n");
CHECKe(pid = fork());
switch(pid) {
case 0:
- sleep(1);
- printf("child process %d\n", getpid());
- _thread_dump_info();
- printf("\n");
+ /* child: */
+ /* Our pid should change */
+ ASSERT(getpid() != parent_pid);
+ /* Our sleeper thread should have disappeared */
+ ASSERT(ESRCH == pthread_cancel(sleeper_thread));
+ /* The atfork handler should have run */
+ ASSERT(atfork_state++ == 4);
+ printf("child ok\n");
_exit(0);
- PANIC("_exit");
+ PANIC("child _exit");
default:
- printf("parent process %d [child %d]\n", getpid(), pid);
- _thread_dump_info();
- printf("\n");
+ /* parent: */
+ /* Our pid should stay the same */
+ ASSERT(getpid() == parent_pid);
+ /* Our sleeper thread should still be around */
+ CHECKr(pthread_cancel(sleeper_thread));
+ /* The atfork handler should have run */
+ ASSERT(atfork_state++ == 4);
+ /* wait for the SIGCHLD from the child */
CHECKe(pause());
PANIC("pause");
}