3 #include <darwintest.h>
14 #include <sys/sysctl.h>
20 * Test to validate that suspended-spawn DTRTs when a SIGKILL is recieved
21 * while the process is waiting for SIGCONT.
23 * Also test that suspended-spawn correctly looks like a SIGSTOP while it's suspended.
25 * <rdar://problem/26184412> posix_spawn non-exec with POSIX_SPAWN_START_SUSPENDED, then killing instead of SIGCONT-ing causes unkillable hung processes
29 spawn_and_signal(int signal
)
31 /* do not buffer output to stdout */
32 setvbuf(stdout
, NULL
, _IONBF
, 0);
35 posix_spawnattr_t attr
;
37 ret
= posix_spawnattr_init(&attr
);
39 T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawnattr_init");
41 ret
= posix_spawnattr_setflags(&attr
, POSIX_SPAWN_START_SUSPENDED
);
43 T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawnattr_setflags");
45 char * const prog
= "/usr/bin/true";
46 char * const argv_child
[] = { prog
, NULL
};
48 extern char **environ
;
50 ret
= posix_spawn(&child_pid
, prog
, NULL
, &attr
, argv_child
, environ
);
51 T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawn");
53 printf("parent: spawned child with pid %d\n", child_pid
);
55 ret
= posix_spawnattr_destroy(&attr
);
57 T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawnattr_destroy");
60 int waitpid_result
= waitpid(child_pid
, &status
, WUNTRACED
|WNOHANG
);
61 T_ASSERT_POSIX_SUCCESS(waitpid_result
, "waitpid");
63 T_ASSERT_EQ(waitpid_result
, child_pid
, "waitpid should return child we spawned");
65 T_ASSERT_EQ(WIFEXITED(status
), 0, "before SIGCONT: must not have exited");
66 T_ASSERT_EQ(WIFSTOPPED(status
), 1, "before SIGCONT: must be stopped");
68 printf("parent: continuing child process\n");
70 ret
= kill(child_pid
, signal
);
71 T_ASSERT_POSIX_SUCCESS(ret
, "kill(signal)");
73 printf("parent: waiting for child process\n");
76 waitpid_result
= waitpid(child_pid
, &status
, 0);
77 T_ASSERT_POSIX_SUCCESS(waitpid_result
, "waitpid");
79 T_ASSERT_EQ(waitpid_result
, child_pid
, "waitpid should return child we spawned");
81 if (signal
== SIGKILL
) {
82 T_ASSERT_EQ(WIFSIGNALED(status
), 1, "child should have exited due to signal");
83 T_ASSERT_EQ(WTERMSIG(status
), SIGKILL
, "child should have exited due to SIGKILL");
85 T_ASSERT_EQ(WIFEXITED(status
), 1, "child should have exited normally");
86 T_ASSERT_EQ(WEXITSTATUS(status
), EX_OK
, "child should have exited with success");
89 printf("wait returned with pid %d, status %d\n", ret
, status
);
92 T_DECL(suspended_spawn_continue
, "Tests spawning a suspended process and continuing it", T_META_TIMEOUT(2))
94 spawn_and_signal(SIGCONT
);
97 T_DECL(suspended_spawn_kill
, "Tests spawning a suspended process and killing it", T_META_TIMEOUT(2))
99 spawn_and_signal(SIGKILL
);