From nobody Mon Jan 26 14:37:34 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4f0B2l1LCTz6QLnp for ; Mon, 26 Jan 2026 14:37:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4f0B2k5bT3z3s2q for ; Mon, 26 Jan 2026 14:37:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1769438254; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4v2Gsd+FqjzmE+TNYwQeAZ5LdWI0CqutjRqKUKhYp9U=; b=ulLNShVO/ospCBO5/8JZkDNgGQVSFpY+BrPXCkJyyXlimESwlxr4aAJmUtQOQTae8lLk9i b/3buZe/anDeo9Pcxmz++hmMmsoOwd80GkEaQXUtcGuaDHjRHwFFRNgX3D35oPoD0Jmyq3 Ar+ou6b8Z8oUDsntX8birrOJn9WKWhluJCBDWqCQWm44NEq81KyXM/AxVzMpj3jDWrwkXZ AQQg6JyY55wgEUY/v8Khx3V2PL2653jKwd8098H/x9vybvrfojN5EURKSs0M/dfVocyQej K0Y0Dg/lntMGb2S7XZm0vVt876Hm3Jy1ekC3oGuR6O6D1gP9UNq4dQYkZN3C/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1769438254; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=4v2Gsd+FqjzmE+TNYwQeAZ5LdWI0CqutjRqKUKhYp9U=; b=DJ6SrBHHanysnsLpxQQ+9jfNeoH8ZIXTooXzZcuS8eVkqOOnI3RXCTfAtxfUbswP0S/2iR Q3/RjXUls6Gd/rucjNm+cxSKgPtiIDBiGZCFvj7+4GvMjESJCn4YEEaLHb6VzKOdWw+Btq 0VzsYLirj4m+lc7OBWN3PMgkdGbAeKWtxewrp0z0ixP/kTD/IuNjZwd5V1B0ywfEZc3z8C dowqFshqmG/9x4+3/V+zAsUORxOSCEabp8Mm15JR5AROzHhX4UUy2xRVI5RZSYI6/bc5gO 77UWXo6EN9L0pzYUSDJva6KTuiX5MDskXKwy8rBQFH5OCS8PwH2wl7R5WRgYFw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1769438254; a=rsa-sha256; cv=none; b=lZFOKnLZNpiJ8CLGeJNfJW1N3Ny2rliHG3UG/XWhpVTWu1sgyMvap4MU/M3pdi/Mzgl7I4 y53jxGuepYTFV3iLkpB7aLCrA6zIzZ6eKXrWSRUw5Fy5EREI2mDQVhFJZZ9sSuILuBUZzJ 8rSW8ZsknF3FKlgQ/CtZ+MHJOaMZTJe20v8U/dFKcJ7zxuXg45Z1gsvw4n19tVAWKm8NrF p1/WJ1cDIrLbAu2PGuiUY2L5HZ72DsH8X7zUko+S9R8AH4ahoz0Inczm2mcTLwrdvnmgmN TWts9769D7wyvzyT5e6KYKQdZNRb2EGG4Qmo8lhL4MPt2EG4MrfEYFPIZdVXZg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4f0B2k59Xzz8Z1 for ; Mon, 26 Jan 2026 14:37:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 30e31 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 26 Jan 2026 14:37:34 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Alan Somers Subject: git: 277539ae7f2f - main - Add tests for pdwait List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: asomers X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 277539ae7f2f07a8dd29d4deb318d66414f8ae2a Auto-Submitted: auto-generated Date: Mon, 26 Jan 2026 14:37:34 +0000 Message-Id: <69777c2e.30e31.77b9dc25@gitrepo.freebsd.org> The branch main has been updated by asomers: URL: https://cgit.FreeBSD.org/src/commit/?id=277539ae7f2f07a8dd29d4deb318d66414f8ae2a commit 277539ae7f2f07a8dd29d4deb318d66414f8ae2a Author: Alan Somers AuthorDate: 2026-01-25 16:14:03 +0000 Commit: Alan Somers CommitDate: 2026-01-26 14:37:16 +0000 Add tests for pdwait MFC With: 4d707825bf62ee73a32b615846eff9c4a9bda538 Sponsored by: ConnectWise --- tests/sys/kern/Makefile | 1 + tests/sys/kern/pdwait.c | 295 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile index 0440b9a023eb..7dfa62ebb229 100644 --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -30,6 +30,7 @@ ATF_TESTS_C+= ktrace_test ATF_TESTS_C+= listener_wakeup ATF_TESTS_C+= module_test ATF_TESTS_C+= pdrfork +ATF_TESTS_C+= pdwait ATF_TESTS_C+= prace ATF_TESTS_C+= procdesc ATF_TESTS_C+= ptrace_test diff --git a/tests/sys/kern/pdwait.c b/tests/sys/kern/pdwait.c new file mode 100644 index 000000000000..513b07cae87e --- /dev/null +++ b/tests/sys/kern/pdwait.c @@ -0,0 +1,295 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2026 ConnectWise + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* basic usage */ +ATF_TC_WITHOUT_HEAD(basic); +ATF_TC_BODY(basic, tc) +{ + int fdp = -1; + pid_t pid; + int r, status; + struct __wrusage ru; + siginfo_t si; + + bzero(&ru, sizeof(ru)); + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + r = pdwait(fdp, &status, WEXITED, &ru, &si); + ATF_CHECK_EQ(r, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 42); + ATF_CHECK(ru.wru_self.ru_stime.tv_usec > 0); + ATF_CHECK_EQ(si.si_signo, SIGCHLD); + ATF_CHECK_EQ(si.si_pid, pid); + ATF_CHECK_EQ(si.si_status, WEXITSTATUS(status)); + + close(fdp); +} + +/* pdwait should work in capability mode */ +ATF_TC_WITHOUT_HEAD(capsicum); +ATF_TC_BODY(capsicum, tc) +{ + int fdp = -1; + pid_t pid; + int status, r; + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + ATF_CHECK_EQ_MSG(0, cap_enter(), "cap_enter: %s", strerror(errno)); + r = pdwait(fdp, &status, WEXITED, NULL, NULL); + ATF_CHECK_EQ(r, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 42); + + close(fdp); +} + +/* pdwait should return EBADF if its argument is not a file descriptor */ +ATF_TC_WITHOUT_HEAD(ebadf); +ATF_TC_BODY(ebadf, tc) +{ + ATF_REQUIRE_ERRNO(EBADF, pdwait(99999, NULL, WEXITED, NULL, NULL) < 0); +} + +/* pdwait should return efault if the status argument is invalid. */ +ATF_TC_WITHOUT_HEAD(efault1); +ATF_TC_BODY(efault1, tc) +{ + int fdp = -1; + pid_t pid; + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + ATF_CHECK_ERRNO(EFAULT, pdwait(fdp, (int*)-1, WEXITED, NULL, NULL) < 0); + + close(fdp); +} + +/* pdwait should return efault2 if the usage argument is invalid. */ +ATF_TC_WITHOUT_HEAD(efault2); +ATF_TC_BODY(efault2, tc) +{ + int fdp = -1; + pid_t pid; + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + ATF_CHECK_ERRNO(EFAULT, + pdwait(fdp, NULL, WEXITED, (struct __wrusage*)-1, NULL) < 0); + + close(fdp); +} + +/* pdwait should return efault if the siginfo argument is invalid. */ +ATF_TC_WITHOUT_HEAD(efault3); +ATF_TC_BODY(efault3, tc) +{ + int fdp = -1; + pid_t pid; + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + ATF_CHECK_ERRNO(EFAULT, + pdwait(fdp, NULL, WEXITED, NULL, (struct __siginfo*)-1) < 0); + + close(fdp); +} + +/* pdwait should return einval if the arguments are bad */ +ATF_TC_WITHOUT_HEAD(einval); +ATF_TC_BODY(einval, tc) +{ + int fdp = -1; + pid_t pid; + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + ATF_CHECK_ERRNO(EINVAL, pdwait(fdp, NULL, 0, NULL, NULL) < 0); + ATF_CHECK_ERRNO(EINVAL, pdwait(fdp, NULL, -1, NULL, NULL) < 0); + ATF_CHECK_ERRNO(EINVAL, + pdwait(STDERR_FILENO, NULL, WEXITED, NULL, NULL) < 0); + + close(fdp); +} + +/* pdwait should fail without the cap_pdwait_rights bit */ +ATF_TC_WITHOUT_HEAD(enotcap); +ATF_TC_BODY(enotcap, tc) +{ + cap_rights_t rights; + int fdp = -1; + pid_t pid; + int status; + + /*cap_rights_init(&rights, CAP_RIGHTS_ALL);*/ + CAP_ALL(&rights); + cap_rights_clear(&rights, CAP_PDWAIT); + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + ATF_CHECK_EQ_MSG(0, cap_enter(), "cap_enter: %s", strerror(errno)); + ATF_REQUIRE_EQ_MSG(0, cap_rights_limit(fdp, &rights), + "cap_rights_limit %s", strerror(errno)); + + ATF_REQUIRE_ERRNO(ENOTCAPABLE, + pdwait(fdp, &status, WEXITED, NULL, NULL) < 0); + + close(fdp); +} + +/* + * Even though the process descriptor is still open, there is no more process + * to signal after pdwait() has returned. + */ +ATF_TC_WITHOUT_HEAD(pdkill_after_pdwait); +ATF_TC_BODY(pdkill_after_pdwait, tc) +{ + int fdp = -1; + pid_t pid; + int r, status; + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + r = pdwait(fdp, &status, WEXITED, NULL, NULL); + ATF_CHECK_EQ(r, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 42); + + ATF_REQUIRE_ERRNO(ESRCH, pdkill(fdp, SIGTERM) < 0); + + close(fdp); +} + +/* + * Even though the process descriptor is still open, there is no more status to + * return after a pid-based wait() function has already returned it. + */ +ATF_TC_WITHOUT_HEAD(pdwait_after_waitpid); +ATF_TC_BODY(pdwait_after_waitpid, tc) +{ + int fdp = -1; + pid_t pid, waited_pid; + int status; + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + waited_pid = waitpid(pid, &status, WEXITED); + + ATF_CHECK_EQ(pid, waited_pid); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 42); + + ATF_REQUIRE_ERRNO(ESRCH, pdwait(fdp, NULL, WEXITED, NULL, NULL) < 0); + + close(fdp); +} + +/* Called twice, waitpid should return ESRCH the second time */ +ATF_TC_WITHOUT_HEAD(twice); +ATF_TC_BODY(twice, tc) +{ + int fdp = -1; + pid_t pid; + int r, status; + + pid = pdfork(&fdp, 0); + if (pid == 0) + _exit(42); + ATF_REQUIRE_MSG(pid >= 0, "pdfork failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(fdp >= 0, "pdfork didn't return a process descriptor"); + + r = pdwait(fdp, &status, WEXITED, NULL, NULL); + ATF_CHECK_EQ(r, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 42); + + ATF_REQUIRE_ERRNO(ESRCH, pdwait(fdp, NULL, WEXITED, NULL, NULL) < 0); + + close(fdp); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, basic); + ATF_TP_ADD_TC(tp, capsicum); + ATF_TP_ADD_TC(tp, ebadf); + ATF_TP_ADD_TC(tp, enotcap); + ATF_TP_ADD_TC(tp, twice); + ATF_TP_ADD_TC(tp, efault1); + ATF_TP_ADD_TC(tp, efault2); + ATF_TP_ADD_TC(tp, efault3); + ATF_TP_ADD_TC(tp, einval); + ATF_TP_ADD_TC(tp, pdwait_after_waitpid); + ATF_TP_ADD_TC(tp, pdkill_after_pdwait); + + return (atf_no_error()); +}