1 /*
2 * Check decoding of waitid syscall.
3 *
4 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
5 * Copyright (c) 2016-2017 The strace developers.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "tests.h"
32 #include <assert.h>
33 #include <signal.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <sys/wait.h>
38 #include <sys/resource.h>
39 #include <asm/unistd.h>
40
41 static const char *
sprint_rusage(const struct rusage * const ru)42 sprint_rusage(const struct rusage *const ru)
43 {
44 static char buf[1024];
45 snprintf(buf, sizeof(buf),
46 "{ru_utime={tv_sec=%lld, tv_usec=%llu}"
47 ", ru_stime={tv_sec=%lld, tv_usec=%llu}"
48 #if VERBOSE
49 ", ru_maxrss=%llu"
50 ", ru_ixrss=%llu"
51 ", ru_idrss=%llu"
52 ", ru_isrss=%llu"
53 ", ru_minflt=%llu"
54 ", ru_majflt=%llu"
55 ", ru_nswap=%llu"
56 ", ru_inblock=%llu"
57 ", ru_oublock=%llu"
58 ", ru_msgsnd=%llu"
59 ", ru_msgrcv=%llu"
60 ", ru_nsignals=%llu"
61 ", ru_nvcsw=%llu"
62 ", ru_nivcsw=%llu}"
63 #else
64 ", ...}"
65 #endif
66 , (long long) ru->ru_utime.tv_sec
67 , zero_extend_signed_to_ull(ru->ru_utime.tv_usec)
68 , (long long) ru->ru_stime.tv_sec
69 , zero_extend_signed_to_ull(ru->ru_stime.tv_usec)
70 #if VERBOSE
71 , zero_extend_signed_to_ull(ru->ru_maxrss)
72 , zero_extend_signed_to_ull(ru->ru_ixrss)
73 , zero_extend_signed_to_ull(ru->ru_idrss)
74 , zero_extend_signed_to_ull(ru->ru_isrss)
75 , zero_extend_signed_to_ull(ru->ru_minflt)
76 , zero_extend_signed_to_ull(ru->ru_majflt)
77 , zero_extend_signed_to_ull(ru->ru_nswap)
78 , zero_extend_signed_to_ull(ru->ru_inblock)
79 , zero_extend_signed_to_ull(ru->ru_oublock)
80 , zero_extend_signed_to_ull(ru->ru_msgsnd)
81 , zero_extend_signed_to_ull(ru->ru_msgrcv)
82 , zero_extend_signed_to_ull(ru->ru_nsignals)
83 , zero_extend_signed_to_ull(ru->ru_nvcsw)
84 , zero_extend_signed_to_ull(ru->ru_nivcsw)
85 #endif
86 );
87 return buf;
88 }
89
90 #define CASE(x) case x: return #x
91
92 static const char *
si_code_2_name(const int code)93 si_code_2_name(const int code)
94 {
95 switch (code) {
96 #ifdef CLD_EXITED
97 CASE(CLD_EXITED);
98 #endif
99 #ifdef CLD_KILLED
100 CASE(CLD_KILLED);
101 #endif
102 #ifdef CLD_DUMPED
103 CASE(CLD_DUMPED);
104 #endif
105 #ifdef CLD_TRAPPED
106 CASE(CLD_TRAPPED);
107 #endif
108 #ifdef CLD_STOPPED
109 CASE(CLD_STOPPED);
110 #endif
111 #ifdef CLD_CONTINUED
112 CASE(CLD_CONTINUED);
113 #endif
114 default:
115 perror_msg_and_fail("unknown si_code %d", code);
116 }
117 }
118
119 static const char *
sprint_siginfo(const siginfo_t * const si,const char * const status_text)120 sprint_siginfo(const siginfo_t *const si, const char *const status_text)
121 {
122 static char buf[1024];
123 snprintf(buf, sizeof(buf),
124 "{si_signo=SIGCHLD"
125 ", si_code=%s"
126 ", si_pid=%u"
127 ", si_uid=%u"
128 ", si_status=%s"
129 ", si_utime=%llu"
130 ", si_stime=%llu}",
131 si_code_2_name(si->si_code),
132 si->si_pid,
133 si->si_uid,
134 status_text,
135 zero_extend_signed_to_ull(si->si_utime),
136 zero_extend_signed_to_ull(si->si_stime));
137 return buf;
138 }
139
140 static unsigned long
poison(unsigned int v)141 poison(unsigned int v)
142 {
143 return (unsigned long) 0xfacefeed00000000ULL | v;
144 }
145
146 static long
do_waitid(const unsigned int idtype,const unsigned int id,const siginfo_t * const infop,const unsigned int options,const struct rusage * const rusage)147 do_waitid(const unsigned int idtype,
148 const unsigned int id,
149 const siginfo_t *const infop,
150 const unsigned int options,
151 const struct rusage *const rusage)
152 {
153 sigset_t mask = {};
154 sigaddset(&mask, SIGCHLD);
155
156 assert(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
157 long rc = syscall(__NR_waitid, poison(idtype), poison(id),
158 infop, poison(options), rusage);
159 assert(sigprocmask(SIG_UNBLOCK, &mask, NULL) == 0);
160 return rc;
161 }
162
163 int
main(void)164 main(void)
165 {
166 tprintf("%s", "");
167
168 int fds[2];
169 if (pipe(fds))
170 perror_msg_and_fail("pipe");
171
172 pid_t pid;
173 pid = fork();
174 if (pid < 0)
175 perror_msg_and_fail("fork");
176
177 if (!pid) {
178 char c;
179 (void) close(1);
180 assert(read(0, &c, sizeof(c)) == 1);
181 return 42;
182 }
183
184 (void) close(0);
185
186 if (do_waitid(P_PID, pid, 0, WNOHANG|WEXITED, 0))
187 perror_msg_and_fail("waitid #1");
188 tprintf("waitid(P_PID, %d, NULL, WNOHANG|WEXITED, NULL) = 0\n", pid);
189
190 TAIL_ALLOC_OBJECT_CONST_PTR(siginfo_t, sinfo);
191 memset(sinfo, 0, sizeof(*sinfo));
192 TAIL_ALLOC_OBJECT_CONST_PTR(struct rusage, rusage);
193 if (do_waitid(P_PID, pid, sinfo, WNOHANG|WEXITED|WSTOPPED, rusage))
194 perror_msg_and_fail("waitid #2");
195 tprintf("waitid(P_PID, %d, {}, WNOHANG|WEXITED|WSTOPPED, %s) = 0\n",
196 pid, sprint_rusage(rusage));
197
198 assert(write(1, "", 1) == 1);
199 (void) close(1);
200
201 if (do_waitid(P_PID, pid, sinfo, WEXITED, rusage))
202 perror_msg_and_fail("waitid #3");
203 tprintf("waitid(P_PID, %d, %s, WEXITED, %s) = 0\n",
204 pid, sprint_siginfo(sinfo, "42"), sprint_rusage(rusage));
205
206 pid = fork();
207 if (pid < 0)
208 perror_msg_and_fail("fork");
209
210 if (!pid) {
211 (void) raise(SIGUSR1);
212 return 1;
213 }
214
215 if (do_waitid(P_PID, pid, sinfo, WEXITED, rusage))
216 perror_msg_and_fail("waitid #4");
217 tprintf("waitid(P_PID, %d, %s, WEXITED, %s) = 0\n",
218 pid, sprint_siginfo(sinfo, "SIGUSR1"), sprint_rusage(rusage));
219
220 if (pipe(fds))
221 perror_msg_and_fail("pipe");
222 pid = fork();
223 if (pid < 0)
224 perror_msg_and_fail("fork");
225
226 if (!pid) {
227 (void) close(1);
228 raise(SIGSTOP);
229 char c;
230 assert(read(0, &c, sizeof(c)) == 1);
231 return 0;
232 }
233
234 (void) close(0);
235
236 if (do_waitid(P_PID, pid, sinfo, WSTOPPED, rusage))
237 perror_msg_and_fail("waitid #5");
238 tprintf("waitid(P_PID, %d, %s, WSTOPPED, %s) = 0\n",
239 pid, sprint_siginfo(sinfo, "SIGSTOP"), sprint_rusage(rusage));
240
241 if (kill(pid, SIGCONT))
242 perror_msg_and_fail("kill(SIGCONT)");
243
244 #if defined WCONTINUED
245 if (do_waitid(P_PID, pid, sinfo, WCONTINUED, rusage))
246 perror_msg_and_fail("waitid #6");
247 tprintf("waitid(P_PID, %d, %s, WCONTINUED, %s) = 0\n",
248 pid, sprint_siginfo(sinfo, "SIGCONT"), sprint_rusage(rusage));
249 #endif /* WCONTINUED */
250
251 assert(write(1, "", 1) == 1);
252 (void) close(1);
253
254 if (do_waitid(P_PID, pid, sinfo, WEXITED, rusage))
255 perror_msg_and_fail("waitid #7");
256 tprintf("waitid(P_PID, %d, %s, WEXITED, %s) = 0\n",
257 pid, sprint_siginfo(sinfo, "0"), sprint_rusage(rusage));
258
259 long rc = do_waitid(P_ALL, -1, sinfo, WEXITED|WSTOPPED, rusage);
260 tprintf("waitid(P_ALL, -1, %p, WEXITED|WSTOPPED, %p)"
261 " = %ld %s (%m)\n", sinfo, rusage, rc, errno2name());
262
263 tprintf("%s\n", "+++ exited with 0 +++");
264 return 0;
265 }
266