From patchwork Fri Apr 10 18:55:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 38802 Return-Path: X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from esa1.hgst.iphmx.com (esa1.hgst.iphmx.com [68.232.141.245]) by sourceware.org (Postfix) with ESMTPS id 24D79385BF81 for ; Fri, 10 Apr 2020 19:03:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 24D79385BF81 IronPort-SDR: hQCbn3jxOOIpISQW27sDBhwrb1vOd9f1bX/a8/NNHYJbNRGjscF+975xrBUA1OjqCrpPcxqDBP f5KoX26WrgKil23fLCf2jg9WneQTh7Ql+QWUth4cfcrOte1TsSPqEORSi1b141znel1L9/pLeh 6m+AU75LjpiEu/XPaH1JJq9eCZINpS6OBMXNtWvrZd2q54gdHSYtcWqMd0RNctO7AtL+GhzKpy EbsOGP7sn+cmUguspGv5VvlwQPfadcVuxcFkEZ47yHcHXuPYLn5KpN/PpfjY65/V34dJqNyBYU 8hM= X-IronPort-AV: E=Sophos;i="5.72,367,1580745600"; d="scan'208";a="243684710" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 11 Apr 2020 03:03:04 +0800 IronPort-SDR: s6J0Gd0lfJ32z51unK8DQ0Qh/CyNs8jlUER1Vzpk5JCH2dfpLElVe7DM9Jdn1lIi0/+W7uvoDS zVM8G7gVM9aIprXM+6/R0gzLaUp3r+/L+VZ9lIbhdqOD1tSBn4YVMZUuTDbZxiR7ZbgxSRQ2Vh jlh8LonbOQbkHrTaEeJu+CFYcMu9Kg9UJTz7OygKcbDrp2xpstN5bBq489R228eh4muSP58cK7 mWtMa5nUhT4TpJ3ZhEeSwYEXyZoxRi476DOEFM5nAFaxIF1+cY4KoEChjVth+C0R9ahN7xhE7P meJeuYs083AL/wgLOl5X7r9d Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Apr 2020 11:54:14 -0700 IronPort-SDR: LKk8HIiUKK8qL4+R4lFKLSst9q/UWGHDtkg3R5BT3rNSg1vfby81+fV+wzdHDNp3mAbi0jRHqs kfMJA762CcYambyT1bckJfd9CENpwq+Bcx0YToNyYCbQ1VQVmWsNVmUrqDrA+OvZwKyAcYsAsD fV1SkLsRwOxCkZZn1ETx/mVT1iwMjWB0JFgaFDUbxXkUAvKy3WeIyV/QiiagQVki7WdmBytjuI cwZN0ldDh+zbw904PfjJoopwxcpV6SZYLh1GXUheyCM6w866AVkWepNPgLF9zHllu96514F4es QK8= WDCIronportException: Internal Received: from phd004806.ad.shared (HELO risc6-mainframe.hgst.com) ([10.86.55.150]) by uls-op-cesaip01.wdc.com with ESMTP; 10 Apr 2020 12:03:05 -0700 From: Alistair Francis To: libc-alpha@sourceware.org Cc: alistair23@gmail.com, Alistair Francis Subject: [PATCH v4 2/2] posix: Add wait4 test case Date: Fri, 10 Apr 2020 11:55:13 -0700 Message-Id: <20200410185513.1284043-3-alistair.francis@wdc.com> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200410185513.1284043-1-alistair.francis@wdc.com> References: <20200410185513.1284043-1-alistair.francis@wdc.com> MIME-Version: 1.0 X-Spam-Status: No, score=-24.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Apr 2020 19:03:10 -0000 Add a wait4 test case based on the waitid test case. --- posix/Makefile | 3 +- posix/tst-wait4.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 posix/tst-wait4.c diff --git a/posix/Makefile b/posix/Makefile index 4507d84bf1..605ddbade8 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -82,7 +82,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \ bug-regex29 bug-regex30 bug-regex31 bug-regex32 \ tst-nice tst-nanosleep tst-regex2 \ transbug tst-rxspencer tst-pcre tst-boost \ - bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \ + bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 \ + tst-waitid tst-wait4 \ tst-getaddrinfo2 bug-glob2 bug-glob3 tst-sysconf \ tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \ tst-execv1 tst-execv2 tst-execl1 tst-execl2 \ diff --git a/posix/tst-wait4.c b/posix/tst-wait4.c new file mode 100644 index 0000000000..5696a3456c --- /dev/null +++ b/posix/tst-wait4.c @@ -0,0 +1,209 @@ +/* Tests for wait4. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static void +test_child (void) +{ + /* First thing, we stop ourselves. */ + raise (SIGSTOP); + + /* Hey, we got continued! */ + while (1) + pause (); +} + +#ifndef WEXITED +# define WEXITED 0 +# define WCONTINUED 0 +# define WSTOPPED WUNTRACED +#endif + +/* Set with only SIGCHLD on do_test_waitid. */ +static sigset_t chldset; + +#ifdef SA_SIGINFO +static void +sigchld (int signo, siginfo_t *info, void *ctx) +{ +} +#endif + +static void +check_sigchld (int code, int status, pid_t pid) +{ +#ifdef SA_SIGINFO + siginfo_t siginfo; + TEST_COMPARE (sigwaitinfo (&chldset, &siginfo), SIGCHLD); + + TEST_COMPARE (siginfo.si_signo, SIGCHLD); + TEST_COMPARE (siginfo.si_code, code); + TEST_COMPARE (siginfo.si_status, status); + TEST_COMPARE (siginfo.si_pid, pid); +#endif +} + +static int +do_test_wait4 (pid_t pid) +{ + /* Adding process_state_tracing_stop ('t') allows the test to work under + trace programs such as ptrace. */ + enum support_process_state stop_state = support_process_state_stopped + | support_process_state_tracing_stop; + + support_process_state_wait (pid, stop_state); + + check_sigchld (CLD_STOPPED, SIGSTOP, pid); + + pid_t ret; + int wstatus; + struct rusage rusage; + + ret = wait4 (pid, &wstatus, WUNTRACED|WCONTINUED|WNOHANG, NULL); + if (ret == -1 && errno == ENOTSUP) + FAIL_RET ("waitid WNOHANG on stopped: %m"); + TEST_COMPARE (ret, pid); + TEST_VERIFY (WIFSTOPPED (wstatus)); + + /* Issue again but with struct rusage input. */ + ret = wait4 (pid, &wstatus, WUNTRACED|WCONTINUED|WNOHANG, &rusage); + /* With WNOHANG and WUNTRACED, if the children has not changes its state + since previous call the expected result it 0. */ + TEST_COMPARE (ret, 0); + + /* Some sanity tests to check if 'wtatus' and 'rusage' possible + input values. */ + ret = wait4 (pid, NULL, WUNTRACED|WCONTINUED|WNOHANG, &rusage); + TEST_COMPARE (ret, 0); + ret = wait4 (pid, NULL, WUNTRACED|WCONTINUED|WNOHANG, NULL); + TEST_COMPARE (ret, 0); + + if (kill (pid, SIGCONT) != 0) + FAIL_RET ("kill (%d, SIGCONT): %m\n", pid); + + /* Wait for the child to have continued. */ + support_process_state_wait (pid, support_process_state_sleeping); + +#if WCONTINUED != 0 + check_sigchld (CLD_CONTINUED, SIGCONT, pid); + + ret = wait4 (pid, &wstatus, WCONTINUED|WNOHANG, NULL); + TEST_COMPARE (ret, pid); + TEST_VERIFY (WIFCONTINUED (wstatus)); + + /* Issue again but with struct rusage input. */ + ret = wait4 (pid, &wstatus, WUNTRACED|WCONTINUED|WNOHANG, &rusage); + /* With WNOHANG and WUNTRACED, if the children has not changes its state + since previous call the expected result it 0. */ + TEST_COMPARE (ret, 0); + + /* Now stop him again and test waitpid with WCONTINUED. */ + if (kill (pid, SIGSTOP) != 0) + FAIL_RET ("kill (%d, SIGSTOP): %m\n", pid); + + /* Wait the child stop. The waitid call below will block until it has + stopped, but if we are real quick and enter the waitid system call + before the SIGCHLD has been generated, then it will be discarded and + never delivered. */ + support_process_state_wait (pid, stop_state); + + ret = wait4 (pid, &wstatus, WUNTRACED|WNOHANG, &rusage); + TEST_COMPARE (ret, pid); + + check_sigchld (CLD_STOPPED, SIGSTOP, pid); + + if (kill (pid, SIGCONT) != 0) + FAIL_RET ("kill (%d, SIGCONT): %m\n", pid); + + /* Wait for the child to have continued. */ + support_process_state_wait (pid, support_process_state_sleeping); + + check_sigchld (CLD_CONTINUED, SIGCONT, pid); + + ret = wait4 (pid, &wstatus, WCONTINUED|WNOHANG, NULL); + TEST_COMPARE (ret, pid); + TEST_VERIFY (WIFCONTINUED (wstatus)); +#endif + + /* Die, child, die! */ + if (kill (pid, SIGKILL) != 0) + FAIL_RET ("kill (%d, SIGKILL): %m\n", pid); + + support_process_state_wait (pid, support_process_state_zombie); + + ret = wait4 (pid, &wstatus, 0, &rusage); + TEST_COMPARE (ret, pid); + TEST_VERIFY (WIFSIGNALED (wstatus)); + TEST_VERIFY (WTERMSIG (wstatus) == SIGKILL); + + check_sigchld (CLD_KILLED, SIGKILL, pid); + + return 0; +} + +static int +do_test (void) +{ +#ifdef SA_SIGINFO + { + struct sigaction sa; + sa.sa_flags = SA_SIGINFO | SA_RESTART; + sa.sa_sigaction = sigchld; + sigemptyset (&sa.sa_mask); + xsigaction (SIGCHLD, &sa, NULL); + } +#endif + + sigemptyset (&chldset); + sigaddset (&chldset, SIGCHLD); + + /* The SIGCHLD shall has blocked at the time of the call to sigwait; + otherwise, the behavior is undefined. */ + sigprocmask (SIG_BLOCK, &chldset, NULL); + + pid_t pid = xfork (); + if (pid == 0) + { + test_child (); + _exit (127); + } + + do_test_wait4 (pid); + + xsignal (SIGCHLD, SIG_IGN); + kill (pid, SIGKILL); /* Make sure it's dead if we bailed early. */ + + return 0; +} + +#include