1 | /*
|
---|
2 | Signals test program.
|
---|
3 |
|
---|
4 | This program spawns a subprocess which will use abort() to end. It is
|
---|
5 | expected that this parent will then be able to capture that signal as part
|
---|
6 | of why it is killed.
|
---|
7 | */
|
---|
8 |
|
---|
9 | #include <cstdlib>
|
---|
10 | #include <iostream>
|
---|
11 |
|
---|
12 | #include <signal.h>
|
---|
13 | #include <spawn.h>
|
---|
14 | #include <sys/wait.h>
|
---|
15 |
|
---|
16 |
|
---|
17 | int
|
---|
18 | main(int argc, char** argv)
|
---|
19 | {
|
---|
20 | // Check if we are the child process; this is the case we have arguments.
|
---|
21 | if (argc > 1)
|
---|
22 | std::abort();
|
---|
23 |
|
---|
24 | // Main process: set up a child process and capture on which signal it terminated
|
---|
25 | pid_t childPid;
|
---|
26 | char* childArgv[] = {argv[0], "abort", nullptr};
|
---|
27 | if (auto status = posix_spawn(&childPid, argv[0], nullptr, nullptr, childArgv, nullptr);
|
---|
28 | status != 0)
|
---|
29 | {
|
---|
30 | std::cerr << "Error spawning process: " << strerror(status) << std::endl;
|
---|
31 | return status;
|
---|
32 | }
|
---|
33 |
|
---|
34 | int childStatus;
|
---|
35 | auto returnPid = waitpid(childPid, &childStatus, 0);
|
---|
36 | if (returnPid != childPid) {
|
---|
37 | std::cerr << "waitpid() did not return the requested pid" << std::endl;
|
---|
38 | return -1;
|
---|
39 | }
|
---|
40 | if (!WIFSIGNALED(childStatus) != 0) {
|
---|
41 | std::cerr << "waidpid(): the child process was expected to stop due to an uncaught signal"
|
---|
42 | << std::endl;
|
---|
43 | return -1;
|
---|
44 | }
|
---|
45 | if (auto signal = WTERMSIG(childStatus); signal != SIGABRT) {
|
---|
46 | std::cerr << "the child process ended with signal " << signal << " instead of SIGABRT"
|
---|
47 | << std::endl;
|
---|
48 | return -1;
|
---|
49 | }
|
---|
50 |
|
---|
51 | std::cout << "Test succeeded: child signal SIGABRT was transmitted correctly" << std::endl;
|
---|
52 | return 0;
|
---|
53 | }
|
---|