diff options
author | mbuhl <> | 2021-09-02 12:40:44 +0000 |
---|---|---|
committer | mbuhl <> | 2021-09-02 12:40:44 +0000 |
commit | e7198b4ee0ece23326da3c1f771171a6ca285eca (patch) | |
tree | 26178d4a39622725fceb2c9310410d40d4760679 /src/regress/lib/libc/sys | |
parent | d0809b5ed8cfa0c035364e0fc4076d693a68339e (diff) | |
download | openbsd-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/Makefile | 35 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/README | 82 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/atf-c.h | 3 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/h_macros.h | 1 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/macros.h | 14 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_clock_gettime.c | 1 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_connect.c | 135 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_fork.c | 387 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_kevent.c | 236 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_minherit.c | 203 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_pollts.c | 203 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_ppoll.c | 34 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_setrlimit.c | 559 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_sigaltstack.c | 102 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_syscall.c | 10 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_wait_noproc.c | 364 | ||||
-rw-r--r-- | src/regress/lib/libc/sys/t_wait_noproc_wnohang.c | 31 |
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 = | |||
29 | PROGS += t_access | 29 | PROGS += t_access |
30 | PROGS += t_bind | 30 | PROGS += t_bind |
31 | PROGS += t_chroot t_clock_gettime | 31 | PROGS += t_chroot t_clock_gettime |
32 | PROGS += t_connect | ||
32 | PROGS += t_dup | 33 | PROGS += t_dup |
34 | PROGS += t_fork | ||
33 | PROGS += t_fsync | 35 | PROGS += t_fsync |
34 | PROGS += t_getgroups t_getitimer t_getlogin t_getpid t_getrusage | 36 | PROGS += t_getgroups t_getitimer t_getlogin t_getpid t_getrusage |
35 | PROGS += t_getsid t_getsockname t_gettimeofday | 37 | PROGS += t_getsid t_getsockname t_gettimeofday |
38 | PROGS += t_kevent | ||
36 | PROGS += t_kill | 39 | PROGS += t_kill |
37 | PROGS += t_link t_listen | 40 | PROGS += t_link t_listen |
38 | PROGS += t_mkdir t_mkfifo t_mknod t_mlock t_mmap | 41 | PROGS += t_minherit |
39 | PROGS += t_msgctl t_msgget t_msgrcv t_msgsnd t_msync | 42 | PROGS += t_mkdir |
40 | PROGS += t_pipe t_pipe2 t_poll t_ptrace | 43 | PROGS += t_mkfifo |
44 | PROGS += t_mknod | ||
45 | PROGS += t_mlock | ||
46 | PROGS += t_mmap | ||
47 | PROGS += t_msgctl | ||
48 | PROGS += t_msgget | ||
49 | PROGS += t_msgrcv | ||
50 | PROGS += t_msgsnd | ||
51 | PROGS += t_msync | ||
52 | PROGS += t_pipe | ||
53 | PROGS += t_pipe2 | ||
54 | PROGS += t_poll | ||
55 | PROGS += t_ppoll | ||
56 | PROGS += t_ptrace | ||
41 | PROGS += t_revoke | 57 | PROGS += t_revoke |
42 | PROGS += t_select t_sendrecv t_setuid t_socketpair t_sigaction t_stat | 58 | PROGS += t_select |
59 | PROGS += t_sendrecv | ||
60 | PROGS += t_setrlimit | ||
61 | PROGS += t_setuid | ||
62 | PROGS += t_sigaction | ||
63 | PROGS += t_sigaltstack | ||
64 | PROGS += t_socketpair | ||
65 | PROGS += t_stat | ||
43 | PROGS += t_syscall | 66 | PROGS += t_syscall |
44 | PROGS += t_truncate | 67 | PROGS += t_truncate |
45 | PROGS += t_umask t_unlink | 68 | PROGS += t_umask t_unlink |
69 | PROGS += t_wait_noproc | ||
70 | PROGS += t_wait_noproc_wnohang | ||
46 | PROGS += t_write | 71 | PROGS += 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. | |||
3 | Reimplement ATF with many hacks to adjust the tests as little as possible. | 3 | Reimplement ATF with many hacks to adjust the tests as little as possible. |
4 | 4 | ||
5 | Tests passing without source file adjustments: | 5 | Tests passing without source file adjustments: |
6 | t_access t_getpid t_link t_msgsnd t_sigaction | 6 | t_access t_getsockname t_msgctl t_sigaltstack |
7 | t_bind t_getsid t_listen t_msync t_socketpair | 7 | t_bind t_gettimeofday t_msgsnd t_socketpair |
8 | t_getgroups t_getsockname t_mkdir t_pipe t_truncate | 8 | t_conect t_kill t_msync t_truncate |
9 | t_getitimer t_gettimeofday t_mkfifo t_sendrecv t_umask | 9 | t_getgroups t_link t_pipe t_umask |
10 | t_getlogin t_kill t_msgctl t_setuid t_write | 10 | t_getitimer t_listen t_ppoll t_write |
11 | t_getlogin t_minherit t_sendrecv | ||
12 | t_getpid t_mkdir t_setuid | ||
13 | t_getsid t_mkfifo t_sigaction | ||
11 | 14 | ||
12 | Tests passing after adjustments: | 15 | Tests passing after adjustments: |
13 | t_chroot - fchroot is not implemented | 16 | t_chroot - fchroot is not implemented |
14 | t_clock_gettime - requires sysctlbyname | 17 | t_clock_gettime - requires sysctlbyname |
15 | t_dup - OpenBSD dup3 is similar to Linux dup3 | 18 | t_dup - OpenBSD dup3 is similar to Linux dup3 |
16 | t_fsync - replace mkstemp | 19 | t_fork - add reallocarr function, remove clone(2) tests |
17 | t_getrusage - no expected fail, PR kern/30115 is NetBSD, work more | 20 | t_fsync - replace mkstemp |
18 | t_mknod - remove tests for unsupported file types | 21 | t_getrusage - no expected fail, PR kern/30115 is NetBSD, work more |
19 | t_msgget - remove msgget_limit test | 22 | t_kevent - no EVFILT_USER, DRVCTLDEV, passing kqueue forbidden |
20 | t_poll - remove pollts_* tests | 23 | t_mknod - remove tests for unsupported file types |
21 | t_ptrace - change EPERM -> EINVAL for PT_ATTACH of a parent | 24 | t_msgget - remove msgget_limit test |
22 | t_revoke - remove basic tests, revoke only on ttys supported | 25 | t_poll - remove pollts_* tests |
23 | t_select - remove sigset_t struct as it is int on OpenBSD | 26 | t_ptrace - change EPERM -> EINVAL for PT_ATTACH of a parent |
27 | t_revoke - remove basic tests, revoke only on ttys supported | ||
28 | t_select - remove sigset_t struct as it is int on OpenBSD | ||
29 | t_setrlimit - remove unsupported resource parameters and lwp | ||
30 | t_syscall - add __syscall prototype | ||
31 | t_wait_noproc - waitid and wait6 are not implemented | ||
32 | t_wait_noproc_wnohang - waitid and wait6 are not implemented | ||
24 | 33 | ||
25 | Failing tests: | 34 | Failing tests: |
26 | t_mlock - wrong errno, succeeds where not expected, POSIX imprecise | 35 | t_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 | |||
28 | t_msgrcv - msgrcv(id, &r, 3 - 1, 0x41, 004000) != -1 | 37 | t_msgrcv - msgrcv(id, &r, 3 - 1, 0x41, 004000) != -1 |
29 | t_pipe2 - closefrom(4) == -1, remove F_GETNOSIGPIPE and nosigpipe test | 38 | t_pipe2 - closefrom(4) == -1, remove F_GETNOSIGPIPE and nosigpipe test |
30 | t_stat - invalid GID with doas | 39 | t_stat - invalid GID with doas |
31 | t_syscall - SIGSEGV | ||
32 | t_unlink - wrong errno according to POSIX | 40 | t_unlink - wrong errno according to POSIX |
41 | t_vfork - !(((status) & 0177) == 0) evaluated to false, SIGSTOP wrong | ||
33 | 42 | ||
34 | Excluded tests: | 43 | Excluded tests: |
35 | t_clock_nanosleep - not available | 44 | t_clock_nanosleep - not available |
36 | t_clone - not available | 45 | t_clone - not available |
37 | t_connect - | 46 | t_futex_ops - no lwp |
38 | t_fork - | 47 | t_futex_robust - no lwp |
39 | t_getcontext - | 48 | t_getcontext - not available, removed in POSIX.1-2008 |
40 | t_issetugid - | 49 | t_getrandom - not available |
41 | t_kevent - | 50 | t_issetugid - works as iplemented |
42 | t_lwp_create - not available | 51 | t_lwp_create - not available |
43 | t_lwp_ctl - not available | 52 | t_lwp_ctl - not available |
44 | t_mincore - removed | 53 | t_mincore - removed |
45 | t_minherit - | 54 | t_mprotect - no exec_prot_support and no return_one in libc |
46 | t_mprotect - | ||
47 | t_nanosleep - not available | 55 | t_nanosleep - not available |
48 | t_posix_fadvise - | 56 | t_pollts - not available |
49 | t_posix_fallocate - | 57 | t_posix_fadvise - optional POSIX Advisory Information |
58 | t_posix_fallocate - optional POSIX Advisory Information | ||
59 | t_ptrace_sigchld - | ||
50 | t_ptrace_wait - | 60 | t_ptrace_wait - |
51 | t_ptrace_wait3 - | 61 | t_ptrace_wait3 - |
52 | t_ptrace_wait4 - | 62 | t_ptrace_wait4 - |
53 | t_ptrace_wait6 - not implemented | 63 | t_ptrace_wait6 - not implemented |
54 | t_ptrace_waitid - | 64 | t_ptrace_waitid - |
55 | t_ptrace_waitpid - | 65 | t_ptrace_waitpid - |
56 | t_recvmmsg - | 66 | t_recvmmsg - not implemented, not POSIX |
57 | t_sendmmsg - | 67 | t_sendmmsg - not implemented, not POSIX |
58 | t_setrlimit - | 68 | t_sigqueue - not implemented, added in POSIX.1-2004 |
59 | t_sigqueue - | 69 | t_sigtimedwait - not implemented, added in POSIX.1-2004 |
60 | t_sigtimedwait - | 70 | t_swapcontext - not available, removed in POSIX.1-2008 |
61 | t_swapcontext - | 71 | t_timer_create - not implemented, added in POSIX.1-2004 |
62 | t_timer_create - | 72 | t_ucontext - not available, removed in POSIX.1-2008 |
63 | t_ucontext - | 73 | t_wait - wait6 is not available, not POSIX |
64 | t_vfork - | ||
65 | t_wait - | ||
66 | t_wait_noproc - | ||
67 | t_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 | |||
42 | ATF_TC(connect_low_port); | ||
43 | ATF_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 | } | ||
49 | ATF_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 | |||
100 | ATF_TC(connect_foreign_family); | ||
101 | ATF_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 | } | ||
106 | ATF_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 | |||
128 | ATF_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) \ | ||
65 | do { \ | ||
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) \ | ||
76 | do { \ | ||
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 | |||
86 | static pid_t | ||
87 | await_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 | |||
141 | static void | ||
142 | raise_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) \ | ||
246 | ATF_TC(test); \ | ||
247 | ATF_TC_HEAD(test, tc) \ | ||
248 | { \ | ||
249 | \ | ||
250 | atf_tc_set_md_var(tc, "descr", \ | ||
251 | "raise " #sig " in a child"); \ | ||
252 | } \ | ||
253 | \ | ||
254 | ATF_TC_BODY(test, tc) \ | ||
255 | { \ | ||
256 | \ | ||
257 | raise_raw(sig); \ | ||
258 | } | ||
259 | |||
260 | RAISE(raise1, SIGKILL) /* non-maskable */ | ||
261 | RAISE(raise2, SIGSTOP) /* non-maskable */ | ||
262 | RAISE(raise3, SIGTSTP) /* ignored in vfork(2) */ | ||
263 | RAISE(raise4, SIGTTIN) /* ignored in vfork(2) */ | ||
264 | RAISE(raise5, SIGTTOU) /* ignored in vfork(2) */ | ||
265 | RAISE(raise6, SIGABRT) /* regular abort trap */ | ||
266 | RAISE(raise7, SIGHUP) /* hangup */ | ||
267 | RAISE(raise8, SIGCONT) /* continued? */ | ||
268 | |||
269 | /// ---------------------------------------------------------------------------- | ||
270 | |||
271 | static int | ||
272 | clone_func(void *arg __unused) | ||
273 | { | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static void | ||
279 | nested_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) \ | ||
339 | ATF_TC(test); \ | ||
340 | ATF_TC_HEAD(test, tc) \ | ||
341 | { \ | ||
342 | \ | ||
343 | atf_tc_set_md_var(tc, "descr", \ | ||
344 | "Test nested " #fn " in a child"); \ | ||
345 | } \ | ||
346 | \ | ||
347 | ATF_TC_BODY(test, tc) \ | ||
348 | { \ | ||
349 | \ | ||
350 | nested_raw(#fn, flags); \ | ||
351 | } | ||
352 | |||
353 | NESTED(nested_fork, fork, 0) | ||
354 | NESTED(nested_vfork, vfork, 0) | ||
355 | #ifndef __OpenBSD__ | ||
356 | NESTED(nested_clone, clone, 0) | ||
357 | NESTED(nested_clone_vm, clone, CLONE_VM) | ||
358 | NESTED(nested_clone_fs, clone, CLONE_FS) | ||
359 | NESTED(nested_clone_files, clone, CLONE_FILES) | ||
360 | //NESTED(nested_clone_sighand, clone, CLONE_SIGHAND) // XXX | ||
361 | NESTED(nested_clone_vfork, clone, CLONE_VFORK) | ||
362 | #endif | ||
363 | |||
364 | ATF_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 | |||
57 | ATF_TC(kevent_zerotimer); | ||
58 | ATF_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 | |||
64 | ATF_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 | |||
75 | ATF_TC(kqueue_desc_passing); | ||
76 | ATF_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 | |||
82 | ATF_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__ | ||
156 | ATF_TC(kqueue_unsupported_fd); | ||
157 | ATF_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 | |||
163 | ATF_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 | |||
192 | ATF_TC(kqueue_EVFILT_USER); | ||
193 | ATF_TC_HEAD(kqueue_EVFILT_USER, tc) | ||
194 | { | ||
195 | atf_tc_set_md_var(tc, "descr", "Checks usability of EVFILT_USER"); | ||
196 | } | ||
197 | |||
198 | ATF_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 | |||
225 | ATF_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 | |||
50 | static long page; | ||
51 | |||
52 | static void * | ||
53 | makemap(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 | |||
65 | ATF_TC(minherit_copy); | ||
66 | ATF_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 | |||
72 | ATF_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 | |||
91 | ATF_TC(minherit_share); | ||
92 | ATF_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 | |||
98 | ATF_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 | |||
119 | static void | ||
120 | segv(int n) { | ||
121 | _exit(n); | ||
122 | } | ||
123 | |||
124 | ATF_TC(minherit_none); | ||
125 | ATF_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 | |||
131 | ATF_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 | |||
151 | ATF_TC(minherit_zero); | ||
152 | ATF_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 | |||
158 | ATF_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 | |||
179 | ATF_TC(minherit_bad); | ||
180 | ATF_TC_HEAD(minherit_bad, tc) | ||
181 | { | ||
182 | atf_tc_set_md_var(tc, "descr", | ||
183 | "Test for bad minherit(2)"); | ||
184 | } | ||
185 | |||
186 | ATF_TC_BODY(minherit_bad, tc) | ||
187 | { | ||
188 | (void)makemap(0, 666); | ||
189 | } | ||
190 | |||
191 | ATF_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 | |||
50 | ATF_TC(basic); | ||
51 | ATF_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 | |||
58 | ATF_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 | |||
122 | ATF_TC(err); | ||
123 | ATF_TC_HEAD(err, tc) | ||
124 | { | ||
125 | atf_tc_set_md_var(tc, "descr", "Check errors from ppoll(2)/pollts(2)"); | ||
126 | } | ||
127 | |||
128 | ATF_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 | |||
150 | ATF_TC(sigmask); | ||
151 | ATF_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 | |||
158 | ATF_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 | |||
195 | ATF_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 | |||
58 | static void sighandler(int); | ||
59 | static const char path[] = "setrlimit"; | ||
60 | |||
61 | static 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 | |||
79 | ATF_TC(setrlimit_basic); | ||
80 | ATF_TC_HEAD(setrlimit_basic, tc) | ||
81 | { | ||
82 | atf_tc_set_md_var(tc, "descr", "A basic soft limit test"); | ||
83 | } | ||
84 | |||
85 | ATF_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 | |||
118 | out: | ||
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 | |||
139 | ATF_TC(setrlimit_current); | ||
140 | ATF_TC_HEAD(setrlimit_current, tc) | ||
141 | { | ||
142 | atf_tc_set_md_var(tc, "descr", "setrlimit(3) with current limits"); | ||
143 | } | ||
144 | |||
145 | ATF_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 | |||
159 | ATF_TC(setrlimit_err); | ||
160 | ATF_TC_HEAD(setrlimit_err, tc) | ||
161 | { | ||
162 | atf_tc_set_md_var(tc, "descr", "Test error conditions"); | ||
163 | } | ||
164 | |||
165 | ATF_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 | |||
184 | ATF_TC_WITH_CLEANUP(setrlimit_fsize); | ||
185 | ATF_TC_HEAD(setrlimit_fsize, tc) | ||
186 | { | ||
187 | atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_FSIZE"); | ||
188 | } | ||
189 | |||
190 | ATF_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 | |||
233 | ATF_TC_CLEANUP(setrlimit_fsize, tc) | ||
234 | { | ||
235 | (void)unlink(path); | ||
236 | } | ||
237 | |||
238 | static void | ||
239 | sighandler(int signo) | ||
240 | { | ||
241 | |||
242 | if (signo != SIGXFSZ) | ||
243 | _exit(EXIT_FAILURE); | ||
244 | |||
245 | _exit(EXIT_SUCCESS); | ||
246 | } | ||
247 | |||
248 | ATF_TC(setrlimit_memlock); | ||
249 | ATF_TC_HEAD(setrlimit_memlock, tc) | ||
250 | { | ||
251 | atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_MEMLOCK"); | ||
252 | } | ||
253 | |||
254 | ATF_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 | |||
305 | ATF_TC(setrlimit_nofile_1); | ||
306 | ATF_TC_HEAD(setrlimit_nofile_1, tc) | ||
307 | { | ||
308 | atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #1"); | ||
309 | } | ||
310 | |||
311 | ATF_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 | |||
353 | ATF_TC(setrlimit_nofile_2); | ||
354 | ATF_TC_HEAD(setrlimit_nofile_2, tc) | ||
355 | { | ||
356 | atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #2"); | ||
357 | } | ||
358 | |||
359 | ATF_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 | |||
412 | ATF_TC(setrlimit_nproc); | ||
413 | ATF_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 | |||
419 | ATF_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 | |||
455 | ATF_TC(setrlimit_nthr); | ||
456 | ATF_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 | |||
462 | static void | ||
463 | func(lwpid_t *id) | ||
464 | { | ||
465 | printf("thread %d\n", *id); | ||
466 | fflush(stdout); | ||
467 | _lwp_exit(); | ||
468 | } | ||
469 | |||
470 | ATF_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 | |||
493 | ATF_TC(setrlimit_perm); | ||
494 | ATF_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 | |||
500 | ATF_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 | |||
522 | ATF_TC(setrlimit_stack); | ||
523 | ATF_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 | |||
529 | ATF_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 | |||
541 | ATF_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 | |||
41 | static stack_t sigstk; | ||
42 | static bool handler_called; | ||
43 | static bool handler_use_altstack; | ||
44 | |||
45 | static void | ||
46 | handler(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 | |||
60 | ATF_TC(sigaltstack_onstack); | ||
61 | ATF_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 | |||
67 | ATF_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 | |||
97 | ATF_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 | ||
48 | ATF_TC(wait); | ||
49 | ATF_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 | |||
55 | ATF_TC_BODY(wait, tc) | ||
56 | { | ||
57 | ATF_REQUIRE_ERRNO(ECHILD, wait(NULL) == -1); | ||
58 | } | ||
59 | #endif | ||
60 | |||
61 | ATF_TC(waitpid); | ||
62 | ATF_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 | |||
69 | ATF_TC_BODY(waitpid, tc) | ||
70 | { | ||
71 | ATF_REQUIRE_ERRNO(ECHILD, waitpid(WAIT_ANY, NULL, TWAIT_OPTION) == -1); | ||
72 | } | ||
73 | |||
74 | #ifndef __OpenBSD__ | ||
75 | ATF_TC(waitid); | ||
76 | ATF_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 | |||
83 | ATF_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 | |||
91 | ATF_TC(wait3); | ||
92 | ATF_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 | |||
98 | ATF_TC_BODY(wait3, tc) | ||
99 | { | ||
100 | ATF_REQUIRE_ERRNO(ECHILD, wait3(NULL, TWAIT_OPTION, NULL) == -1); | ||
101 | } | ||
102 | |||
103 | ATF_TC(wait4); | ||
104 | ATF_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 | |||
111 | ATF_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 | */ | ||
139 | static int | ||
140 | get_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 | */ | ||
178 | static int | ||
179 | get_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 | |||
227 | ATF_TC(waitpid_options); | ||
228 | ATF_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 | |||
236 | ATF_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__ | ||
250 | ATF_TC(waitid_options); | ||
251 | ATF_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 | |||
259 | ATF_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 | |||
273 | ATF_TC(wait3_options); | ||
274 | ATF_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 | |||
280 | ATF_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 | |||
293 | ATF_TC(wait4_options); | ||
294 | ATF_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 | |||
301 | ATF_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__ | ||
315 | ATF_TC(wait6_options); | ||
316 | ATF_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 | |||
323 | ATF_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 | |||
337 | ATF_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" | ||