1*63d1fd59SEnji Cooper /* $NetBSD: t_wait.c,v 1.8 2017/01/13 19:28:55 christos 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*63d1fd59SEnji Cooper __RCSID("$NetBSD: t_wait.c,v 1.8 2017/01/13 19:28:55 christos Exp $"); 33640235e2SEnji Cooper 34640235e2SEnji Cooper #include <sys/wait.h> 35640235e2SEnji Cooper #include <sys/resource.h> 36640235e2SEnji Cooper 37640235e2SEnji Cooper #include <errno.h> 38*63d1fd59SEnji Cooper #include <inttypes.h> 39640235e2SEnji Cooper #include <limits.h> 40640235e2SEnji Cooper #include <pwd.h> 41640235e2SEnji Cooper #include <signal.h> 42*63d1fd59SEnji Cooper #include <stdio.h> 43640235e2SEnji Cooper #include <stdlib.h> 44640235e2SEnji Cooper #include <unistd.h> 45640235e2SEnji Cooper 46640235e2SEnji Cooper #include <atf-c.h> 47640235e2SEnji Cooper 48640235e2SEnji Cooper #ifdef __FreeBSD__ 49640235e2SEnji Cooper #define wrusage __wrusage 50640235e2SEnji Cooper #endif 51640235e2SEnji Cooper 52640235e2SEnji Cooper ATF_TC(wait6_invalid); 53640235e2SEnji Cooper ATF_TC_HEAD(wait6_invalid, tc) 54640235e2SEnji Cooper { 55640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 56640235e2SEnji Cooper "Test that wait6(2) returns EINVAL with 0 options"); 57640235e2SEnji Cooper } 58640235e2SEnji Cooper 59640235e2SEnji Cooper ATF_TC_BODY(wait6_invalid, tc) 60640235e2SEnji Cooper { 61640235e2SEnji Cooper siginfo_t si; 62640235e2SEnji Cooper struct wrusage wru; 63640235e2SEnji Cooper int st; 64640235e2SEnji Cooper ATF_REQUIRE(wait6(P_ALL, 0, &st, 0, &wru, &si) == -1 65640235e2SEnji Cooper && errno == EINVAL); 66640235e2SEnji Cooper } 67640235e2SEnji Cooper 68640235e2SEnji Cooper ATF_TC(wait6_exited); 69640235e2SEnji Cooper ATF_TC_HEAD(wait6_exited, tc) 70640235e2SEnji Cooper { 71640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 72640235e2SEnji Cooper "Test that wait6(2) handled exiting process and code"); 73640235e2SEnji Cooper } 74640235e2SEnji Cooper 75640235e2SEnji Cooper ATF_TC_BODY(wait6_exited, tc) 76640235e2SEnji Cooper { 77640235e2SEnji Cooper siginfo_t si; 78640235e2SEnji Cooper struct wrusage wru; 79640235e2SEnji Cooper int st; 80640235e2SEnji Cooper pid_t pid; 81640235e2SEnji Cooper 82640235e2SEnji Cooper switch (pid = fork()) { 83640235e2SEnji Cooper case -1: 84640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 85640235e2SEnji Cooper case 0: 86640235e2SEnji Cooper exit(0x5a5a5a5a); 87640235e2SEnji Cooper /*NOTREACHED*/ 88640235e2SEnji Cooper default: 89640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 90640235e2SEnji Cooper ATF_REQUIRE(WIFEXITED(st) && WEXITSTATUS(st) == 0x5a); 91640235e2SEnji Cooper ATF_REQUIRE(si.si_status = 0x5a5a5a5a); 92640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 93640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 94640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_EXITED); 95640235e2SEnji Cooper #ifdef __NetBSD__ 96640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 97640235e2SEnji Cooper (uintmax_t)si.si_utime); 98640235e2SEnji Cooper #endif 99640235e2SEnji Cooper break; 100640235e2SEnji Cooper } 101640235e2SEnji Cooper } 102640235e2SEnji Cooper 103640235e2SEnji Cooper ATF_TC(wait6_terminated); 104640235e2SEnji Cooper ATF_TC_HEAD(wait6_terminated, tc) 105640235e2SEnji Cooper { 106640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 107640235e2SEnji Cooper "Test that wait6(2) handled terminated process and code"); 108640235e2SEnji Cooper } 109640235e2SEnji Cooper 110640235e2SEnji Cooper ATF_TC_BODY(wait6_terminated, tc) 111640235e2SEnji Cooper { 112640235e2SEnji Cooper siginfo_t si; 113640235e2SEnji Cooper struct wrusage wru; 114640235e2SEnji Cooper int st; 115640235e2SEnji Cooper pid_t pid; 116640235e2SEnji Cooper 117640235e2SEnji Cooper switch (pid = fork()) { 118640235e2SEnji Cooper case 0: 119640235e2SEnji Cooper sleep(100); 120640235e2SEnji Cooper /*FALLTHROUGH*/ 121640235e2SEnji Cooper case -1: 122640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 123640235e2SEnji Cooper default: 124640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGTERM) == 0); 125640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 126640235e2SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGTERM); 127640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGTERM); 128640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 129640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 130640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_KILLED); 131640235e2SEnji Cooper #ifdef __NetBSD__ 132640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 133640235e2SEnji Cooper (uintmax_t)si.si_utime); 134640235e2SEnji Cooper #endif 135640235e2SEnji Cooper break; 136640235e2SEnji Cooper } 137640235e2SEnji Cooper } 138640235e2SEnji Cooper 139640235e2SEnji Cooper ATF_TC(wait6_coredumped); 140640235e2SEnji Cooper ATF_TC_HEAD(wait6_coredumped, tc) 141640235e2SEnji Cooper { 142640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 143640235e2SEnji Cooper "Test that wait6(2) handled coredumped process and code"); 144640235e2SEnji Cooper } 145640235e2SEnji Cooper 146640235e2SEnji Cooper ATF_TC_BODY(wait6_coredumped, tc) 147640235e2SEnji Cooper { 148640235e2SEnji Cooper siginfo_t si; 149640235e2SEnji Cooper struct wrusage wru; 150640235e2SEnji Cooper int st; 151640235e2SEnji Cooper pid_t pid; 152640235e2SEnji Cooper static const struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; 153640235e2SEnji Cooper 154640235e2SEnji Cooper switch (pid = fork()) { 155640235e2SEnji Cooper case 0: 156640235e2SEnji Cooper ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); 157640235e2SEnji Cooper *(char *)8 = 0; 158640235e2SEnji Cooper /*FALLTHROUGH*/ 159640235e2SEnji Cooper case -1: 160640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 161640235e2SEnji Cooper default: 162640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 163640235e2SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGSEGV 164640235e2SEnji Cooper && WCOREDUMP(st)); 165640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGSEGV); 166640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 167640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 168640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_DUMPED); 169640235e2SEnji Cooper #ifdef __NetBSD__ 170640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 171640235e2SEnji Cooper (uintmax_t)si.si_utime); 172640235e2SEnji Cooper #endif 173640235e2SEnji Cooper break; 174640235e2SEnji Cooper } 175640235e2SEnji Cooper } 176640235e2SEnji Cooper 177640235e2SEnji Cooper ATF_TC(wait6_stop_and_go); 178640235e2SEnji Cooper ATF_TC_HEAD(wait6_stop_and_go, tc) 179640235e2SEnji Cooper { 180640235e2SEnji Cooper atf_tc_set_md_var(tc, "descr", 181640235e2SEnji Cooper "Test that wait6(2) handled stopped/continued process and code"); 182640235e2SEnji Cooper } 183640235e2SEnji Cooper 184640235e2SEnji Cooper ATF_TC_BODY(wait6_stop_and_go, tc) 185640235e2SEnji Cooper { 186640235e2SEnji Cooper siginfo_t si; 187640235e2SEnji Cooper struct wrusage wru; 188640235e2SEnji Cooper int st; 189640235e2SEnji Cooper pid_t pid; 190640235e2SEnji Cooper static const struct rlimit rl = { 0, 0 }; 191640235e2SEnji Cooper 192640235e2SEnji Cooper ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); 193640235e2SEnji Cooper switch (pid = fork()) { 194640235e2SEnji Cooper case 0: 195640235e2SEnji Cooper sleep(100); 196640235e2SEnji Cooper /*FALLTHROUGH*/ 197640235e2SEnji Cooper case -1: 198640235e2SEnji Cooper ATF_REQUIRE(pid > 0); 199640235e2SEnji Cooper default: 200640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGSTOP) == 0); 201640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid); 202ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 203ddba0402SEnji Cooper ATF_REQUIRE(!WIFSIGNALED(st)); 204640235e2SEnji Cooper ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP); 205ddba0402SEnji Cooper ATF_REQUIRE(!WIFCONTINUED(st)); 206640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGSTOP); 207640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 208640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 209640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_STOPPED); 210640235e2SEnji Cooper #ifdef __NetBSD__ 211640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 212640235e2SEnji Cooper (uintmax_t)si.si_utime); 213640235e2SEnji Cooper #endif 214640235e2SEnji Cooper 215640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGCONT) == 0); 216640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid); 217ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 218ddba0402SEnji Cooper ATF_REQUIRE(!WIFSIGNALED(st)); 219640235e2SEnji Cooper ATF_REQUIRE(WIFCONTINUED(st)); 220ddba0402SEnji Cooper ATF_REQUIRE(!WIFSTOPPED(st)); 221640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGCONT); 222640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 223640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 224640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_CONTINUED); 225640235e2SEnji Cooper #ifdef __NetBSD__ 226640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 227640235e2SEnji Cooper (uintmax_t)si.si_utime); 228640235e2SEnji Cooper #endif 229640235e2SEnji Cooper 230640235e2SEnji Cooper ATF_REQUIRE(kill(pid, SIGQUIT) == 0); 231640235e2SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 232ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 233640235e2SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT); 234ddba0402SEnji Cooper ATF_REQUIRE(!WIFSTOPPED(st)); 235ddba0402SEnji Cooper ATF_REQUIRE(!WIFCONTINUED(st)); 236640235e2SEnji Cooper ATF_REQUIRE(si.si_status == SIGQUIT); 237640235e2SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 238640235e2SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 239640235e2SEnji Cooper ATF_REQUIRE(si.si_code == CLD_KILLED); 240640235e2SEnji Cooper #ifdef __NetBSD__ 241640235e2SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 242640235e2SEnji Cooper (uintmax_t)si.si_utime); 243640235e2SEnji Cooper #endif 244640235e2SEnji Cooper break; 245640235e2SEnji Cooper } 246640235e2SEnji Cooper } 247640235e2SEnji Cooper 248ddba0402SEnji Cooper ATF_TC(wait6_stopgo_loop); 249ddba0402SEnji Cooper ATF_TC_HEAD(wait6_stopgo_loop, tc) 250ddba0402SEnji Cooper { 251ddba0402SEnji Cooper atf_tc_set_md_var(tc, "descr", 252ddba0402SEnji Cooper "Test that wait6(2) handled stopped/continued process loop"); 253ddba0402SEnji Cooper } 254ddba0402SEnji Cooper 255ddba0402SEnji Cooper ATF_TC_BODY(wait6_stopgo_loop, tc) 256ddba0402SEnji Cooper { 257ddba0402SEnji Cooper siginfo_t si; 258ddba0402SEnji Cooper struct wrusage wru; 259ddba0402SEnji Cooper int st; 260ddba0402SEnji Cooper pid_t pid; 261ddba0402SEnji Cooper static const struct rlimit rl = { 0, 0 }; 262ddba0402SEnji Cooper size_t N = 100; 263ddba0402SEnji Cooper 264ddba0402SEnji Cooper ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); 265ddba0402SEnji Cooper switch (pid = fork()) { 266ddba0402SEnji Cooper case 0: 267ddba0402SEnji Cooper sleep(100); 268ddba0402SEnji Cooper /*FALLTHROUGH*/ 269ddba0402SEnji Cooper case -1: 270ddba0402SEnji Cooper ATF_REQUIRE(pid > 0); 271ddba0402SEnji Cooper } 272ddba0402SEnji Cooper 273ddba0402SEnji Cooper printf("Before loop of SIGSTOP/SIGCONT sequence %zu times\n", N); 274ddba0402SEnji Cooper while (N --> 0) { 275ddba0402SEnji Cooper ATF_REQUIRE(kill(pid, SIGSTOP) == 0); 276ddba0402SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid); 277ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 278ddba0402SEnji Cooper ATF_REQUIRE(!WIFSIGNALED(st)); 279ddba0402SEnji Cooper ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP); 280ddba0402SEnji Cooper ATF_REQUIRE(!WIFCONTINUED(st)); 281ddba0402SEnji Cooper ATF_REQUIRE(si.si_status == SIGSTOP); 282ddba0402SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 283ddba0402SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 284ddba0402SEnji Cooper ATF_REQUIRE(si.si_code == CLD_STOPPED); 285ddba0402SEnji Cooper 286ddba0402SEnji Cooper ATF_REQUIRE(kill(pid, SIGCONT) == 0); 287ddba0402SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid); 288ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 289ddba0402SEnji Cooper ATF_REQUIRE(!WIFSIGNALED(st)); 290ddba0402SEnji Cooper ATF_REQUIRE(WIFCONTINUED(st)); 291ddba0402SEnji Cooper ATF_REQUIRE(!WIFSTOPPED(st)); 292ddba0402SEnji Cooper ATF_REQUIRE(si.si_status == SIGCONT); 293ddba0402SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 294ddba0402SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 295ddba0402SEnji Cooper ATF_REQUIRE(si.si_code == CLD_CONTINUED); 296ddba0402SEnji Cooper } 297ddba0402SEnji Cooper ATF_REQUIRE(kill(pid, SIGQUIT) == 0); 298ddba0402SEnji Cooper ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); 299ddba0402SEnji Cooper ATF_REQUIRE(!WIFEXITED(st)); 300ddba0402SEnji Cooper ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT); 301ddba0402SEnji Cooper ATF_REQUIRE(!WIFSTOPPED(st)); 302ddba0402SEnji Cooper ATF_REQUIRE(!WIFCONTINUED(st)); 303ddba0402SEnji Cooper ATF_REQUIRE(si.si_status == SIGQUIT); 304ddba0402SEnji Cooper ATF_REQUIRE(si.si_pid == pid); 305ddba0402SEnji Cooper ATF_REQUIRE(si.si_uid == getuid()); 306ddba0402SEnji Cooper ATF_REQUIRE(si.si_code == CLD_KILLED); 307ddba0402SEnji Cooper #ifdef __NetBSD__ 308ddba0402SEnji Cooper printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, 309ddba0402SEnji Cooper (uintmax_t)si.si_utime); 310ddba0402SEnji Cooper #endif 311ddba0402SEnji Cooper } 312ddba0402SEnji Cooper 313640235e2SEnji Cooper ATF_TP_ADD_TCS(tp) 314640235e2SEnji Cooper { 315640235e2SEnji Cooper 316640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_invalid); 317640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_exited); 318640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_terminated); 319640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_coredumped); 320640235e2SEnji Cooper ATF_TP_ADD_TC(tp, wait6_stop_and_go); 321ddba0402SEnji Cooper ATF_TP_ADD_TC(tp, wait6_stopgo_loop); 322640235e2SEnji Cooper 323640235e2SEnji Cooper return atf_no_error(); 324640235e2SEnji Cooper } 325