summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/sys
diff options
context:
space:
mode:
authormbuhl <>2021-09-02 12:40:44 +0000
committermbuhl <>2021-09-02 12:40:44 +0000
commite7198b4ee0ece23326da3c1f771171a6ca285eca (patch)
tree26178d4a39622725fceb2c9310410d40d4760679 /src/regress/lib/libc/sys
parentd0809b5ed8cfa0c035364e0fc4076d693a68339e (diff)
downloadopenbsd-e7198b4ee0ece23326da3c1f771171a6ca285eca.tar.gz
openbsd-e7198b4ee0ece23326da3c1f771171a6ca285eca.tar.bz2
openbsd-e7198b4ee0ece23326da3c1f771171a6ca285eca.zip
Import more NetBSD system call regression tests.
OK bluhm@
Diffstat (limited to 'src/regress/lib/libc/sys')
-rw-r--r--src/regress/lib/libc/sys/Makefile35
-rw-r--r--src/regress/lib/libc/sys/README82
-rw-r--r--src/regress/lib/libc/sys/atf-c.h3
-rw-r--r--src/regress/lib/libc/sys/h_macros.h1
-rw-r--r--src/regress/lib/libc/sys/macros.h14
-rw-r--r--src/regress/lib/libc/sys/t_clock_gettime.c1
-rw-r--r--src/regress/lib/libc/sys/t_connect.c135
-rw-r--r--src/regress/lib/libc/sys/t_fork.c387
-rw-r--r--src/regress/lib/libc/sys/t_kevent.c236
-rw-r--r--src/regress/lib/libc/sys/t_minherit.c203
-rw-r--r--src/regress/lib/libc/sys/t_pollts.c203
-rw-r--r--src/regress/lib/libc/sys/t_ppoll.c34
-rw-r--r--src/regress/lib/libc/sys/t_setrlimit.c559
-rw-r--r--src/regress/lib/libc/sys/t_sigaltstack.c102
-rw-r--r--src/regress/lib/libc/sys/t_syscall.c10
-rw-r--r--src/regress/lib/libc/sys/t_wait_noproc.c364
-rw-r--r--src/regress/lib/libc/sys/t_wait_noproc_wnohang.c31
17 files changed, 2350 insertions, 50 deletions
diff --git a/src/regress/lib/libc/sys/Makefile b/src/regress/lib/libc/sys/Makefile
index 7a3b920426..acb5c89896 100644
--- a/src/regress/lib/libc/sys/Makefile
+++ b/src/regress/lib/libc/sys/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.10 2020/12/17 00:51:11 bluhm Exp $ 1# $OpenBSD: Makefile,v 1.11 2021/09/02 12:40:44 mbuhl Exp $
2 2
3# Copyright (c) 2019 Moritz Buhl <openbsd@moritzbuhl.de> 3# Copyright (c) 2019 Moritz Buhl <openbsd@moritzbuhl.de>
4# Copyright (c) 2019 Alexander Bluhm <bluhm@openbsd.org> 4# Copyright (c) 2019 Alexander Bluhm <bluhm@openbsd.org>
@@ -29,20 +29,45 @@ PROGS =
29PROGS += t_access 29PROGS += t_access
30PROGS += t_bind 30PROGS += t_bind
31PROGS += t_chroot t_clock_gettime 31PROGS += t_chroot t_clock_gettime
32PROGS += t_connect
32PROGS += t_dup 33PROGS += t_dup
34PROGS += t_fork
33PROGS += t_fsync 35PROGS += t_fsync
34PROGS += t_getgroups t_getitimer t_getlogin t_getpid t_getrusage 36PROGS += t_getgroups t_getitimer t_getlogin t_getpid t_getrusage
35PROGS += t_getsid t_getsockname t_gettimeofday 37PROGS += t_getsid t_getsockname t_gettimeofday
38PROGS += t_kevent
36PROGS += t_kill 39PROGS += t_kill
37PROGS += t_link t_listen 40PROGS += t_link t_listen
38PROGS += t_mkdir t_mkfifo t_mknod t_mlock t_mmap 41PROGS += t_minherit
39PROGS += t_msgctl t_msgget t_msgrcv t_msgsnd t_msync 42PROGS += t_mkdir
40PROGS += t_pipe t_pipe2 t_poll t_ptrace 43PROGS += t_mkfifo
44PROGS += t_mknod
45PROGS += t_mlock
46PROGS += t_mmap
47PROGS += t_msgctl
48PROGS += t_msgget
49PROGS += t_msgrcv
50PROGS += t_msgsnd
51PROGS += t_msync
52PROGS += t_pipe
53PROGS += t_pipe2
54PROGS += t_poll
55PROGS += t_ppoll
56PROGS += t_ptrace
41PROGS += t_revoke 57PROGS += t_revoke
42PROGS += t_select t_sendrecv t_setuid t_socketpair t_sigaction t_stat 58PROGS += t_select
59PROGS += t_sendrecv
60PROGS += t_setrlimit
61PROGS += t_setuid
62PROGS += t_sigaction
63PROGS += t_sigaltstack
64PROGS += t_socketpair
65PROGS += t_stat
43PROGS += t_syscall 66PROGS += t_syscall
44PROGS += t_truncate 67PROGS += t_truncate
45PROGS += t_umask t_unlink 68PROGS += t_umask t_unlink
69PROGS += t_wait_noproc
70PROGS += t_wait_noproc_wnohang
46PROGS += t_write 71PROGS += t_write
47 72
48# failing tests 73# failing tests
diff --git a/src/regress/lib/libc/sys/README b/src/regress/lib/libc/sys/README
index 0f7d82e7b6..5606fcaa15 100644
--- a/src/regress/lib/libc/sys/README
+++ b/src/regress/lib/libc/sys/README
@@ -3,24 +3,33 @@ Regression tests for system calls ported from NetBSD.
3Reimplement ATF with many hacks to adjust the tests as little as possible. 3Reimplement ATF with many hacks to adjust the tests as little as possible.
4 4
5Tests passing without source file adjustments: 5Tests passing without source file adjustments:
6t_access t_getpid t_link t_msgsnd t_sigaction 6t_access t_getsockname t_msgctl t_sigaltstack
7t_bind t_getsid t_listen t_msync t_socketpair 7t_bind t_gettimeofday t_msgsnd t_socketpair
8t_getgroups t_getsockname t_mkdir t_pipe t_truncate 8t_conect t_kill t_msync t_truncate
9t_getitimer t_gettimeofday t_mkfifo t_sendrecv t_umask 9t_getgroups t_link t_pipe t_umask
10t_getlogin t_kill t_msgctl t_setuid t_write 10t_getitimer t_listen t_ppoll t_write
11t_getlogin t_minherit t_sendrecv
12t_getpid t_mkdir t_setuid
13t_getsid t_mkfifo t_sigaction
11 14
12Tests passing after adjustments: 15Tests passing after adjustments:
13t_chroot - fchroot is not implemented 16t_chroot - fchroot is not implemented
14t_clock_gettime - requires sysctlbyname 17t_clock_gettime - requires sysctlbyname
15t_dup - OpenBSD dup3 is similar to Linux dup3 18t_dup - OpenBSD dup3 is similar to Linux dup3
16t_fsync - replace mkstemp 19t_fork - add reallocarr function, remove clone(2) tests
17t_getrusage - no expected fail, PR kern/30115 is NetBSD, work more 20t_fsync - replace mkstemp
18t_mknod - remove tests for unsupported file types 21t_getrusage - no expected fail, PR kern/30115 is NetBSD, work more
19t_msgget - remove msgget_limit test 22t_kevent - no EVFILT_USER, DRVCTLDEV, passing kqueue forbidden
20t_poll - remove pollts_* tests 23t_mknod - remove tests for unsupported file types
21t_ptrace - change EPERM -> EINVAL for PT_ATTACH of a parent 24t_msgget - remove msgget_limit test
22t_revoke - remove basic tests, revoke only on ttys supported 25t_poll - remove pollts_* tests
23t_select - remove sigset_t struct as it is int on OpenBSD 26t_ptrace - change EPERM -> EINVAL for PT_ATTACH of a parent
27t_revoke - remove basic tests, revoke only on ttys supported
28t_select - remove sigset_t struct as it is int on OpenBSD
29t_setrlimit - remove unsupported resource parameters and lwp
30t_syscall - add __syscall prototype
31t_wait_noproc - waitid and wait6 are not implemented
32t_wait_noproc_wnohang - waitid and wait6 are not implemented
24 33
25Failing tests: 34Failing tests:
26t_mlock - wrong errno, succeeds where not expected, POSIX imprecise 35t_mlock - wrong errno, succeeds where not expected, POSIX imprecise
@@ -28,40 +37,37 @@ t_mmap - ENOTBLK on test NetBSD is skipping, remove mmap_va0 test
28t_msgrcv - msgrcv(id, &r, 3 - 1, 0x41, 004000) != -1 37t_msgrcv - msgrcv(id, &r, 3 - 1, 0x41, 004000) != -1
29t_pipe2 - closefrom(4) == -1, remove F_GETNOSIGPIPE and nosigpipe test 38t_pipe2 - closefrom(4) == -1, remove F_GETNOSIGPIPE and nosigpipe test
30t_stat - invalid GID with doas 39t_stat - invalid GID with doas
31t_syscall - SIGSEGV
32t_unlink - wrong errno according to POSIX 40t_unlink - wrong errno according to POSIX
41t_vfork - !(((status) & 0177) == 0) evaluated to false, SIGSTOP wrong
33 42
34Excluded tests: 43Excluded tests:
35t_clock_nanosleep - not available 44t_clock_nanosleep - not available
36t_clone - not available 45t_clone - not available
37t_connect - 46t_futex_ops - no lwp
38t_fork - 47t_futex_robust - no lwp
39t_getcontext - 48t_getcontext - not available, removed in POSIX.1-2008
40t_issetugid - 49t_getrandom - not available
41t_kevent - 50t_issetugid - works as iplemented
42t_lwp_create - not available 51t_lwp_create - not available
43t_lwp_ctl - not available 52t_lwp_ctl - not available
44t_mincore - removed 53t_mincore - removed
45t_minherit - 54t_mprotect - no exec_prot_support and no return_one in libc
46t_mprotect -
47t_nanosleep - not available 55t_nanosleep - not available
48t_posix_fadvise - 56t_pollts - not available
49t_posix_fallocate - 57t_posix_fadvise - optional POSIX Advisory Information
58t_posix_fallocate - optional POSIX Advisory Information
59t_ptrace_sigchld -
50t_ptrace_wait - 60t_ptrace_wait -
51t_ptrace_wait3 - 61t_ptrace_wait3 -
52t_ptrace_wait4 - 62t_ptrace_wait4 -
53t_ptrace_wait6 - not implemented 63t_ptrace_wait6 - not implemented
54t_ptrace_waitid - 64t_ptrace_waitid -
55t_ptrace_waitpid - 65t_ptrace_waitpid -
56t_recvmmsg - 66t_recvmmsg - not implemented, not POSIX
57t_sendmmsg - 67t_sendmmsg - not implemented, not POSIX
58t_setrlimit - 68t_sigqueue - not implemented, added in POSIX.1-2004
59t_sigqueue - 69t_sigtimedwait - not implemented, added in POSIX.1-2004
60t_sigtimedwait - 70t_swapcontext - not available, removed in POSIX.1-2008
61t_swapcontext - 71t_timer_create - not implemented, added in POSIX.1-2004
62t_timer_create - 72t_ucontext - not available, removed in POSIX.1-2008
63t_ucontext - 73t_wait - wait6 is not available, not POSIX
64t_vfork -
65t_wait -
66t_wait_noproc -
67t_wait_noproc_wnohang -
diff --git a/src/regress/lib/libc/sys/atf-c.h b/src/regress/lib/libc/sys/atf-c.h
index 93e2026ca1..c10628be26 100644
--- a/src/regress/lib/libc/sys/atf-c.h
+++ b/src/regress/lib/libc/sys/atf-c.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: atf-c.h,v 1.2 2021/06/09 19:42:46 mortimer Exp $ */ 1/* $OpenBSD: atf-c.h,v 1.3 2021/09/02 12:40:44 mbuhl Exp $ */
2/* 2/*
3 * Copyright (c) 2019 Moritz Buhl <openbsd@moritzbuhl.de> 3 * Copyright (c) 2019 Moritz Buhl <openbsd@moritzbuhl.de>
4 * 4 *
@@ -76,6 +76,7 @@ ATF_TC_FUNCTIONS(fn)
76#define ATF_CHECK ATF_REQUIRE 76#define ATF_CHECK ATF_REQUIRE
77#define ATF_CHECK_MSG ATF_REQUIRE_MSG 77#define ATF_CHECK_MSG ATF_REQUIRE_MSG
78#define ATF_CHECK_EQ ATF_REQUIRE_EQ 78#define ATF_CHECK_EQ ATF_REQUIRE_EQ
79#define ATF_CHECK_ERRNO ATF_REQUIRE_ERRNO
79#define ATF_CHECK_STREQ ATF_REQUIRE_STREQ 80#define ATF_CHECK_STREQ ATF_REQUIRE_STREQ
80 81
81#define atf_req(exp, err, msg, ...) \ 82#define atf_req(exp, err, msg, ...) \
diff --git a/src/regress/lib/libc/sys/h_macros.h b/src/regress/lib/libc/sys/h_macros.h
index 227db0f31b..22f7ed83f4 100644
--- a/src/regress/lib/libc/sys/h_macros.h
+++ b/src/regress/lib/libc/sys/h_macros.h
@@ -1,3 +1,4 @@
1/* $OpenBSD: h_macros.h,v 1.2 2021/09/02 12:40:44 mbuhl Exp $ */
1/* $NetBSD: h_macros.h,v 1.13 2016/08/20 15:49:08 christos Exp $ */ 2/* $NetBSD: h_macros.h,v 1.13 2016/08/20 15:49:08 christos Exp $ */
2 3
3/*- 4/*-
diff --git a/src/regress/lib/libc/sys/macros.h b/src/regress/lib/libc/sys/macros.h
index ef858d137a..56f9ff1a1a 100644
--- a/src/regress/lib/libc/sys/macros.h
+++ b/src/regress/lib/libc/sys/macros.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: macros.h,v 1.2 2020/01/30 08:22:30 mpi Exp $ */ 1/* $OpenBSD: macros.h,v 1.3 2021/09/02 12:40:44 mbuhl Exp $ */
2/* Public domain - Moritz Buhl */ 2/* Public domain - Moritz Buhl */
3 3
4#include <sys/param.h> 4#include <sys/param.h>
@@ -49,6 +49,14 @@ sysctlbyname(char* s, void *oldp, size_t *oldlenp, void *newp, size_t newlen)
49 return sysctl(mib, miblen, oldp, oldlenp, newp, newlen); 49 return sysctl(mib, miblen, oldp, oldlenp, newp, newlen);
50} 50}
51 51
52/* t_connect.c */
53#define IPPORT_RESERVEDMAX 1023
54
55/* t_fork.c */
56#define kinfo_proc2 kinfo_proc
57#define KERN_PROC2 KERN_PROC
58#define reallocarr(pp, n, s) ((*pp = reallocarray(*pp, n, s)), *pp == NULL)
59
52/* t_mlock.c */ 60/* t_mlock.c */
53#define MAP_WIRED __MAP_NOREPLACE 61#define MAP_WIRED __MAP_NOREPLACE
54 62
@@ -63,3 +71,7 @@ sysctlbyname(char* s, void *oldp, size_t *oldlenp, void *newp, size_t newlen)
63 71
64/* t_write.c */ 72/* t_write.c */
65#define _PATH_DEVZERO "/dev/zero" 73#define _PATH_DEVZERO "/dev/zero"
74
75/* t_wait_noproc.c */
76#define ___STRING(x) #x
77#define __BIT(n) (1 << (n))
diff --git a/src/regress/lib/libc/sys/t_clock_gettime.c b/src/regress/lib/libc/sys/t_clock_gettime.c
index 206710799e..b75be63e4c 100644
--- a/src/regress/lib/libc/sys/t_clock_gettime.c
+++ b/src/regress/lib/libc/sys/t_clock_gettime.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: t_clock_gettime.c,v 1.2 2021/09/02 12:40:44 mbuhl Exp $ */
1/* $NetBSD: t_clock_gettime.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */ 2/* $NetBSD: t_clock_gettime.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */
2 3
3/*- 4/*-
diff --git a/src/regress/lib/libc/sys/t_connect.c b/src/regress/lib/libc/sys/t_connect.c
new file mode 100644
index 0000000000..c1730a40c7
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_connect.c
@@ -0,0 +1,135 @@
1/* $OpenBSD: t_connect.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_connect.c,v 1.3 2017/01/13 20:09:48 christos Exp $ */
3/*
4 * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29#include "macros.h"
30
31#include <sys/socket.h>
32#include <err.h>
33#include <errno.h>
34#include <string.h>
35#include <unistd.h>
36
37#include <arpa/inet.h>
38#include <netinet/in.h>
39
40#include "atf-c.h"
41
42ATF_TC(connect_low_port);
43ATF_TC_HEAD(connect_low_port, tc)
44{
45 atf_tc_set_md_var(tc, "descr", "Checks that low-port allocation "
46 "works");
47 atf_tc_set_md_var(tc, "require.user", "root");
48}
49ATF_TC_BODY(connect_low_port, tc)
50{
51 struct sockaddr_in sin, sinlist;
52 int sd, val, slist;
53 socklen_t slen;
54
55 slist = socket(AF_INET, SOCK_STREAM, 0);
56 sd = socket(AF_INET, SOCK_STREAM, 0);
57
58 ATF_REQUIRE(sd > 0);
59 ATF_REQUIRE(slist > 0);
60
61 /* bind listening socket */
62 memset(&sinlist, 0, sizeof(sinlist));
63 sinlist.sin_family = AF_INET;
64 sinlist.sin_port = htons(31522);
65 sinlist.sin_addr.s_addr = inet_addr("127.0.0.1");
66
67 ATF_REQUIRE_EQ(bind(slist,
68 (struct sockaddr *)&sinlist, sizeof(sinlist)), 0);
69 ATF_REQUIRE_EQ(listen(slist, 1), 0);
70
71 val = IP_PORTRANGE_LOW;
72 if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val,
73 sizeof(val)) == -1)
74 atf_tc_fail("setsockopt failed: %s", strerror(errno));
75
76 memset(&sin, 0, sizeof(sin));
77
78 sin.sin_port = htons(31522);
79 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
80 sin.sin_family = AF_INET;
81
82 if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
83 int serrno = errno;
84 atf_tc_fail("connect failed: %s%s",
85 strerror(serrno),
86 serrno != EACCES ? "" :
87 " (see http://mail-index.netbsd.org/"
88 "source-changes/2007/12/16/0011.html)");
89 }
90
91 slen = sizeof(sin);
92 ATF_REQUIRE_EQ(getsockname(sd, (struct sockaddr *)&sin, &slen), 0);
93 ATF_REQUIRE_EQ(slen, sizeof(sin));
94 ATF_REQUIRE(ntohs(sin.sin_port) <= IPPORT_RESERVEDMAX);
95
96 close(sd);
97 close(slist);
98}
99
100ATF_TC(connect_foreign_family);
101ATF_TC_HEAD(connect_foreign_family, tc)
102{
103 atf_tc_set_md_var(tc, "descr", "Checks that connecting a socket "
104 "with a different address family fails");
105}
106ATF_TC_BODY(connect_foreign_family, tc)
107{
108 struct sockaddr_in addr;
109
110 /* addr.sin_family = AF_UNSPEC = 0 */
111 memset(&addr, 0, sizeof(addr));
112
113 /*
114 * it is not necessary to initialize sin_{addr,port} since
115 * those structure members shall not be accessed if connect
116 * fails correctly.
117 */
118
119 int sock = socket(AF_LOCAL, SOCK_STREAM, 0);
120 ATF_REQUIRE(sock != -1);
121
122 ATF_REQUIRE(-1 == connect(sock, (struct sockaddr *)&addr, sizeof(addr)));
123 ATF_REQUIRE(EAFNOSUPPORT == errno);
124
125 close(sock);
126}
127
128ATF_TP_ADD_TCS(tp)
129{
130
131 ATF_TP_ADD_TC(tp, connect_low_port);
132 ATF_TP_ADD_TC(tp, connect_foreign_family);
133
134 return atf_no_error();
135}
diff --git a/src/regress/lib/libc/sys/t_fork.c b/src/regress/lib/libc/sys/t_fork.c
new file mode 100644
index 0000000000..76d66ce9d4
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_fork.c
@@ -0,0 +1,387 @@
1/* $OpenBSD: t_fork.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_fork.c,v 1.4 2019/04/06 15:41:54 kamil Exp $ */
3
4/*-
5 * Copyright (c) 2018, 2019 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29#include "macros.h"
30
31#include <sys/cdefs.h>
32__COPYRIGHT("@(#) Copyright (c) 2018, 2019\
33 The NetBSD Foundation, inc. All rights reserved.");
34__RCSID("$NetBSD: t_fork.c,v 1.4 2019/04/06 15:41:54 kamil Exp $");
35
36#include <sys/param.h>
37#include <sys/types.h>
38#include <sys/sysctl.h>
39#include <sys/wait.h>
40#include <sched.h>
41#include <signal.h>
42#include <stdbool.h>
43#include <stdlib.h>
44#include <unistd.h>
45#include <err.h>
46#include <errno.h>
47
48#include "atf-c.h"
49
50#ifdef VFORK
51#define FORK vfork
52#else
53#define FORK fork
54#endif
55
56/*
57 * A child process cannot call atf functions and expect them to magically
58 * work like in the parent.
59 * The printf(3) messaging from a child will not work out of the box as well
60 * without estabilishing a communication protocol with its parent. To not
61 * overcomplicate the tests - do not log from a child and use err(3)/errx(3)
62 * wrapped with ASSERT_EQ()/ASSERT_NEQ() as that is guaranteed to work.
63 */
64#define ASSERT_EQ(x, y) \
65do { \
66 uintmax_t vx = (x); \
67 uintmax_t vy = (y); \
68 int ret = vx == vy; \
69 if (!ret) \
70 errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: " \
71 "%s(%ju) == %s(%ju)", __FILE__, __LINE__, __func__, \
72 #x, vx, #y, vy); \
73} while (/*CONSTCOND*/0)
74
75#define ASSERT_NEQ(x, y) \
76do { \
77 uintmax_t vx = (x); \
78 uintmax_t vy = (y); \
79 int ret = vx != vy; \
80 if (!ret) \
81 errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: " \
82 "%s(%ju) != %s(%ju)", __FILE__, __LINE__, __func__, \
83 #x, vx, #y, vy); \
84} while (/*CONSTCOND*/0)
85
86static pid_t
87await_stopped_child(pid_t process)
88{
89 struct kinfo_proc2 *p = NULL;
90 size_t i, len;
91 pid_t child = -1;
92
93 int name[] = {
94 [0] = CTL_KERN,
95 [1] = KERN_PROC2,
96 [2] = KERN_PROC_ALL,
97 [3] = 0,
98 [4] = sizeof(struct kinfo_proc2),
99 [5] = 0
100 };
101
102 const size_t namelen = __arraycount(name);
103
104 /* Await the process becoming a zombie */
105 while(1) {
106 name[5] = 0;
107
108 ASSERT_EQ(sysctl(name, namelen, 0, &len, NULL, 0), 0);
109
110 ASSERT_EQ(reallocarr(&p, len, sizeof(struct kinfo_proc2)), 0);
111
112 name[5] = len;
113
114 ASSERT_EQ(sysctl(name, namelen, p, &len, NULL, 0), 0);
115
116 for (i = 0; i < len/sizeof(struct kinfo_proc2); i++) {
117 if (p[i].p_pid == getpid())
118 continue;
119 if (p[i].p_ppid != process)
120 continue;
121#ifndef __OpenBSD__
122 if (p[i].p_stat != LSSTOP)
123 continue;
124#endif
125 child = p[i].p_pid;
126 break;
127 }
128
129 if (child != -1)
130 break;
131
132 ASSERT_EQ(usleep(1000), 0);
133 }
134
135 /* Free the buffer */
136 ASSERT_EQ(reallocarr(&p, 0, sizeof(struct kinfo_proc2)), 0);
137
138 return child;
139}
140
141static void
142raise_raw(int sig)
143{
144 int rv, status;
145 pid_t child, parent, watcher, wpid;
146 int expect_core = (sig == SIGABRT) ? 1 : 0;
147
148 /*
149 * Spawn a dedicated thread to watch for a stopped child and emit
150 * the SIGKILL signal to it.
151 *
152 * This is required in vfork(2)ing parent and optional in fork(2).
153 *
154 * vfork(2) might clobber watcher, this means that it's safer and
155 * simpler to reparent this process to initproc and forget about it.
156 */
157 if (sig == SIGSTOP
158#ifndef VFORK
159 || (sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
160#endif
161 ) {
162
163 parent = getpid();
164
165 watcher = fork();
166 ATF_REQUIRE(watcher != 1);
167 if (watcher == 0) {
168 /* Double fork(2) trick to reparent to initproc */
169 watcher = fork();
170 ASSERT_NEQ(watcher, -1);
171 if (watcher != 0)
172 _exit(0);
173
174 child = await_stopped_child(parent);
175
176 errno = 0;
177 rv = kill(child, SIGKILL);
178 ASSERT_EQ(rv, 0);
179 ASSERT_EQ(errno, 0);
180
181 /* This exit value will be collected by initproc */
182 _exit(0);
183 }
184
185 wpid = waitpid(watcher, &status, 0);
186
187 ATF_REQUIRE_EQ(wpid, watcher);
188
189 ATF_REQUIRE(WIFEXITED(status));
190 ATF_REQUIRE(!WIFCONTINUED(status));
191 ATF_REQUIRE(!WIFSIGNALED(status));
192 ATF_REQUIRE(!WIFSTOPPED(status));
193 ATF_REQUIRE_EQ(WEXITSTATUS(status), 0);
194 }
195
196 child = FORK();
197 ATF_REQUIRE(child != 1);
198 if (child == 0) {
199 rv = raise(sig);
200 ASSERT_EQ(rv, 0);
201 _exit(0);
202 }
203 wpid = waitpid(child, &status, 0);
204
205 ATF_REQUIRE_EQ(wpid, child);
206
207 switch (sig) {
208 case SIGKILL:
209 case SIGABRT:
210 case SIGHUP:
211 ATF_REQUIRE(!WIFEXITED(status));
212 ATF_REQUIRE(!WIFCONTINUED(status));
213 ATF_REQUIRE(WIFSIGNALED(status));
214 ATF_REQUIRE(!WIFSTOPPED(status));
215 ATF_REQUIRE_EQ(WTERMSIG(status), sig);
216 ATF_REQUIRE_EQ(!!WCOREDUMP(status), expect_core);
217 break;
218#ifdef VFORK
219 case SIGTSTP:
220 case SIGTTIN:
221 case SIGTTOU:
222#endif
223 case SIGCONT:
224 ATF_REQUIRE(WIFEXITED(status));
225 ATF_REQUIRE(!WIFCONTINUED(status));
226 ATF_REQUIRE(!WIFSIGNALED(status));
227 ATF_REQUIRE(!WIFSTOPPED(status));
228 ATF_REQUIRE_EQ(WEXITSTATUS(status), 0);
229 break;
230#ifndef VFORK
231 case SIGTSTP:
232 case SIGTTIN:
233 case SIGTTOU:
234#endif
235 case SIGSTOP:
236 ATF_REQUIRE(!WIFEXITED(status));
237 ATF_REQUIRE(!WIFCONTINUED(status));
238 ATF_REQUIRE(WIFSIGNALED(status));
239 ATF_REQUIRE(!WIFSTOPPED(status));
240 ATF_REQUIRE_EQ(WTERMSIG(status), SIGKILL);
241 ATF_REQUIRE_EQ(!!WCOREDUMP(status), 0);
242 }
243}
244
245#define RAISE(test, sig) \
246ATF_TC(test); \
247ATF_TC_HEAD(test, tc) \
248{ \
249 \
250 atf_tc_set_md_var(tc, "descr", \
251 "raise " #sig " in a child"); \
252} \
253 \
254ATF_TC_BODY(test, tc) \
255{ \
256 \
257 raise_raw(sig); \
258}
259
260RAISE(raise1, SIGKILL) /* non-maskable */
261RAISE(raise2, SIGSTOP) /* non-maskable */
262RAISE(raise3, SIGTSTP) /* ignored in vfork(2) */
263RAISE(raise4, SIGTTIN) /* ignored in vfork(2) */
264RAISE(raise5, SIGTTOU) /* ignored in vfork(2) */
265RAISE(raise6, SIGABRT) /* regular abort trap */
266RAISE(raise7, SIGHUP) /* hangup */
267RAISE(raise8, SIGCONT) /* continued? */
268
269/// ----------------------------------------------------------------------------
270
271static int
272clone_func(void *arg __unused)
273{
274
275 return 0;
276}
277
278static void
279nested_raw(const char *fn, volatile int flags)
280{
281 int status;
282 pid_t child, child2, wpid;
283 const size_t stack_size = 1024 * 1024;
284 void *stack, *stack_base;
285
286 stack = malloc(stack_size);
287 ATF_REQUIRE(stack != NULL);
288
289#ifdef __MACHINE_STACK_GROWS_UP
290 stack_base = stack;
291#else
292 stack_base = (char *)stack + stack_size;
293#endif
294
295 flags |= SIGCHLD;
296
297 child = FORK();
298 ATF_REQUIRE(child != 1);
299 if (child == 0) {
300 if (strcmp(fn, "fork") == 0)
301 child2 = fork();
302 else if (strcmp(fn, "vfork") == 0)
303 child2 = vfork();
304#ifndef __OpenBSD__
305 else if (strcmp(fn, "clone") == 0)
306 child2 = __clone(clone_func, stack_base, flags, NULL);
307#endif
308 else
309 __unreachable();
310
311 ASSERT_NEQ(child2, -1);
312
313 if ((strcmp(fn, "fork") == 0) || (strcmp(fn, "vfork") == 0)) {
314 if (child2 == 0)
315 _exit(0);
316 }
317
318 wpid = waitpid(child2, &status, 0);
319 ASSERT_EQ(child2, wpid);
320 ASSERT_EQ(!!WIFEXITED(status), true);
321 ASSERT_EQ(!!WIFCONTINUED(status), false);
322 ASSERT_EQ(!!WIFSIGNALED(status), false);
323 ASSERT_EQ(!!WIFSTOPPED(status), false);
324 ASSERT_EQ(WEXITSTATUS(status), 0);
325
326 _exit(0);
327 }
328 wpid = waitpid(child, &status, 0);
329
330 ATF_REQUIRE_EQ(wpid, child);
331 ATF_REQUIRE_EQ(!!WIFEXITED(status), true);
332 ATF_REQUIRE_EQ(!!WIFCONTINUED(status), false);
333 ATF_REQUIRE_EQ(!!WIFSIGNALED(status), false);
334 ATF_REQUIRE_EQ(!!WIFSTOPPED(status), false);
335 ATF_REQUIRE_EQ(WEXITSTATUS(status), 0);
336}
337
338#define NESTED(test, fn, flags) \
339ATF_TC(test); \
340ATF_TC_HEAD(test, tc) \
341{ \
342 \
343 atf_tc_set_md_var(tc, "descr", \
344 "Test nested " #fn " in a child"); \
345} \
346 \
347ATF_TC_BODY(test, tc) \
348{ \
349 \
350 nested_raw(#fn, flags); \
351}
352
353NESTED(nested_fork, fork, 0)
354NESTED(nested_vfork, vfork, 0)
355#ifndef __OpenBSD__
356NESTED(nested_clone, clone, 0)
357NESTED(nested_clone_vm, clone, CLONE_VM)
358NESTED(nested_clone_fs, clone, CLONE_FS)
359NESTED(nested_clone_files, clone, CLONE_FILES)
360//NESTED(nested_clone_sighand, clone, CLONE_SIGHAND) // XXX
361NESTED(nested_clone_vfork, clone, CLONE_VFORK)
362#endif
363
364ATF_TP_ADD_TCS(tp)
365{
366 ATF_TP_ADD_TC(tp, raise1);
367 ATF_TP_ADD_TC(tp, raise2);
368 ATF_TP_ADD_TC(tp, raise3);
369 ATF_TP_ADD_TC(tp, raise4);
370 ATF_TP_ADD_TC(tp, raise5);
371 ATF_TP_ADD_TC(tp, raise6);
372 ATF_TP_ADD_TC(tp, raise7);
373 ATF_TP_ADD_TC(tp, raise8);
374
375 ATF_TP_ADD_TC(tp, nested_fork);
376 ATF_TP_ADD_TC(tp, nested_vfork);
377#ifndef __OpenBSD__
378 ATF_TP_ADD_TC(tp, nested_clone);
379 ATF_TP_ADD_TC(tp, nested_clone_vm);
380 ATF_TP_ADD_TC(tp, nested_clone_fs);
381 ATF_TP_ADD_TC(tp, nested_clone_files);
382// ATF_TP_ADD_TC(tp, nested_clone_sighand); // XXX
383 ATF_TP_ADD_TC(tp, nested_clone_vfork);
384#endif
385
386 return atf_no_error();
387}
diff --git a/src/regress/lib/libc/sys/t_kevent.c b/src/regress/lib/libc/sys/t_kevent.c
new file mode 100644
index 0000000000..171e1f3dc9
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_kevent.c
@@ -0,0 +1,236 @@
1/* $OpenBSD: t_kevent.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_kevent.c,v 1.9 2020/10/31 01:08:32 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundatiom
9 * by Christos Zoulas.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32#include "macros.h"
33
34#include <sys/cdefs.h>
35__RCSID("$NetBSD: t_kevent.c,v 1.9 2020/10/31 01:08:32 christos Exp $");
36
37#include <sys/types.h>
38#include <sys/event.h>
39
40#include "atf-c.h"
41#include <errno.h>
42#include <time.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
47#include <fcntl.h>
48#include <err.h>
49#ifndef __OpenBSD__
50#include <sys/drvctlio.h>
51#endif
52#include <sys/event.h>
53#include <sys/time.h>
54#include <sys/socket.h>
55#include <sys/wait.h>
56
57ATF_TC(kevent_zerotimer);
58ATF_TC_HEAD(kevent_zerotimer, tc)
59{
60 atf_tc_set_md_var(tc, "descr", "Checks that kevent with a 0 timer "
61 "does not crash the system (PR lib/45618)");
62}
63
64ATF_TC_BODY(kevent_zerotimer, tc)
65{
66 struct kevent ev;
67 int kq;
68
69 ATF_REQUIRE((kq = kqueue()) != -1);
70 EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0);
71 ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) != -1);
72 ATF_REQUIRE(kevent(kq, NULL, 0, &ev, 1, NULL) == 1);
73}
74
75ATF_TC(kqueue_desc_passing);
76ATF_TC_HEAD(kqueue_desc_passing, tc)
77{
78 atf_tc_set_md_var(tc, "descr", "Checks that passing a kqueue to "
79 "another process does not crash the kernel (PR 46463)");
80}
81
82ATF_TC_BODY(kqueue_desc_passing, tc)
83{
84 pid_t child;
85 int s[2], storage, status, kq;
86 struct cmsghdr *msg;
87 struct iovec iov;
88 struct msghdr m;
89 struct kevent ev;
90
91 ATF_REQUIRE((kq = kqueue()) != -1);
92
93 // atf_tc_skip("crashes kernel (PR kern/46463)");
94
95 ATF_REQUIRE(socketpair(AF_LOCAL, SOCK_STREAM, 0, s) != -1);
96 msg = malloc(CMSG_SPACE(sizeof(int)));
97 m.msg_iov = &iov;
98 m.msg_iovlen = 1;
99 m.msg_name = NULL;
100 m.msg_namelen = 0;
101 m.msg_control = msg;
102 m.msg_controllen = CMSG_SPACE(sizeof(int));
103
104 child = fork();
105 if (child == 0) {
106#ifdef __OpenBSD__
107 sleep(1);
108 exit(0);
109#endif
110 close(s[0]);
111
112 iov.iov_base = &storage;
113 iov.iov_len = sizeof(int);
114 m.msg_iov = &iov;
115 m.msg_iovlen = 1;
116
117 if (recvmsg(s[1], &m, 0) == -1)
118 err(1, "child: could not recvmsg");
119
120 kq = *(int *)CMSG_DATA(msg);
121 printf("child (pid %d): received kq fd %d\n", getpid(), kq);
122 exit(0);
123 }
124
125 close(s[1]);
126
127 iov.iov_base = &storage;
128 iov.iov_len = sizeof(int);
129
130 msg->cmsg_level = SOL_SOCKET;
131 msg->cmsg_type = SCM_RIGHTS;
132 msg->cmsg_len = CMSG_LEN(sizeof(int));
133
134 *(int *)CMSG_DATA(msg) = kq;
135
136 EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0);
137 ATF_CHECK(kevent(kq, &ev, 1, NULL, 0, NULL) != -1);
138
139 printf("parent (pid %d): sending kq fd %d\n", getpid(), kq);
140 if (sendmsg(s[0], &m, 0) == -1) {
141#ifdef __OpenBSD__
142 ATF_REQUIRE_EQ_MSG(errno, EINVAL, "errno is %d", errno);
143#else
144 ATF_REQUIRE_EQ_MSG(errno, EBADF, "errno is %d", errno);
145 atf_tc_skip("PR kern/46523");
146#endif
147 }
148
149 close(kq);
150
151 waitpid(child, &status, 0);
152 ATF_CHECK(WIFEXITED(status) && WEXITSTATUS(status)==0);
153}
154
155#ifndef __OpenBSD__
156ATF_TC(kqueue_unsupported_fd);
157ATF_TC_HEAD(kqueue_unsupported_fd, tc)
158{
159 atf_tc_set_md_var(tc, "descr", "Checks that watching an fd whose"
160 " type is not supported does not crash the kernel");
161}
162
163ATF_TC_BODY(kqueue_unsupported_fd, tc)
164{
165 /* mqueue and semaphore use fnullop_kqueue also */
166 int fd, kq;
167 struct kevent ev;
168
169 fd = open(DRVCTLDEV, O_RDONLY);
170 if (fd == -1) {
171 switch (errno) {
172 case ENOENT:
173 case ENXIO:
174 atf_tc_skip("no " DRVCTLDEV " available for testing");
175 break;
176 }
177 }
178 ATF_REQUIRE(fd != -1);
179 ATF_REQUIRE((kq = kqueue()) != -1);
180
181 EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
182 NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
183 NOTE_RENAME|NOTE_REVOKE, 0, 0);
184
185 ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) == -1);
186 ATF_REQUIRE_ERRNO(EOPNOTSUPP, true);
187
188 (void)close(fd);
189 (void)close(kq);
190}
191
192ATF_TC(kqueue_EVFILT_USER);
193ATF_TC_HEAD(kqueue_EVFILT_USER, tc)
194{
195 atf_tc_set_md_var(tc, "descr", "Checks usability of EVFILT_USER");
196}
197
198ATF_TC_BODY(kqueue_EVFILT_USER, tc)
199{
200 /* mqueue and semaphore use fnullop_kqueue also */
201 int kq;
202 struct kevent ev, rev;
203
204 ATF_REQUIRE((kq = kqueue()) != -1);
205
206 EV_SET(&ev, 666, EVFILT_USER, EV_ADD | EV_ENABLE, 0, 0, 0);
207 ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) == 0);
208 EV_SET(&ev, 666, EVFILT_USER, 0, NOTE_FFCOPY | NOTE_TRIGGER | 8, 0, 0);
209 ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) == 0);
210 const struct timespec timeout = {
211 .tv_sec = 1,
212 .tv_nsec = 0,
213 };
214
215 ATF_REQUIRE(kevent(kq, NULL, 0, &rev, 1, &timeout) == 1);
216 ATF_REQUIRE(rev.ident == 666);
217 ATF_REQUIRE(rev.filter == EVFILT_USER);
218 ATF_REQUIRE(rev.fflags == 8);
219 (void)close(kq);
220}
221#endif
222
223
224
225ATF_TP_ADD_TCS(tp)
226{
227
228 ATF_TP_ADD_TC(tp, kevent_zerotimer);
229 ATF_TP_ADD_TC(tp, kqueue_desc_passing);
230#ifndef __OpenBSD__
231 ATF_TP_ADD_TC(tp, kqueue_unsupported_fd);
232 ATF_TP_ADD_TC(tp, kqueue_EVFILT_USER);
233#endif
234
235 return atf_no_error();
236}
diff --git a/src/regress/lib/libc/sys/t_minherit.c b/src/regress/lib/libc/sys/t_minherit.c
new file mode 100644
index 0000000000..dd9ddf1d1e
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_minherit.c
@@ -0,0 +1,203 @@
1/* $OpenBSD: t_minherit.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $ */
3
4/*-
5 * Copyright (c) 2014 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Christos Zoulas
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32#include "macros.h"
33
34#include <sys/cdefs.h>
35__RCSID("$NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $");
36
37#include <sys/param.h>
38#include <sys/mman.h>
39#include <sys/sysctl.h>
40#include <sys/wait.h>
41
42#include <errno.h>
43#include <fcntl.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
47
48#include "atf-c.h"
49
50static long page;
51
52static void *
53makemap(int v, int f) {
54 void *map = mmap(NULL, page, PROT_READ|PROT_WRITE,
55 MAP_SHARED|MAP_ANON, -1, 0);
56 ATF_REQUIRE(map != MAP_FAILED);
57 memset(map, v, page);
58 if (f != 666)
59 ATF_REQUIRE(minherit(map, page, f) == 0);
60 else
61 ATF_REQUIRE(minherit(map, page, f) == -1);
62 return map;
63}
64
65ATF_TC(minherit_copy);
66ATF_TC_HEAD(minherit_copy, tc)
67{
68 atf_tc_set_md_var(tc, "descr",
69 "Test for MAP_INHERIT_COPY from minherit(2)");
70}
71
72ATF_TC_BODY(minherit_copy, tc)
73{
74 void *map1 = makemap(1, MAP_INHERIT_COPY);
75 void *map2 = makemap(1, MAP_INHERIT_COPY);
76 switch (fork()) {
77 default:
78 ATF_REQUIRE(wait(NULL) != -1);
79 ATF_REQUIRE(memcmp(map1, map2, page) == 0);
80 break;
81 case -1:
82 ATF_REQUIRE(0);
83 break;
84 case 0:
85 ATF_REQUIRE(memcmp(map1, map2, page) == 0);
86 memset(map1, 0, page);
87 exit(0);
88 }
89}
90
91ATF_TC(minherit_share);
92ATF_TC_HEAD(minherit_share, tc)
93{
94 atf_tc_set_md_var(tc, "descr",
95 "Test for MAP_INHERIT_SHARE from minherit(2)");
96}
97
98ATF_TC_BODY(minherit_share, tc)
99{
100 void *map1 = makemap(1, MAP_INHERIT_SHARE);
101 void *map2 = makemap(1, MAP_INHERIT_SHARE);
102
103 switch (fork()) {
104 default:
105 ATF_REQUIRE(wait(NULL) != -1);
106 memset(map2, 0, page);
107 ATF_REQUIRE(memcmp(map1, map2, page) == 0);
108 break;
109 case -1:
110 ATF_REQUIRE(0);
111 break;
112 case 0:
113 ATF_REQUIRE(memcmp(map1, map2, page) == 0);
114 memset(map1, 0, page);
115 exit(0);
116 }
117}
118
119static void
120segv(int n) {
121 _exit(n);
122}
123
124ATF_TC(minherit_none);
125ATF_TC_HEAD(minherit_none, tc)
126{
127 atf_tc_set_md_var(tc, "descr",
128 "Test for MAP_INHERIT_NONE from minherit(2)");
129}
130
131ATF_TC_BODY(minherit_none, tc)
132{
133 void *map1 = makemap(0, MAP_INHERIT_NONE);
134 int status;
135
136 switch (fork()) {
137 default:
138 ATF_REQUIRE(wait(&status) != -1);
139 ATF_REQUIRE(WEXITSTATUS(status) == SIGSEGV);
140 break;
141 case -1:
142 ATF_REQUIRE(0);
143 break;
144 case 0:
145 ATF_REQUIRE(signal(SIGSEGV, segv) != SIG_ERR);
146 memset(map1, 0, page);
147 exit(0);
148 }
149}
150
151ATF_TC(minherit_zero);
152ATF_TC_HEAD(minherit_zero, tc)
153{
154 atf_tc_set_md_var(tc, "descr",
155 "Test for MAP_INHERIT_ZERO from minherit(2)");
156}
157
158ATF_TC_BODY(minherit_zero, tc)
159{
160 void *map1 = makemap(1, MAP_INHERIT_ZERO);
161 void *map2 = makemap(0, MAP_INHERIT_SHARE);
162
163 switch (fork()) {
164 default:
165 ATF_REQUIRE(wait(NULL) != -1);
166 memset(map2, 1, page);
167 ATF_REQUIRE(memcmp(map1, map2, page) == 0);
168 break;
169 case -1:
170 ATF_REQUIRE(0);
171 break;
172 case 0:
173 ATF_REQUIRE(memcmp(map1, map2, page) == 0);
174 memset(map1, 2, page);
175 exit(0);
176 }
177}
178
179ATF_TC(minherit_bad);
180ATF_TC_HEAD(minherit_bad, tc)
181{
182 atf_tc_set_md_var(tc, "descr",
183 "Test for bad minherit(2)");
184}
185
186ATF_TC_BODY(minherit_bad, tc)
187{
188 (void)makemap(0, 666);
189}
190
191ATF_TP_ADD_TCS(tp)
192{
193 page = sysconf(_SC_PAGESIZE);
194 ATF_REQUIRE(page >= 0);
195
196 ATF_TP_ADD_TC(tp, minherit_copy);
197 ATF_TP_ADD_TC(tp, minherit_share);
198 ATF_TP_ADD_TC(tp, minherit_none);
199 ATF_TP_ADD_TC(tp, minherit_zero);
200 ATF_TP_ADD_TC(tp, minherit_bad);
201
202 return atf_no_error();
203}
diff --git a/src/regress/lib/libc/sys/t_pollts.c b/src/regress/lib/libc/sys/t_pollts.c
new file mode 100644
index 0000000000..966b8c7721
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_pollts.c
@@ -0,0 +1,203 @@
1/* $OpenBSD: t_pollts.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_pollts.c,v 1.1 2020/07/17 15:34:17 kamil Exp $ */
3
4/*-
5 * Copyright (c) 2011, 2020 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Matthias Scheler.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32#include "macros.h"
33
34#include <sys/time.h>
35#include <sys/wait.h>
36
37#include "atf-c.h"
38#include <errno.h>
39#include <fcntl.h>
40#include <paths.h>
41#include <poll.h>
42#include <stdio.h>
43#include <signal.h>
44#include <unistd.h>
45
46#ifndef POLLTS
47#define POLLTS pollts
48#endif
49
50ATF_TC(basic);
51ATF_TC_HEAD(basic, tc)
52{
53 atf_tc_set_md_var(tc, "timeout", "10");
54 atf_tc_set_md_var(tc, "descr",
55 "Basis functionality test for ppoll(2)/pollts(2)");
56}
57
58ATF_TC_BODY(basic, tc)
59{
60 int fds[2];
61 struct pollfd pfds[2];
62 struct timespec timeout;
63 int ret;
64
65 ATF_REQUIRE_EQ(pipe(fds), 0);
66
67 pfds[0].fd = fds[0];
68 pfds[0].events = POLLIN;
69 pfds[1].fd = fds[1];
70 pfds[1].events = POLLOUT;
71
72 /* Use a timeout of 1 second. */
73 timeout.tv_sec = 1;
74 timeout.tv_nsec = 0;
75
76 /*
77 * Check that we get a timeout waiting for data on the read end
78 * of our pipe.
79 */
80 pfds[0].revents = -1;
81 pfds[1].revents = -1;
82 ATF_REQUIRE_EQ_MSG(ret = POLLTS(&pfds[0], 1, &timeout, NULL), 0,
83 "got: %d", ret);
84 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
85 ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
86
87 /* Check that the write end of the pipe as reported as ready. */
88 pfds[0].revents = -1;
89 pfds[1].revents = -1;
90 ATF_REQUIRE_EQ_MSG(ret = POLLTS(&pfds[1], 1, &timeout, NULL), 1,
91 "got: %d", ret);
92 ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
93 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
94 pfds[1].revents);
95
96 /* Check that only the write end of the pipe as reported as ready. */
97 pfds[0].revents = -1;
98 pfds[1].revents = -1;
99 ATF_REQUIRE_EQ_MSG(ret = POLLTS(pfds, 2, &timeout, NULL), 1,
100 "got: %d", ret);
101 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
102 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
103 pfds[1].revents);
104
105 /* Write data to our pipe. */
106 ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
107
108 /* Check that both ends of our pipe are reported as ready. */
109 pfds[0].revents = -1;
110 pfds[1].revents = -1;
111 ATF_REQUIRE_EQ_MSG(ret = POLLTS(pfds, 2, &timeout, NULL), 2,
112 "got: %d", ret);
113 ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
114 pfds[0].revents);
115 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
116 pfds[1].revents);
117
118 ATF_REQUIRE_EQ(close(fds[0]), 0);
119 ATF_REQUIRE_EQ(close(fds[1]), 0);
120}
121
122ATF_TC(err);
123ATF_TC_HEAD(err, tc)
124{
125 atf_tc_set_md_var(tc, "descr", "Check errors from ppoll(2)/pollts(2)");
126}
127
128ATF_TC_BODY(err, tc)
129{
130 struct timespec timeout;
131 struct pollfd pfd;
132 int fd = 0;
133
134 pfd.fd = fd;
135 pfd.events = POLLIN;
136
137 timeout.tv_sec = 1;
138 timeout.tv_nsec = 0;
139
140 errno = 0;
141 ATF_REQUIRE_ERRNO(EFAULT, POLLTS((void *)-1, 1, &timeout, NULL) == -1);
142
143 timeout.tv_sec = -1;
144 timeout.tv_nsec = -1;
145
146 errno = 0;
147 ATF_REQUIRE_ERRNO(EINVAL, POLLTS(&pfd, 1, &timeout, NULL) == -1);
148}
149
150ATF_TC(sigmask);
151ATF_TC_HEAD(sigmask, tc)
152{
153 atf_tc_set_md_var(tc, "timeout", "10");
154 atf_tc_set_md_var(tc, "descr",
155 "Check that ppoll(2)/pollts(2) restores the signal mask (PR kern/44986)");
156}
157
158ATF_TC_BODY(sigmask, tc)
159{
160 int fd;
161 struct pollfd pfd;
162 struct timespec timeout;
163 sigset_t mask;
164 int ret;
165
166 fd = open(_PATH_DEVNULL, O_RDONLY);
167 ATF_REQUIRE(fd >= 0);
168
169 pfd.fd = fd;
170 pfd.events = POLLIN;
171
172 /* Use a timeout of 1 second. */
173 timeout.tv_sec = 1;
174 timeout.tv_nsec = 0;
175
176 /* Unblock all signals. */
177 ATF_REQUIRE_EQ(sigfillset(&mask), 0);
178 ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0);
179
180 /*
181 * Check that ppoll(2)/pollts(2) immediately returns. We block *all*
182 * signals during ppoll(2)/pollts(2).
183 */
184 ATF_REQUIRE_EQ_MSG(ret = POLLTS(&pfd, 1, &timeout, &mask), 1,
185 "got: %d", ret);
186
187 /* Check that signals are now longer blocked. */
188 ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0);
189 ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0,
190 "signal mask was changed.");
191
192 ATF_REQUIRE_EQ(close(fd), 0);
193}
194
195ATF_TP_ADD_TCS(tp)
196{
197
198 ATF_TP_ADD_TC(tp, basic);
199 ATF_TP_ADD_TC(tp, err);
200 ATF_TP_ADD_TC(tp, sigmask);
201
202 return atf_no_error();
203}
diff --git a/src/regress/lib/libc/sys/t_ppoll.c b/src/regress/lib/libc/sys/t_ppoll.c
new file mode 100644
index 0000000000..c5daef1f5f
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_ppoll.c
@@ -0,0 +1,34 @@
1/* $OpenBSD: t_ppoll.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_ppoll.c,v 1.1 2020/07/17 15:34:17 kamil Exp $ */
3
4/*-
5 * Copyright (c) 2011, 2020 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Matthias Scheler.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#define POLLTS ppoll
34#include "t_pollts.c"
diff --git a/src/regress/lib/libc/sys/t_setrlimit.c b/src/regress/lib/libc/sys/t_setrlimit.c
new file mode 100644
index 0000000000..d72ec5216d
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_setrlimit.c
@@ -0,0 +1,559 @@
1/* $OpenBSD: t_setrlimit.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_setrlimit.c,v 1.7 2020/10/13 06:58:57 rin Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jukka Ruohonen.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32#include "macros.h"
33
34#include <sys/cdefs.h>
35__RCSID("$NetBSD: t_setrlimit.c,v 1.7 2020/10/13 06:58:57 rin Exp $");
36
37#include <sys/resource.h>
38#include <sys/mman.h>
39#include <sys/wait.h>
40
41#include "atf-c.h"
42#include <errno.h>
43#include <fcntl.h>
44#include <limits.h>
45#ifndef __OpenBSD__
46#include <lwp.h>
47#endif
48#include <signal.h>
49#include <stdint.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#ifndef __OpenBSD__
54#include <ucontext.h>
55#endif
56#include <unistd.h>
57
58static void sighandler(int);
59static const char path[] = "setrlimit";
60
61static const int rlimit[] = {
62#ifndef __OpenBSD__
63 RLIMIT_AS,
64#endif
65 RLIMIT_CORE,
66 RLIMIT_CPU,
67 RLIMIT_DATA,
68 RLIMIT_FSIZE,
69 RLIMIT_MEMLOCK,
70 RLIMIT_NOFILE,
71 RLIMIT_NPROC,
72 RLIMIT_RSS,
73#ifndef __OpenBSD__
74 RLIMIT_SBSIZE,
75#endif
76 RLIMIT_STACK
77};
78
79ATF_TC(setrlimit_basic);
80ATF_TC_HEAD(setrlimit_basic, tc)
81{
82 atf_tc_set_md_var(tc, "descr", "A basic soft limit test");
83}
84
85ATF_TC_BODY(setrlimit_basic, tc)
86{
87 struct rlimit res;
88 int *buf, lim;
89 size_t i;
90
91 buf = calloc(__arraycount(rlimit), sizeof(int));
92
93 if (buf == NULL)
94 atf_tc_fail("initialization failed");
95
96 for (i = lim = 0; i < __arraycount(rlimit); i++) {
97
98 (void)memset(&res, 0, sizeof(struct rlimit));
99
100 if (getrlimit(rlimit[i], &res) != 0)
101 continue;
102
103 if (res.rlim_cur == RLIM_INFINITY || res.rlim_cur == 0)
104 continue;
105
106 if (res.rlim_cur == res.rlim_max) /* An unprivileged run. */
107 continue;
108
109 buf[i] = res.rlim_cur;
110 res.rlim_cur = res.rlim_cur - 1;
111
112 if (setrlimit(rlimit[i], &res) != 0) {
113 lim = rlimit[i];
114 goto out;
115 }
116 }
117
118out:
119 for (i = 0; i < __arraycount(rlimit); i++) {
120
121 (void)memset(&res, 0, sizeof(struct rlimit));
122
123 if (buf[i] == 0)
124 continue;
125
126 if (getrlimit(rlimit[i], &res) != 0)
127 continue;
128
129 res.rlim_cur = buf[i];
130
131 (void)setrlimit(rlimit[i], &res);
132 }
133
134 if (lim != 0)
135 atf_tc_fail("failed to set limit (%d)", lim);
136 free(buf);
137}
138
139ATF_TC(setrlimit_current);
140ATF_TC_HEAD(setrlimit_current, tc)
141{
142 atf_tc_set_md_var(tc, "descr", "setrlimit(3) with current limits");
143}
144
145ATF_TC_BODY(setrlimit_current, tc)
146{
147 struct rlimit res;
148 size_t i;
149
150 for (i = 0; i < __arraycount(rlimit); i++) {
151
152 (void)memset(&res, 0, sizeof(struct rlimit));
153
154 ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0);
155 ATF_REQUIRE(setrlimit(rlimit[i], &res) == 0);
156 }
157}
158
159ATF_TC(setrlimit_err);
160ATF_TC_HEAD(setrlimit_err, tc)
161{
162 atf_tc_set_md_var(tc, "descr", "Test error conditions");
163}
164
165ATF_TC_BODY(setrlimit_err, tc)
166{
167 struct rlimit res;
168 size_t i;
169
170 for (i = 0; i < __arraycount(rlimit); i++) {
171
172 errno = 0;
173
174 ATF_REQUIRE(getrlimit(rlimit[i], (void *)0) != 0);
175 ATF_REQUIRE(errno == EFAULT);
176 }
177
178 errno = 0;
179
180 ATF_REQUIRE(getrlimit(INT_MAX, &res) != 0);
181 ATF_REQUIRE(errno == EINVAL);
182}
183
184ATF_TC_WITH_CLEANUP(setrlimit_fsize);
185ATF_TC_HEAD(setrlimit_fsize, tc)
186{
187 atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_FSIZE");
188}
189
190ATF_TC_BODY(setrlimit_fsize, tc)
191{
192 struct rlimit res;
193 int fd, sta;
194 pid_t pid;
195
196 fd = open(path, O_RDWR | O_CREAT, 0700);
197
198 if (fd < 0)
199 atf_tc_fail("initialization failed");
200
201 pid = fork();
202 ATF_REQUIRE(pid >= 0);
203
204 if (pid == 0) {
205
206 res.rlim_cur = 2;
207 res.rlim_max = 2;
208
209 if (setrlimit(RLIMIT_FSIZE, &res) != 0)
210 _exit(EXIT_FAILURE);
211
212 if (signal(SIGXFSZ, sighandler) == SIG_ERR)
213 _exit(EXIT_FAILURE);
214
215 /*
216 * The third call should generate a SIGXFSZ.
217 */
218 (void)write(fd, "X", 1);
219 (void)write(fd, "X", 1);
220 (void)write(fd, "X", 1);
221
222 _exit(EXIT_FAILURE);
223 }
224
225 (void)close(fd);
226 (void)wait(&sta);
227 (void)unlink(path);
228
229 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
230 atf_tc_fail("RLIMIT_FSIZE not enforced");
231}
232
233ATF_TC_CLEANUP(setrlimit_fsize, tc)
234{
235 (void)unlink(path);
236}
237
238static void
239sighandler(int signo)
240{
241
242 if (signo != SIGXFSZ)
243 _exit(EXIT_FAILURE);
244
245 _exit(EXIT_SUCCESS);
246}
247
248ATF_TC(setrlimit_memlock);
249ATF_TC_HEAD(setrlimit_memlock, tc)
250{
251 atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_MEMLOCK");
252}
253
254ATF_TC_BODY(setrlimit_memlock, tc)
255{
256 struct rlimit res;
257 void *buf;
258 long page;
259 pid_t pid;
260 int sta;
261
262 page = sysconf(_SC_PAGESIZE);
263 ATF_REQUIRE(page >= 0);
264
265 buf = malloc(page);
266 pid = fork();
267
268 if (buf == NULL || pid < 0)
269 atf_tc_fail("initialization failed");
270
271 if (pid == 0) {
272
273 /*
274 * Try to lock a page while
275 * RLIMIT_MEMLOCK is zero.
276 */
277 if (mlock(buf, page) != 0)
278 _exit(EXIT_FAILURE);
279
280 if (munlock(buf, page) != 0)
281 _exit(EXIT_FAILURE);
282
283 res.rlim_cur = 0;
284 res.rlim_max = 0;
285
286 if (setrlimit(RLIMIT_MEMLOCK, &res) != 0)
287 _exit(EXIT_FAILURE);
288
289 if (mlock(buf, page) != 0)
290 _exit(EXIT_SUCCESS);
291
292 (void)munlock(buf, page);
293
294 _exit(EXIT_FAILURE);
295 }
296
297 free(buf);
298
299 (void)wait(&sta);
300
301 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
302 atf_tc_fail("RLIMIT_MEMLOCK not enforced");
303}
304
305ATF_TC(setrlimit_nofile_1);
306ATF_TC_HEAD(setrlimit_nofile_1, tc)
307{
308 atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #1");
309}
310
311ATF_TC_BODY(setrlimit_nofile_1, tc)
312{
313 struct rlimit res;
314 int fd, i, rv, sta;
315 pid_t pid;
316
317 res.rlim_cur = 0;
318 res.rlim_max = 0;
319
320 pid = fork();
321 ATF_REQUIRE(pid >= 0);
322
323 if (pid == 0) {
324
325 /*
326 * Close all descriptors, set RLIMIT_NOFILE
327 * to zero, and try to open a random file.
328 * This should fail with EMFILE.
329 */
330 for (i = 0; i < 1024; i++)
331 (void)close(i);
332
333 rv = setrlimit(RLIMIT_NOFILE, &res);
334
335 if (rv != 0)
336 _exit(EXIT_FAILURE);
337
338 errno = 0;
339 fd = open("/etc/passwd", O_RDONLY);
340
341 if (fd >= 0 || errno != EMFILE)
342 _exit(EXIT_FAILURE);
343
344 _exit(EXIT_SUCCESS);
345 }
346
347 (void)wait(&sta);
348
349 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
350 atf_tc_fail("RLIMIT_NOFILE not enforced");
351}
352
353ATF_TC(setrlimit_nofile_2);
354ATF_TC_HEAD(setrlimit_nofile_2, tc)
355{
356 atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #2");
357}
358
359ATF_TC_BODY(setrlimit_nofile_2, tc)
360{
361 static const rlim_t lim = 12;
362 struct rlimit res;
363 int fd, i, rv, sta;
364 pid_t pid;
365
366 /*
367 * See that an arbitrary limit on
368 * open files is being enforced.
369 */
370 res.rlim_cur = lim;
371 res.rlim_max = lim;
372
373 pid = fork();
374 ATF_REQUIRE(pid >= 0);
375
376 if (pid == 0) {
377
378 for (i = 0; i < 1024; i++)
379 (void)close(i);
380
381 rv = setrlimit(RLIMIT_NOFILE, &res);
382
383 if (rv != 0)
384 _exit(EXIT_FAILURE);
385
386 for (i = 0; i < (int)lim; i++) {
387
388 fd = open("/etc/passwd", O_RDONLY);
389
390 if (fd < 0)
391 _exit(EXIT_FAILURE);
392 }
393
394 /*
395 * After the limit has been reached,
396 * EMFILE should again follow.
397 */
398 fd = open("/etc/passwd", O_RDONLY);
399
400 if (fd >= 0 || errno != EMFILE)
401 _exit(EXIT_FAILURE);
402
403 _exit(EXIT_SUCCESS);
404 }
405
406 (void)wait(&sta);
407
408 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
409 atf_tc_fail("RLIMIT_NOFILE not enforced");
410}
411
412ATF_TC(setrlimit_nproc);
413ATF_TC_HEAD(setrlimit_nproc, tc)
414{
415 atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NPROC");
416 atf_tc_set_md_var(tc, "require.user", "unprivileged");
417}
418
419ATF_TC_BODY(setrlimit_nproc, tc)
420{
421 struct rlimit res;
422 pid_t pid, cpid;
423 int sta;
424
425 pid = fork();
426 ATF_REQUIRE(pid >= 0);
427
428 if (pid == 0) {
429
430 /*
431 * Set RLIMIT_NPROC to zero and try to fork.
432 */
433 res.rlim_cur = 0;
434 res.rlim_max = 0;
435
436 if (setrlimit(RLIMIT_NPROC, &res) != 0)
437 _exit(EXIT_FAILURE);
438
439 cpid = fork();
440
441 if (cpid < 0)
442 _exit(EXIT_SUCCESS);
443
444 _exit(EXIT_FAILURE);
445 }
446
447 (void)waitpid(pid, &sta, 0);
448
449 if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
450 atf_tc_fail("RLIMIT_NPROC not enforced");
451}
452
453#ifndef __OpenBSD__
454
455ATF_TC(setrlimit_nthr);
456ATF_TC_HEAD(setrlimit_nthr, tc)
457{
458 atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NTHR");
459 atf_tc_set_md_var(tc, "require.user", "unprivileged");
460}
461
462static void
463func(lwpid_t *id)
464{
465 printf("thread %d\n", *id);
466 fflush(stdout);
467 _lwp_exit();
468}
469
470ATF_TC_BODY(setrlimit_nthr, tc)
471{
472 struct rlimit res;
473 lwpid_t lwpid;
474 ucontext_t c;
475
476 /*
477 * Set RLIMIT_NTHR to zero and try to create a thread.
478 */
479 res.rlim_cur = 0;
480 res.rlim_max = 0;
481 ATF_REQUIRE(setrlimit(RLIMIT_NTHR, &res) == 0);
482 ATF_REQUIRE(getcontext(&c) == 0);
483 c.uc_link = NULL;
484 sigemptyset(&c.uc_sigmask);
485 c.uc_stack.ss_flags = 0;
486 c.uc_stack.ss_size = 4096;
487 ATF_REQUIRE((c.uc_stack.ss_sp = malloc(c.uc_stack.ss_size)) != NULL);
488 makecontext(&c, func, 1, &lwpid);
489 ATF_CHECK_ERRNO(EAGAIN, _lwp_create(&c, 0, &lwpid) == -1);
490}
491#endif
492
493ATF_TC(setrlimit_perm);
494ATF_TC_HEAD(setrlimit_perm, tc)
495{
496 atf_tc_set_md_var(tc, "descr", "Test setrlimit(2) for EPERM");
497 atf_tc_set_md_var(tc, "require.user", "unprivileged");
498}
499
500ATF_TC_BODY(setrlimit_perm, tc)
501{
502 struct rlimit res;
503 size_t i;
504
505 /*
506 * Try to raise the maximum limits as an user.
507 */
508 for (i = 0; i < __arraycount(rlimit); i++) {
509
510 ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0);
511
512 if (res.rlim_max == UINT64_MAX) /* Overflow. */
513 continue;
514
515 errno = 0;
516 res.rlim_max = res.rlim_max + 1;
517
518 ATF_CHECK_ERRNO(EPERM, setrlimit(rlimit[i], &res) != 0);
519 }
520}
521
522ATF_TC(setrlimit_stack);
523ATF_TC_HEAD(setrlimit_stack, tc)
524{
525 atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_STACK");
526 atf_tc_set_md_var(tc, "require.user", "unprivileged");
527}
528
529ATF_TC_BODY(setrlimit_stack, tc)
530{
531 struct rlimit res;
532
533 /* Ensure soft limit is not bigger than hard limit */
534 res.rlim_cur = res.rlim_max = 6 * 1024 * 1024;
535 ATF_REQUIRE(setrlimit(RLIMIT_STACK, &res) == 0);
536 ATF_REQUIRE(getrlimit(RLIMIT_STACK, &res) == 0);
537 ATF_CHECK(res.rlim_cur <= res.rlim_max);
538
539}
540
541ATF_TP_ADD_TCS(tp)
542{
543
544 ATF_TP_ADD_TC(tp, setrlimit_basic);
545 ATF_TP_ADD_TC(tp, setrlimit_current);
546 ATF_TP_ADD_TC(tp, setrlimit_err);
547 ATF_TP_ADD_TC(tp, setrlimit_fsize);
548 ATF_TP_ADD_TC(tp, setrlimit_memlock);
549 ATF_TP_ADD_TC(tp, setrlimit_nofile_1);
550 ATF_TP_ADD_TC(tp, setrlimit_nofile_2);
551 ATF_TP_ADD_TC(tp, setrlimit_nproc);
552 ATF_TP_ADD_TC(tp, setrlimit_perm);
553#ifndef __OpenBSD__
554 ATF_TP_ADD_TC(tp, setrlimit_nthr);
555#endif
556 ATF_TP_ADD_TC(tp, setrlimit_stack);
557
558 return atf_no_error();
559}
diff --git a/src/regress/lib/libc/sys/t_sigaltstack.c b/src/regress/lib/libc/sys/t_sigaltstack.c
new file mode 100644
index 0000000000..ac02650296
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_sigaltstack.c
@@ -0,0 +1,102 @@
1/* $OpenBSD: t_sigaltstack.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_sigaltstack.c,v 1.2 2020/05/01 21:35:30 christos Exp $ */
3
4/*-
5 * Copyright (c) 2020 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29#include "macros.h"
30
31#include <sys/cdefs.h>
32__RCSID("$NetBSD: t_sigaltstack.c,v 1.2 2020/05/01 21:35:30 christos Exp $");
33
34#include <signal.h>
35#include <stdbool.h>
36
37#include "atf-c.h"
38
39#include "h_macros.h"
40
41static stack_t sigstk;
42static bool handler_called;
43static bool handler_use_altstack;
44
45static void
46handler(int signo __unused)
47{
48 char sp[128];
49
50 handler_called = true;
51
52 /* checking if the stack pointer is within the range of altstack */
53 if ((char *)sigstk.ss_sp <= sp &&
54 ((char *)sigstk.ss_sp + sigstk.ss_size) > sp)
55 handler_use_altstack = true;
56 else
57 handler_use_altstack = false;
58}
59
60ATF_TC(sigaltstack_onstack);
61ATF_TC_HEAD(sigaltstack_onstack, tc)
62{
63 atf_tc_set_md_var(tc, "descr",
64 "Checks for using signal stack with SA_ONSTACK");
65}
66
67ATF_TC_BODY(sigaltstack_onstack, tc)
68{
69 struct sigaction sa;
70 int i;
71
72 /* set a signal handler use alternative stack */
73 memset(&sigstk, 0, sizeof(sigstk));
74 sigstk.ss_sp = malloc(SIGSTKSZ);
75 ATF_REQUIRE(sigstk.ss_sp != NULL);
76 sigstk.ss_size = SIGSTKSZ;
77 sigstk.ss_flags = 0;
78 ATF_REQUIRE(sigaltstack(&sigstk, 0) == 0);
79
80 sigemptyset(&sa.sa_mask);
81 sa.sa_handler = handler;
82 sa.sa_flags = SA_ONSTACK;
83 sigaction(SIGUSR1, &sa, NULL);
84
85 /* test several times */
86 for (i = 1; i <= 5; i++) {
87 handler_called = false;
88 kill(getpid(), SIGUSR1);
89
90 if (!handler_called)
91 atf_tc_fail("signal handler wasn't called (count=%d)", i);
92 if (!handler_use_altstack)
93 atf_tc_fail("alternative stack wasn't used (count=%d)", i);
94 }
95}
96
97ATF_TP_ADD_TCS(tp)
98{
99 ATF_TP_ADD_TC(tp, sigaltstack_onstack);
100
101 return atf_no_error();
102}
diff --git a/src/regress/lib/libc/sys/t_syscall.c b/src/regress/lib/libc/sys/t_syscall.c
index 72ad9139d6..454905837f 100644
--- a/src/regress/lib/libc/sys/t_syscall.c
+++ b/src/regress/lib/libc/sys/t_syscall.c
@@ -1,5 +1,5 @@
1/* $OpenBSD: t_syscall.c,v 1.2 2020/11/10 14:43:14 bluhm Exp $ */ 1/* $OpenBSD: t_syscall.c,v 1.3 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_syscall.c,v 1.3 2018/05/28 07:55:56 martin Exp $ */ 2/* $NetBSD: t_syscall.c,v 1.4 2021/01/18 05:44:20 simonb Exp $ */
3 3
4/*- 4/*-
5 * Copyright (c) 2018 The NetBSD Foundation, Inc. 5 * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
33#include "macros.h" 33#include "macros.h"
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__RCSID("$NetBSD: t_syscall.c,v 1.3 2018/05/28 07:55:56 martin Exp $"); 36__RCSID("$NetBSD: t_syscall.c,v 1.4 2021/01/18 05:44:20 simonb Exp $");
37 37
38 38
39#include "atf-c.h" 39#include "atf-c.h"
@@ -84,7 +84,7 @@ ATF_TC_BODY(mmap_syscall, tc)
84 84
85 p = (const char *)syscall(SYS_mmap, 85 p = (const char *)syscall(SYS_mmap,
86 0, sizeof(secrect_data), PROT_READ, MAP_PRIVATE, fd, 0, 0, 0); 86 0, sizeof(secrect_data), PROT_READ, MAP_PRIVATE, fd, 0, 0, 0);
87 ATF_REQUIRE(p != NULL); 87 ATF_REQUIRE(p != MAP_FAILED);
88 88
89 ATF_REQUIRE(strcmp(p, secrect_data) == 0); 89 ATF_REQUIRE(strcmp(p, secrect_data) == 0);
90} 90}
@@ -110,7 +110,7 @@ ATF_TC_BODY(mmap___syscall, tc)
110 p = (const char *)__SYSCALL_TO_UINTPTR_T(__syscall(SYS_mmap, 110 p = (const char *)__SYSCALL_TO_UINTPTR_T(__syscall(SYS_mmap,
111 0, sizeof(secrect_data), PROT_READ, MAP_PRIVATE, fd, 111 0, sizeof(secrect_data), PROT_READ, MAP_PRIVATE, fd,
112 /* pad*/ 0, (off_t)0)); 112 /* pad*/ 0, (off_t)0));
113 ATF_REQUIRE(p != NULL); 113 ATF_REQUIRE(p != MAP_FAILED);
114 114
115 ATF_REQUIRE(strcmp(p, secrect_data) == 0); 115 ATF_REQUIRE(strcmp(p, secrect_data) == 0);
116} 116}
diff --git a/src/regress/lib/libc/sys/t_wait_noproc.c b/src/regress/lib/libc/sys/t_wait_noproc.c
new file mode 100644
index 0000000000..73fc7ae035
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_wait_noproc.c
@@ -0,0 +1,364 @@
1/* $OpenBSD: t_wait_noproc.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $ */
3
4/*-
5 * Copyright (c) 2016 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "macros.h"
31
32#include <sys/cdefs.h>
33__RCSID("$NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $");
34
35#include <sys/wait.h>
36#include <sys/resource.h>
37
38#include <errno.h>
39#include <stdio.h>
40
41#include "atf-c.h"
42
43#ifndef TWAIT_OPTION
44#define TWAIT_OPTION 0
45#endif
46
47#if TWAIT_OPTION == 0
48ATF_TC(wait);
49ATF_TC_HEAD(wait, tc)
50{
51 atf_tc_set_md_var(tc, "descr",
52 "Test that wait(2) returns ECHILD for no child");
53}
54
55ATF_TC_BODY(wait, tc)
56{
57 ATF_REQUIRE_ERRNO(ECHILD, wait(NULL) == -1);
58}
59#endif
60
61ATF_TC(waitpid);
62ATF_TC_HEAD(waitpid, tc)
63{
64 atf_tc_set_md_var(tc, "descr",
65 "Test that waitpid(2) returns ECHILD for WAIT_ANY and option %s",
66 ___STRING(TWAIT_OPTION));
67}
68
69ATF_TC_BODY(waitpid, tc)
70{
71 ATF_REQUIRE_ERRNO(ECHILD, waitpid(WAIT_ANY, NULL, TWAIT_OPTION) == -1);
72}
73
74#ifndef __OpenBSD__
75ATF_TC(waitid);
76ATF_TC_HEAD(waitid, tc)
77{
78 atf_tc_set_md_var(tc, "descr",
79 "Test that waitid(2) returns ECHILD for P_ALL and option %s",
80 ___STRING(TWAIT_OPTION));
81}
82
83ATF_TC_BODY(waitid, tc)
84{
85 ATF_REQUIRE_ERRNO(ECHILD,
86 waitid(P_ALL, 0, NULL,
87 WTRAPPED | WEXITED | TWAIT_OPTION) == -1);
88}
89#endif
90
91ATF_TC(wait3);
92ATF_TC_HEAD(wait3, tc)
93{
94 atf_tc_set_md_var(tc, "descr",
95 "Test that wait3(2) returns ECHILD for no child");
96}
97
98ATF_TC_BODY(wait3, tc)
99{
100 ATF_REQUIRE_ERRNO(ECHILD, wait3(NULL, TWAIT_OPTION, NULL) == -1);
101}
102
103ATF_TC(wait4);
104ATF_TC_HEAD(wait4, tc)
105{
106 atf_tc_set_md_var(tc, "descr",
107 "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s",
108 ___STRING(TWAIT_OPTION));
109}
110
111ATF_TC_BODY(wait4, tc)
112{
113 ATF_REQUIRE_ERRNO(ECHILD,
114 wait4(WAIT_ANY, NULL, TWAIT_OPTION, NULL) == -1);
115}
116
117#ifndef __OpenBSD__
118 * Adjusted for OpenBSD, not available
119 * ATF_TC(wait6);
120 * ATF_TC_HEAD(wait6, tc)
121 * {
122 * atf_tc_set_md_var(tc, "descr",
123 * "Test that wait6(2) returns ECHILD for P_ALL and option %s",
124 * ___STRING(TWAIT_OPTION));
125 * }
126 *
127 * ATF_TC_BODY(wait6, tc)
128 * {
129 * ATF_REQUIRE_ERRNO(ECHILD,
130 * wait6(P_ALL, 0, NULL,
131 * WTRAPPED | WEXITED | TWAIT_OPTION, NULL, NULL) == -1);
132 * }
133 */
134
135/*
136 * Generator of valid combinations of options
137 * Usage: i = 0; while ((o = get_options_wait6(i++)) != -1) {}
138 */
139static int
140get_options6(size_t pos)
141{
142 int rv = 0;
143 size_t n;
144 /*
145 * waitid(2) must specify at least one of WEXITED, WUNTRACED,
146 * WSTOPPED, WTRAPPED or WCONTINUED. Single option WNOWAIT
147 * isn't valid.
148 */
149 const int matrix[] = {
150 WNOWAIT, // First in order to blacklist it easily
151 WEXITED,
152 WUNTRACED,
153 WSTOPPED, // SUS compatibility, equal to WUNTRACED
154 WTRAPPED,
155 WCONTINUED
156 };
157
158 const size_t M = (1 << __arraycount(matrix)) - 1;
159 /* Skip empty and sole WNOWAIT option */
160 pos+=2;
161
162 if (pos > M)
163 return -1;
164
165 for (n = 0; n < __arraycount(matrix); n++) {
166 if (pos & __BIT(n))
167 rv |= matrix[n];
168 }
169
170 return rv;
171}
172#endif
173
174/*
175 * Generator of valid combinations of options
176 * Usage: i = 0; while ((o = get_options_wait4(i++)) != -1) {}
177 */
178static int
179get_options4(size_t pos)
180{
181 int rv = 0;
182 size_t n;
183
184 const int special[] = {
185 0,
186#ifndef __OpenBSD__
187 WALLSIG,
188 WALTSIG,
189 __WALL, // Linux compatibility, equal to WALLSIG
190 __WCLONE // Linux compatibility, equal to WALTSIG
191#endif
192 };
193
194 const int matrix[] = {
195#ifndef __OpenBSD__
196 WNOWAIT,
197 WEXITED,
198#endif
199 WUNTRACED,
200#ifndef __OpenBSD__
201 WSTOPPED, // SUS compatibility, equal to WUNTRACED
202 WTRAPPED,
203#endif
204 WCONTINUED
205 };
206
207 const size_t M = (1 << __arraycount(special)) - 1;
208
209 if (pos < __arraycount(special))
210 return special[pos];
211
212 pos -= __arraycount(special);
213
214 ++pos; /* Don't start with empty mask */
215
216 if (pos > M)
217 return -1;
218
219 for (n = 0; n < __arraycount(special); n++) {
220 if (pos & __BIT(n))
221 rv |= matrix[n];
222 }
223
224 return rv;
225}
226
227ATF_TC(waitpid_options);
228ATF_TC_HEAD(waitpid_options, tc)
229{
230 atf_tc_set_md_var(tc, "descr",
231 "Test that waitpid(2) returns ECHILD for WAIT_ANY and valid "
232 "combination of options with%s WNOHANG",
233 TWAIT_OPTION == 0 ? "out" : "");
234}
235
236ATF_TC_BODY(waitpid_options, tc)
237{
238 size_t i = 0;
239 int o;
240
241 while((o = get_options4(i++)) != -1) {
242 printf("Testing waitpid(2) with options %x\n", o);
243
244 ATF_REQUIRE_ERRNO(ECHILD,
245 waitpid(WAIT_ANY, NULL, o | TWAIT_OPTION) == -1);
246 }
247}
248
249#ifndef __OpenBSD__
250ATF_TC(waitid_options);
251ATF_TC_HEAD(waitid_options, tc)
252{
253 atf_tc_set_md_var(tc, "descr",
254 "Test that waitid(2) returns ECHILD for P_ALL and valid "
255 "combination of options with%s WNOHANG",
256 TWAIT_OPTION == 0 ? "out" : "");
257}
258
259ATF_TC_BODY(waitid_options, tc)
260{
261 size_t i = 0;
262 int o;
263
264 while((o = get_options6(i++)) != -1) {
265 printf("Testing waitid(2) with options %x\n", o);
266
267 ATF_REQUIRE_ERRNO(ECHILD,
268 waitid(P_ALL, 0, NULL, o | TWAIT_OPTION) == -1);
269 }
270}
271#endif
272
273ATF_TC(wait3_options);
274ATF_TC_HEAD(wait3_options, tc)
275{
276 atf_tc_set_md_var(tc, "descr",
277 "Test that wait3(2) returns ECHILD for no child");
278}
279
280ATF_TC_BODY(wait3_options, tc)
281{
282 size_t i = 0;
283 int o;
284
285 while((o = get_options4(i++)) != -1) {
286 printf("Testing wait3(2) with options %x\n", o);
287
288 ATF_REQUIRE_ERRNO(ECHILD,
289 wait3(NULL, o | TWAIT_OPTION, NULL) == -1);
290 }
291}
292
293ATF_TC(wait4_options);
294ATF_TC_HEAD(wait4_options, tc)
295{
296 atf_tc_set_md_var(tc, "descr",
297 "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s",
298 ___STRING(TWAIT_OPTION));
299}
300
301ATF_TC_BODY(wait4_options, tc)
302{
303 size_t i = 0;
304 int o;
305
306 while((o = get_options4(i++)) != -1) {
307 printf("Testing wait4(2) with options %x\n", o);
308
309 ATF_REQUIRE_ERRNO(ECHILD,
310 wait4(WAIT_ANY, NULL, o | TWAIT_OPTION, NULL) == -1);
311 }
312}
313
314#ifndef __OpenBSD__
315ATF_TC(wait6_options);
316ATF_TC_HEAD(wait6_options, tc)
317{
318 atf_tc_set_md_var(tc, "descr",
319 "Test that wait6(2) returns ECHILD for P_ALL and option %s",
320 ___STRING(TWAIT_OPTION));
321}
322
323ATF_TC_BODY(wait6_options, tc)
324{
325 size_t i = 0;
326 int o;
327
328 while((o = get_options6(i++)) != -1) {
329 printf("Testing wait6(2) with options %x\n", o);
330
331 ATF_REQUIRE_ERRNO(ECHILD,
332 wait6(P_ALL, 0, NULL, o | TWAIT_OPTION, NULL, NULL) == -1);
333 }
334}
335#endif
336
337ATF_TP_ADD_TCS(tp)
338{
339
340#if TWAIT_OPTION == 0
341 ATF_TP_ADD_TC(tp, wait);
342#endif
343 ATF_TP_ADD_TC(tp, waitpid);
344#ifndef __OpenBSD__
345 ATF_TP_ADD_TC(tp, waitid);
346#endif
347 ATF_TP_ADD_TC(tp, wait3);
348 ATF_TP_ADD_TC(tp, wait4);
349#ifndef __OpenBSD__
350 ATF_TP_ADD_TC(tp, wait6);
351#endif
352
353 ATF_TP_ADD_TC(tp, waitpid_options);
354#ifndef __OpenBSD__
355 ATF_TP_ADD_TC(tp, waitid_options);
356#endif
357 ATF_TP_ADD_TC(tp, wait3_options);
358 ATF_TP_ADD_TC(tp, wait4_options);
359#ifndef __OpenBSD__
360 ATF_TP_ADD_TC(tp, wait6_options);
361#endif
362
363 return atf_no_error();
364}
diff --git a/src/regress/lib/libc/sys/t_wait_noproc_wnohang.c b/src/regress/lib/libc/sys/t_wait_noproc_wnohang.c
new file mode 100644
index 0000000000..d1dcb98164
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_wait_noproc_wnohang.c
@@ -0,0 +1,31 @@
1/* $OpenBSD: t_wait_noproc_wnohang.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */
2/* $NetBSD: t_wait_noproc_wnohang.c,v 1.1 2016/11/06 15:03:30 kamil Exp $ */
3
4/*-
5 * Copyright (c) 2016 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#define TWAIT_OPTION WNOHANG
31#include "t_wait_noproc.c"