1*ddba0402SEnji Cooper /* $NetBSD: t_wait.c,v 1.7 2016/11/06 15:04:14 kamil Exp $ */ 2640235e2SEnji Cooper 3640235e2SEnji Cooper /*- 4640235e2SEnji Cooper * Copyright (c) 2016 The NetBSD Foundation, Inc. 5640235e2SEnji Cooper * All rights reserved. 6640235e2SEnji Cooper * 7640235e2SEnji Cooper * This code is derived from software contributed to The NetBSD Foundation 8640235e2SEnji Cooper * by Christos Zoulas. 9640235e2SEnji Cooper * 10640235e2SEnji Cooper * Redistribution and use in source and binary forms, with or without 11640235e2SEnji Cooper * modification, are permitted provided that the following conditions 12640235e2SEnji Cooper * are met: 13640235e2SEnji Cooper * 1. Redistributions of source code must retain the above copyright 14640235e2SEnji Cooper * notice, this list of conditions and the following disclaimer. 15640235e2SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 16640235e2SEnji Cooper * notice, this list of conditions and the following disclaimer in the 17640235e2SEnji Cooper * documentation and/or other materials provided with the distribution. 18640235e2SEnji Cooper * 19640235e2SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20640235e2SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21640235e2SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22640235e2SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23640235e2SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24640235e2SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25640235e2SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26640235e2SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27640235e2SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28640235e2SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29640235e2SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 30640235e2SEnji Cooper */ 31640235e2SEnji Cooper #include <sys/cdefs.h> 32*ddba0402SEnji Cooper __RCSID("$NetBSD: t_wait.c,v 1.7 2016/11/06 15:04:14 kamil Exp $"); 33640235e2SEnji Cooper 34640235e2SEnji Cooper #include <sys/wait.h> 35640235e2SEnji Cooper #include <sys/resource.h> 36640235e2SEnji Cooper 37640235e2SEnji Cooper #include <stdio.h> 38640235e2SEnji Cooper #include <errno.h> 39640235e2SEnji Cooper #include <limits.h> 40640235e2SEnji Cooper #include <pwd.h> 41640235e2SEnji Cooper #include <signal.h> 42640235e2SEnji Cooper #include <stdlib.h> 43640235e2SEnji Cooper #include <unistd.h> 44640235e2SEnji Cooper 45640235e2SEnji Cooper #include <atf-c.h> 46640235e2SEnji Cooper 47640235e2SEnji Cooper #ifdef __FreeBSD__ 48640235e2SEnji Cooper #define wrusage __wrusage 49640235e2SEnji Cooper #endif 50640235e2SEnji Cooper 51640235e2SEnji Cooper ATF_TC(wait6_invalid); 52640235e2SEnji Cooper ATF_TC_HEAD(wait6_invalid, tc) 53640235e2SEnji Cooper { 54640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 55640235e2SEnji Cooper "Test that wait6(2) returns EINVAL with 0 options"); 56640235e2SEnji Cooper } 57640235e2SEnji Cooper 58640235e2SEnji Cooper ATF_TC_BODY(wait6_invalid, tc) 59640235e2SEnji Cooper { 60640235e2SEnji Cooper siginfo_t si; 61640235e2SEnji Cooper struct wrusage wru; 62640235e2SEnji Cooper int st; 63640235e2SEnji Cooper ATF_REQUIRE(wait6(P_ALL, 0, &st, 0, &wru, &si) == -1 64640235e2SEnji Cooper && errno == EINVAL); 65640235e2SEnji Cooper } 66640235e2SEnji Cooper 67640235e2SEnji Cooper ATF_TC(wait6_exited); 68640235e2SEnji Cooper ATF_TC_HEAD(wait6_exited, tc) 69640235e2SEnji Cooper { 70640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 71640235e2SEnji Cooper "Test that wait6(2) handled exiting process and code"); 72640235e2SEnji Cooper } 73640235e2SEnji Cooper 74640235e2SEnji Cooper ATF_TC_BODY(wait6_exited, tc) 75640235e2SEnji Cooper { 76640235e2SEnji Cooper siginfo_t si; 77640235e2SEnji Cooper struct wrusage wru; 78640235e2SEnji Cooper int st; 79640235e2SEnji Cooper pid_t pid; 80640235e2SEnji Cooper 81640235e2SEnji Cooper switch (pid = fork()) { 82640235e2SEnji Cooper case -1: 83640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 84640235e2SEnji Cooper case 0: 85640235e2SEnji Cooper exit(0x5a5a5a5a); 86640235e2SEnji Cooper /*NOTREACHED*/ 87640235e2SEnji Cooper default: 88640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 89640235e2SEnji Cooper ATF_REQUIRE(WIFEXITED(st) && WEXITSTATUS(st) == 0x5a); 90640235e2SEnji Cooper ATF_REQUIRE(si.si_status = 0x5a5a5a5a); 91640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 92640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 93640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_EXITED); 94640235e2SEnji Cooper #ifdef __NetBSD__ 95640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 96640235e2SEnji Cooper (uintmax_t)si.si_utime); 97640235e2SEnji Cooper #endif 98640235e2SEnji Cooper break; 99640235e2SEnji Cooper } 100640235e2SEnji Cooper } 101640235e2SEnji Cooper 102640235e2SEnji Cooper ATF_TC(wait6_terminated); 103640235e2SEnji Cooper ATF_TC_HEAD(wait6_terminated, tc) 104640235e2SEnji Cooper { 105640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 106640235e2SEnji Cooper "Test that wait6(2) handled terminated process and code"); 107640235e2SEnji Cooper } 108640235e2SEnji Cooper 109640235e2SEnji Cooper ATF_TC_BODY(wait6_terminated, tc) 110640235e2SEnji Cooper { 111640235e2SEnji Cooper siginfo_t si; 112640235e2SEnji Cooper struct wrusage wru; 113640235e2SEnji Cooper int st; 114640235e2SEnji Cooper pid_t pid; 115640235e2SEnji Cooper 116640235e2SEnji Cooper switch (pid = fork()) { 117640235e2SEnji Cooper case 0: 118640235e2SEnji Cooper sleep(100); 119640235e2SEnji Cooper /*FALLTHROUGH*/ 120640235e2SEnji Cooper case -1: 121640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 122640235e2SEnji Cooper default: 123640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGTERM) == 0); 124640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 125640235e2SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGTERM); 126640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGTERM); 127640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 128640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 129640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_KILLED); 130640235e2SEnji Cooper #ifdef __NetBSD__ 131640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 132640235e2SEnji Cooper (uintmax_t)si.si_utime); 133640235e2SEnji Cooper #endif 134640235e2SEnji Cooper break; 135640235e2SEnji Cooper } 136640235e2SEnji Cooper } 137640235e2SEnji Cooper 138640235e2SEnji Cooper ATF_TC(wait6_coredumped); 139640235e2SEnji Cooper ATF_TC_HEAD(wait6_coredumped, tc) 140640235e2SEnji Cooper { 141640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 142640235e2SEnji Cooper "Test that wait6(2) handled coredumped process and code"); 143640235e2SEnji Cooper } 144640235e2SEnji Cooper 145640235e2SEnji Cooper ATF_TC_BODY(wait6_coredumped, tc) 146640235e2SEnji Cooper { 147640235e2SEnji Cooper siginfo_t si; 148640235e2SEnji Cooper struct wrusage wru; 149640235e2SEnji Cooper int st; 150640235e2SEnji Cooper pid_t pid; 151640235e2SEnji Cooper static const struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; 152640235e2SEnji Cooper 153640235e2SEnji Cooper switch (pid = fork()) { 154640235e2SEnji Cooper case 0: 155640235e2SEnji Cooper ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); 156640235e2SEnji Cooper *(char *)8 = 0; 157640235e2SEnji Cooper /*FALLTHROUGH*/ 158640235e2SEnji Cooper case -1: 159640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 160640235e2SEnji Cooper default: 161640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 162640235e2SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGSEGV 163640235e2SEnji Cooper && WCOREDUMP(st)); 164640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGSEGV); 165640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 166640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 167640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_DUMPED); 168640235e2SEnji Cooper #ifdef __NetBSD__ 169640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 170640235e2SEnji Cooper (uintmax_t)si.si_utime); 171640235e2SEnji Cooper #endif 172640235e2SEnji Cooper break; 173640235e2SEnji Cooper } 174640235e2SEnji Cooper } 175640235e2SEnji Cooper 176640235e2SEnji Cooper ATF_TC(wait6_stop_and_go); 177640235e2SEnji Cooper ATF_TC_HEAD(wait6_stop_and_go, tc) 178640235e2SEnji Cooper { 179640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 180640235e2SEnji Cooper "Test that wait6(2) handled stopped/continued process and code"); 181640235e2SEnji Cooper } 182640235e2SEnji Cooper 183640235e2SEnji Cooper ATF_TC_BODY(wait6_stop_and_go, tc) 184640235e2SEnji Cooper { 185640235e2SEnji Cooper siginfo_t si; 186640235e2SEnji Cooper struct wrusage wru; 187640235e2SEnji Cooper int st; 188640235e2SEnji Cooper pid_t pid; 189640235e2SEnji Cooper static const struct rlimit rl = { 0, 0 }; 190640235e2SEnji Cooper 191640235e2SEnji Cooper ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); 192640235e2SEnji Cooper switch (pid = fork()) { 193640235e2SEnji Cooper case 0: 194640235e2SEnji Cooper sleep(100); 195640235e2SEnji Cooper /*FALLTHROUGH*/ 196640235e2SEnji Cooper case -1: 197640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 198640235e2SEnji Cooper default: 199640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGSTOP) == 0); 200640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid); 201*ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 202*ddba0402SEnji Cooper ATF_REQUIRE(!WIFSIGNALED(st)); 203640235e2SEnji Cooper ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP); 204*ddba0402SEnji Cooper ATF_REQUIRE(!WIFCONTINUED(st)); 205640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGSTOP); 206640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 207640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 208640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_STOPPED); 209640235e2SEnji Cooper #ifdef __NetBSD__ 210640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 211640235e2SEnji Cooper (uintmax_t)si.si_utime); 212640235e2SEnji Cooper #endif 213640235e2SEnji Cooper 214640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGCONT) == 0); 215640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid); 216*ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 217*ddba0402SEnji Cooper ATF_REQUIRE(!WIFSIGNALED(st)); 218640235e2SEnji Cooper ATF_REQUIRE(WIFCONTINUED(st)); 219*ddba0402SEnji Cooper ATF_REQUIRE(!WIFSTOPPED(st)); 220640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGCONT); 221640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 222640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 223640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_CONTINUED); 224640235e2SEnji Cooper #ifdef __NetBSD__ 225640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 226640235e2SEnji Cooper (uintmax_t)si.si_utime); 227640235e2SEnji Cooper #endif 228640235e2SEnji Cooper 229640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGQUIT) == 0); 230640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 231*ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 232640235e2SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT); 233*ddba0402SEnji Cooper ATF_REQUIRE(!WIFSTOPPED(st)); 234*ddba0402SEnji Cooper ATF_REQUIRE(!WIFCONTINUED(st)); 235640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGQUIT); 236640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 237640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 238640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_KILLED); 239640235e2SEnji Cooper #ifdef __NetBSD__ 240640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 241640235e2SEnji Cooper (uintmax_t)si.si_utime); 242640235e2SEnji Cooper #endif 243640235e2SEnji Cooper break; 244640235e2SEnji Cooper } 245640235e2SEnji Cooper } 246640235e2SEnji Cooper 247*ddba0402SEnji Cooper ATF_TC(wait6_stopgo_loop); 248*ddba0402SEnji Cooper ATF_TC_HEAD(wait6_stopgo_loop, tc) 249*ddba0402SEnji Cooper { 250*ddba0402SEnji Cooper atf_tc_set_md_var(tc, "descr", 251*ddba0402SEnji Cooper "Test that wait6(2) handled stopped/continued process loop"); 252*ddba0402SEnji Cooper } 253*ddba0402SEnji Cooper 254*ddba0402SEnji Cooper ATF_TC_BODY(wait6_stopgo_loop, tc) 255*ddba0402SEnji Cooper { 256*ddba0402SEnji Cooper siginfo_t si; 257*ddba0402SEnji Cooper struct wrusage wru; 258*ddba0402SEnji Cooper int st; 259*ddba0402SEnji Cooper pid_t pid; 260*ddba0402SEnji Cooper static const struct rlimit rl = { 0, 0 }; 261*ddba0402SEnji Cooper size_t N = 100; 262*ddba0402SEnji Cooper 263*ddba0402SEnji Cooper ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); 264*ddba0402SEnji Cooper switch (pid = fork()) { 265*ddba0402SEnji Cooper case 0: 266*ddba0402SEnji Cooper sleep(100); 267*ddba0402SEnji Cooper /*FALLTHROUGH*/ 268*ddba0402SEnji Cooper case -1: 269*ddba0402SEnji Cooper ATF_REQUIRE(pid > 0); 270*ddba0402SEnji Cooper } 271*ddba0402SEnji Cooper 272*ddba0402SEnji Cooper printf("Before loop of SIGSTOP/SIGCONT sequence %zu times\n", N); 273*ddba0402SEnji Cooper while (N --> 0) { 274*ddba0402SEnji Cooper ATF_REQUIRE(kill(pid, SIGSTOP) == 0); 275*ddba0402SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid); 276*ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 277*ddba0402SEnji Cooper ATF_REQUIRE(!WIFSIGNALED(st)); 278*ddba0402SEnji Cooper ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP); 279*ddba0402SEnji Cooper ATF_REQUIRE(!WIFCONTINUED(st)); 280*ddba0402SEnji Cooper ATF_REQUIRE(si.si_status == SIGSTOP); 281*ddba0402SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 282*ddba0402SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 283*ddba0402SEnji Cooper ATF_REQUIRE(si.si_code == CLD_STOPPED); 284*ddba0402SEnji Cooper 285*ddba0402SEnji Cooper ATF_REQUIRE(kill(pid, SIGCONT) == 0); 286*ddba0402SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid); 287*ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 288*ddba0402SEnji Cooper ATF_REQUIRE(!WIFSIGNALED(st)); 289*ddba0402SEnji Cooper ATF_REQUIRE(WIFCONTINUED(st)); 290*ddba0402SEnji Cooper ATF_REQUIRE(!WIFSTOPPED(st)); 291*ddba0402SEnji Cooper ATF_REQUIRE(si.si_status == SIGCONT); 292*ddba0402SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 293*ddba0402SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 294*ddba0402SEnji Cooper ATF_REQUIRE(si.si_code == CLD_CONTINUED); 295*ddba0402SEnji Cooper } 296*ddba0402SEnji Cooper ATF_REQUIRE(kill(pid, SIGQUIT) == 0); 297*ddba0402SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 298*ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 299*ddba0402SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT); 300*ddba0402SEnji Cooper ATF_REQUIRE(!WIFSTOPPED(st)); 301*ddba0402SEnji Cooper ATF_REQUIRE(!WIFCONTINUED(st)); 302*ddba0402SEnji Cooper ATF_REQUIRE(si.si_status == SIGQUIT); 303*ddba0402SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 304*ddba0402SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 305*ddba0402SEnji Cooper ATF_REQUIRE(si.si_code == CLD_KILLED); 306*ddba0402SEnji Cooper #ifdef __NetBSD__ 307*ddba0402SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 308*ddba0402SEnji Cooper (uintmax_t)si.si_utime); 309*ddba0402SEnji Cooper #endif 310*ddba0402SEnji Cooper } 311*ddba0402SEnji Cooper 312640235e2SEnji Cooper ATF_TP_ADD_TCS(tp) 313640235e2SEnji Cooper { 314640235e2SEnji Cooper 315640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_invalid); 316640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_exited); 317640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_terminated); 318640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_coredumped); 319640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_stop_and_go); 320*ddba0402SEnji Cooper ATF_TP_ADD_TC(tp, wait6_stopgo_loop); 321640235e2SEnji Cooper 322640235e2SEnji Cooper return atf_no_error(); 323640235e2SEnji Cooper } 324