1*640235e2SEnji Cooper /* $NetBSD: t_wait.c,v 1.4 2016/04/27 21:14:24 christos Exp $ */ 2*640235e2SEnji Cooper 3*640235e2SEnji Cooper /*- 4*640235e2SEnji Cooper * Copyright (c) 2016 The NetBSD Foundation, Inc. 5*640235e2SEnji Cooper * All rights reserved. 6*640235e2SEnji Cooper * 7*640235e2SEnji Cooper * This code is derived from software contributed to The NetBSD Foundation 8*640235e2SEnji Cooper * by Christos Zoulas. 9*640235e2SEnji Cooper * 10*640235e2SEnji Cooper * Redistribution and use in source and binary forms, with or without 11*640235e2SEnji Cooper * modification, are permitted provided that the following conditions 12*640235e2SEnji Cooper * are met: 13*640235e2SEnji Cooper * 1. Redistributions of source code must retain the above copyright 14*640235e2SEnji Cooper * notice, this list of conditions and the following disclaimer. 15*640235e2SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 16*640235e2SEnji Cooper * notice, this list of conditions and the following disclaimer in the 17*640235e2SEnji Cooper * documentation and/or other materials provided with the distribution. 18*640235e2SEnji Cooper * 19*640235e2SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20*640235e2SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21*640235e2SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22*640235e2SEnji Cooper * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23*640235e2SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*640235e2SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*640235e2SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*640235e2SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*640235e2SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*640235e2SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*640235e2SEnji Cooper * POSSIBILITY OF SUCH DAMAGE. 30*640235e2SEnji Cooper */ 31*640235e2SEnji Cooper #include <sys/cdefs.h> 32*640235e2SEnji Cooper __RCSID("$NetBSD: t_wait.c,v 1.4 2016/04/27 21:14:24 christos Exp $"); 33*640235e2SEnji Cooper 34*640235e2SEnji Cooper #include <sys/wait.h> 35*640235e2SEnji Cooper #include <sys/resource.h> 36*640235e2SEnji Cooper 37*640235e2SEnji Cooper #include <stdio.h> 38*640235e2SEnji Cooper #include <errno.h> 39*640235e2SEnji Cooper #include <limits.h> 40*640235e2SEnji Cooper #include <pwd.h> 41*640235e2SEnji Cooper #include <signal.h> 42*640235e2SEnji Cooper #include <stdlib.h> 43*640235e2SEnji Cooper #include <unistd.h> 44*640235e2SEnji Cooper 45*640235e2SEnji Cooper #include <atf-c.h> 46*640235e2SEnji Cooper 47*640235e2SEnji Cooper #ifdef __FreeBSD__ 48*640235e2SEnji Cooper #define wrusage __wrusage 49*640235e2SEnji Cooper #endif 50*640235e2SEnji Cooper 51*640235e2SEnji Cooper ATF_TC(wait6_invalid); 52*640235e2SEnji Cooper ATF_TC_HEAD(wait6_invalid, tc) 53*640235e2SEnji Cooper { 54*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 55*640235e2SEnji Cooper "Test that wait6(2) returns EINVAL with 0 options"); 56*640235e2SEnji Cooper } 57*640235e2SEnji Cooper 58*640235e2SEnji Cooper ATF_TC_BODY(wait6_invalid, tc) 59*640235e2SEnji Cooper { 60*640235e2SEnji Cooper siginfo_t si; 61*640235e2SEnji Cooper struct wrusage wru; 62*640235e2SEnji Cooper int st; 63*640235e2SEnji Cooper ATF_REQUIRE(wait6(P_ALL, 0, &st, 0, &wru, &si) == -1 64*640235e2SEnji Cooper && errno == EINVAL); 65*640235e2SEnji Cooper } 66*640235e2SEnji Cooper 67*640235e2SEnji Cooper ATF_TC(wait6_noproc); 68*640235e2SEnji Cooper ATF_TC_HEAD(wait6_noproc, tc) 69*640235e2SEnji Cooper { 70*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 71*640235e2SEnji Cooper "Test that wait6(2) returns ECHILD with for no processes"); 72*640235e2SEnji Cooper } 73*640235e2SEnji Cooper 74*640235e2SEnji Cooper ATF_TC_BODY(wait6_noproc, tc) 75*640235e2SEnji Cooper { 76*640235e2SEnji Cooper siginfo_t si; 77*640235e2SEnji Cooper struct wrusage wru; 78*640235e2SEnji Cooper int st; 79*640235e2SEnji Cooper ATF_REQUIRE(wait6(P_ALL, 0, &st, WEXITED, &wru, &si) == -1 80*640235e2SEnji Cooper && errno == ECHILD); 81*640235e2SEnji Cooper } 82*640235e2SEnji Cooper 83*640235e2SEnji Cooper ATF_TC(wait6_exited); 84*640235e2SEnji Cooper ATF_TC_HEAD(wait6_exited, tc) 85*640235e2SEnji Cooper { 86*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 87*640235e2SEnji Cooper "Test that wait6(2) handled exiting process and code"); 88*640235e2SEnji Cooper } 89*640235e2SEnji Cooper 90*640235e2SEnji Cooper ATF_TC_BODY(wait6_exited, tc) 91*640235e2SEnji Cooper { 92*640235e2SEnji Cooper siginfo_t si; 93*640235e2SEnji Cooper struct wrusage wru; 94*640235e2SEnji Cooper int st; 95*640235e2SEnji Cooper pid_t pid; 96*640235e2SEnji Cooper 97*640235e2SEnji Cooper switch (pid = fork()) { 98*640235e2SEnji Cooper case -1: 99*640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 100*640235e2SEnji Cooper case 0: 101*640235e2SEnji Cooper exit(0x5a5a5a5a); 102*640235e2SEnji Cooper /*NOTREACHED*/ 103*640235e2SEnji Cooper default: 104*640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 105*640235e2SEnji Cooper ATF_REQUIRE(WIFEXITED(st) && WEXITSTATUS(st) == 0x5a); 106*640235e2SEnji Cooper ATF_REQUIRE(si.si_status = 0x5a5a5a5a); 107*640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 108*640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 109*640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_EXITED); 110*640235e2SEnji Cooper #ifdef __NetBSD__ 111*640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 112*640235e2SEnji Cooper (uintmax_t)si.si_utime); 113*640235e2SEnji Cooper #endif 114*640235e2SEnji Cooper break; 115*640235e2SEnji Cooper } 116*640235e2SEnji Cooper } 117*640235e2SEnji Cooper 118*640235e2SEnji Cooper ATF_TC(wait6_terminated); 119*640235e2SEnji Cooper ATF_TC_HEAD(wait6_terminated, tc) 120*640235e2SEnji Cooper { 121*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 122*640235e2SEnji Cooper "Test that wait6(2) handled terminated process and code"); 123*640235e2SEnji Cooper } 124*640235e2SEnji Cooper 125*640235e2SEnji Cooper ATF_TC_BODY(wait6_terminated, tc) 126*640235e2SEnji Cooper { 127*640235e2SEnji Cooper siginfo_t si; 128*640235e2SEnji Cooper struct wrusage wru; 129*640235e2SEnji Cooper int st; 130*640235e2SEnji Cooper pid_t pid; 131*640235e2SEnji Cooper 132*640235e2SEnji Cooper switch (pid = fork()) { 133*640235e2SEnji Cooper case 0: 134*640235e2SEnji Cooper sleep(100); 135*640235e2SEnji Cooper /*FALLTHROUGH*/ 136*640235e2SEnji Cooper case -1: 137*640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 138*640235e2SEnji Cooper default: 139*640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGTERM) == 0); 140*640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 141*640235e2SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGTERM); 142*640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGTERM); 143*640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 144*640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 145*640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_KILLED); 146*640235e2SEnji Cooper #ifdef __NetBSD__ 147*640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 148*640235e2SEnji Cooper (uintmax_t)si.si_utime); 149*640235e2SEnji Cooper #endif 150*640235e2SEnji Cooper break; 151*640235e2SEnji Cooper } 152*640235e2SEnji Cooper } 153*640235e2SEnji Cooper 154*640235e2SEnji Cooper ATF_TC(wait6_coredumped); 155*640235e2SEnji Cooper ATF_TC_HEAD(wait6_coredumped, tc) 156*640235e2SEnji Cooper { 157*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 158*640235e2SEnji Cooper "Test that wait6(2) handled coredumped process and code"); 159*640235e2SEnji Cooper } 160*640235e2SEnji Cooper 161*640235e2SEnji Cooper ATF_TC_BODY(wait6_coredumped, tc) 162*640235e2SEnji Cooper { 163*640235e2SEnji Cooper siginfo_t si; 164*640235e2SEnji Cooper struct wrusage wru; 165*640235e2SEnji Cooper int st; 166*640235e2SEnji Cooper pid_t pid; 167*640235e2SEnji Cooper static const struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; 168*640235e2SEnji Cooper 169*640235e2SEnji Cooper switch (pid = fork()) { 170*640235e2SEnji Cooper case 0: 171*640235e2SEnji Cooper ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); 172*640235e2SEnji Cooper *(char *)8 = 0; 173*640235e2SEnji Cooper /*FALLTHROUGH*/ 174*640235e2SEnji Cooper case -1: 175*640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 176*640235e2SEnji Cooper default: 177*640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 178*640235e2SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGSEGV 179*640235e2SEnji Cooper && WCOREDUMP(st)); 180*640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGSEGV); 181*640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 182*640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 183*640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_DUMPED); 184*640235e2SEnji Cooper #ifdef __NetBSD__ 185*640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 186*640235e2SEnji Cooper (uintmax_t)si.si_utime); 187*640235e2SEnji Cooper #endif 188*640235e2SEnji Cooper break; 189*640235e2SEnji Cooper } 190*640235e2SEnji Cooper } 191*640235e2SEnji Cooper 192*640235e2SEnji Cooper ATF_TC(wait6_stop_and_go); 193*640235e2SEnji Cooper ATF_TC_HEAD(wait6_stop_and_go, tc) 194*640235e2SEnji Cooper { 195*640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 196*640235e2SEnji Cooper "Test that wait6(2) handled stopped/continued process and code"); 197*640235e2SEnji Cooper } 198*640235e2SEnji Cooper 199*640235e2SEnji Cooper ATF_TC_BODY(wait6_stop_and_go, tc) 200*640235e2SEnji Cooper { 201*640235e2SEnji Cooper siginfo_t si; 202*640235e2SEnji Cooper struct wrusage wru; 203*640235e2SEnji Cooper int st; 204*640235e2SEnji Cooper pid_t pid; 205*640235e2SEnji Cooper static const struct rlimit rl = { 0, 0 }; 206*640235e2SEnji Cooper 207*640235e2SEnji Cooper ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); 208*640235e2SEnji Cooper switch (pid = fork()) { 209*640235e2SEnji Cooper case 0: 210*640235e2SEnji Cooper sleep(100); 211*640235e2SEnji Cooper /*FALLTHROUGH*/ 212*640235e2SEnji Cooper case -1: 213*640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 214*640235e2SEnji Cooper default: 215*640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGSTOP) == 0); 216*640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid); 217*640235e2SEnji Cooper ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP); 218*640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGSTOP); 219*640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 220*640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 221*640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_STOPPED); 222*640235e2SEnji Cooper #ifdef __NetBSD__ 223*640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 224*640235e2SEnji Cooper (uintmax_t)si.si_utime); 225*640235e2SEnji Cooper #endif 226*640235e2SEnji Cooper 227*640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGCONT) == 0); 228*640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid); 229*640235e2SEnji Cooper ATF_REQUIRE(WIFCONTINUED(st)); 230*640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGCONT); 231*640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 232*640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 233*640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_CONTINUED); 234*640235e2SEnji Cooper #ifdef __NetBSD__ 235*640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 236*640235e2SEnji Cooper (uintmax_t)si.si_utime); 237*640235e2SEnji Cooper #endif 238*640235e2SEnji Cooper 239*640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGQUIT) == 0); 240*640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 241*640235e2SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT); 242*640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGQUIT); 243*640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 244*640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 245*640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_KILLED); 246*640235e2SEnji Cooper #ifdef __NetBSD__ 247*640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 248*640235e2SEnji Cooper (uintmax_t)si.si_utime); 249*640235e2SEnji Cooper #endif 250*640235e2SEnji Cooper break; 251*640235e2SEnji Cooper } 252*640235e2SEnji Cooper } 253*640235e2SEnji Cooper 254*640235e2SEnji Cooper ATF_TP_ADD_TCS(tp) 255*640235e2SEnji Cooper { 256*640235e2SEnji Cooper 257*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_invalid); 258*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_noproc); 259*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_exited); 260*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_terminated); 261*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_coredumped); 262*640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_stop_and_go); 263*640235e2SEnji Cooper 264*640235e2SEnji Cooper return atf_no_error(); 265*640235e2SEnji Cooper } 266