]> granicus.if.org Git - strace/blob - tests/siginfo.c
f85f7afb2ffeb232f0867087897fc4ac83acd55c
[strace] / tests / siginfo.c
1 /*
2  * Check SIGCHLD siginfo_t decoding.
3  *
4  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
5  * All rights reserved.
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9
10 #include "tests.h"
11 #include <assert.h>
12 #include <signal.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <sys/wait.h>
16
17 static siginfo_t sinfo;
18
19 static void
20 handler(int no, siginfo_t *si, void *uc)
21 {
22         memcpy(&sinfo, si, sizeof(sinfo));
23 }
24
25 int
26 main(void)
27 {
28         tprintf("%s", "");
29
30         int fds[2];
31         if (pipe(fds))
32                 perror_msg_and_fail("pipe");
33
34         pid_t pid = fork();
35         if (pid < 0)
36                 perror_msg_and_fail("fork");
37
38         if (!pid) {
39                 char c;
40                 (void) close(1);
41                 assert(read(0, &c, sizeof(c)) == 1);
42                 return 42;
43         }
44
45         (void) close(0);
46
47         struct sigaction sa = {
48                 .sa_sigaction = handler,
49                 .sa_flags = SA_SIGINFO
50         };
51         assert(sigaction(SIGCHLD, &sa, NULL) == 0);
52
53         sigset_t block_mask, unblock_mask;
54         assert(sigprocmask(SIG_SETMASK, NULL, &block_mask) == 0);
55         sigaddset(&block_mask, SIGCHLD);
56         assert(sigprocmask(SIG_SETMASK, &block_mask, NULL) == 0);
57
58         unblock_mask = block_mask;
59         sigdelset(&unblock_mask, SIGCHLD);
60
61         assert(write(1, "", 1) == 1);
62         (void) close(1);
63
64         sigsuspend(&unblock_mask);
65         tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED"
66                 ", si_pid=%d, si_uid=%u, si_status=%d"
67                 ", si_utime=%llu, si_stime=%llu} ---\n",
68                 sinfo.si_pid, sinfo.si_uid, sinfo.si_status,
69                 zero_extend_signed_to_ull(sinfo.si_utime),
70                 zero_extend_signed_to_ull(sinfo.si_stime));
71
72         int s;
73         assert(wait(&s) == pid);
74         assert(WIFEXITED(s) && WEXITSTATUS(s) == 42);
75
76         if (pipe(fds))
77                 perror_msg_and_fail("pipe");
78         pid = fork();
79         if (pid < 0)
80                 perror_msg_and_fail("fork");
81
82         if (!pid) {
83                 (void) close(1);
84                 char c;
85                 assert(read(0, &c, sizeof(c)) == 1);
86                 (void) raise(SIGUSR1);
87                 return 1;
88         }
89
90         (void) close(0);
91
92         assert(write(1, "", 1) == 1);
93         (void) close(1);
94
95         sigsuspend(&unblock_mask);
96         tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED"
97                 ", si_pid=%d, si_uid=%u, si_status=SIGUSR1"
98                 ", si_utime=%llu, si_stime=%llu} ---\n",
99                 sinfo.si_pid, sinfo.si_uid,
100                 zero_extend_signed_to_ull(sinfo.si_utime),
101                 zero_extend_signed_to_ull(sinfo.si_stime));
102
103         assert(wait(&s) == pid);
104         assert(WIFSIGNALED(s) && WTERMSIG(s) == SIGUSR1);
105
106         if (pipe(fds))
107                 perror_msg_and_fail("pipe");
108         pid = fork();
109         if (pid < 0)
110                 perror_msg_and_fail("fork");
111
112         if (!pid) {
113                 (void) close(1);
114                 raise(SIGSTOP);
115                 char c;
116                 assert(read(0, &c, sizeof(c)) == 1);
117                 return 0;
118         }
119
120         (void) close(0);
121
122         sigsuspend(&unblock_mask);
123         tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_STOPPED"
124                 ", si_pid=%d, si_uid=%u, si_status=SIGSTOP"
125                 ", si_utime=%llu, si_stime=%llu} ---\n",
126                 sinfo.si_pid, sinfo.si_uid,
127                 zero_extend_signed_to_ull(sinfo.si_utime),
128                 zero_extend_signed_to_ull(sinfo.si_stime));
129
130         assert(kill(pid, SIGCONT) == 0);
131
132         sigsuspend(&unblock_mask);
133         tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_CONTINUED"
134                 ", si_pid=%d, si_uid=%u, si_status=SIGCONT"
135                 ", si_utime=%llu, si_stime=%llu} ---\n",
136                 sinfo.si_pid, sinfo.si_uid,
137                 zero_extend_signed_to_ull(sinfo.si_utime),
138                 zero_extend_signed_to_ull(sinfo.si_stime));
139
140         assert(write(1, "", 1) == 1);
141         (void) close(1);
142
143         sigsuspend(&unblock_mask);
144         tprintf("--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED"
145                 ", si_pid=%d, si_uid=%u, si_status=0"
146                 ", si_utime=%llu, si_stime=%llu} ---\n",
147                 sinfo.si_pid, sinfo.si_uid,
148                 zero_extend_signed_to_ull(sinfo.si_utime),
149                 zero_extend_signed_to_ull(sinfo.si_stime));
150
151         assert(wait(&s) == pid && s == 0);
152
153         tprintf("%s\n", "+++ exited with 0 +++");
154         return 0;
155 }