diff options
author | Renato Botelho <renato@netgate.com> | 2017-02-23 06:28:41 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2017-02-23 06:28:41 -0300 |
commit | 82ceeb2ea625cd9bff60f2863b9a0830f55b7905 (patch) | |
tree | 263ca9347bf664a4489743f9302e699ce14de1df /contrib/netbsd-tests/lib/libc/sys | |
parent | 4a05f5440acda223e6a0ec5157bc32ecc0f09ff9 (diff) | |
parent | d20dd8b36e7a565be7bfbb22aade51c8ffd753e9 (diff) | |
download | FreeBSD-src-devel.zip FreeBSD-src-devel.tar.gz |
Merge remote-tracking branch 'origin/stable/10' into develdevel
Diffstat (limited to 'contrib/netbsd-tests/lib/libc/sys')
20 files changed, 1504 insertions, 130 deletions
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_access.c b/contrib/netbsd-tests/lib/libc/sys/t_access.c index 69d2df2..c537eca 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_access.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_access.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ +/* $NetBSD: t_access.c,v 2.2 2017/01/10 22:36:29 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -29,7 +29,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); +__RCSID("$NetBSD: t_access.c,v 1.2 2017/01/10 22:36:29 christos Exp $"); + +#ifdef __FreeBSD__ +#include <sys/param.h> /* For __FreeBSD_version */ +#endif + +#include <atf-c.h> + +#include <sys/stat.h> #include <errno.h> #include <fcntl.h> @@ -38,13 +46,6 @@ __RCSID("$NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); #include <stdlib.h> #include <unistd.h> -#include <atf-c.h> - -#ifdef __FreeBSD__ -#include <sys/param.h> -#include <sys/stat.h> -#endif - static const char path[] = "access"; static const int mode[4] = { R_OK, W_OK, X_OK, F_OK }; diff --git a/contrib/netbsd-tests/lib/libc/sys/t_bind.c b/contrib/netbsd-tests/lib/libc/sys/t_bind.c new file mode 100644 index 0000000..0c6027c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_bind.c @@ -0,0 +1,78 @@ +/* $NetBSD: t_bind.c,v 1.3 2015/04/05 23:28:10 rtr Exp $ */ +/* + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <unistd.h> + +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +#include <atf-c.h> + +ATF_TC(bind_foreign_family); + +ATF_TC_HEAD(bind_foreign_family, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that binding a socket " + "with a different address family fails"); +} + +ATF_TC_BODY(bind_foreign_family, tc) +{ + struct sockaddr_in addr; + + /* addr.sin_family = AF_UNSPEC = 0 */ + memset(&addr, 0, sizeof(addr)); + + /* + * it is not necessary to initialize sin_{addr,port} since + * those structure members shall not be accessed if bind + * fails correctly. + */ + + int sock = socket(AF_LOCAL, SOCK_STREAM, 0); + ATF_REQUIRE(sock != -1); + + /* should fail but currently doesn't */ + ATF_REQUIRE(-1 == bind(sock, (struct sockaddr *)&addr, sizeof(addr))); + ATF_REQUIRE(EAFNOSUPPORT == errno); + + close(sock); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bind_foreign_family); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_chroot.c b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c index 651dc10..1f1c49b 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_chroot.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ +/* $NetBSD: t_chroot.c,v 1.2 2017/01/10 22:36:29 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -29,9 +29,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); +__RCSID("$NetBSD: t_chroot.c,v 1.2 2017/01/10 22:36:29 christos Exp $"); #include <sys/wait.h> +#include <sys/stat.h> #include <atf-c.h> #include <errno.h> @@ -42,10 +43,6 @@ __RCSID("$NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); #include <string.h> #include <unistd.h> -#ifdef __FreeBSD__ -#include <sys/stat.h> -#endif - ATF_TC(chroot_basic); ATF_TC_HEAD(chroot_basic, tc) { diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c b/contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c new file mode 100644 index 0000000..8c1fd03 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c @@ -0,0 +1,63 @@ +/* $NetBSD: t_clock_nanosleep.c,v 1.1 2016/11/11 15:30:44 njoly Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_clock_nanosleep.c,v 1.1 2016/11/11 15:30:44 njoly Exp $"); + +#include <atf-c.h> +#include <time.h> + +ATF_TC(clock_nanosleep_remain); +ATF_TC_HEAD(clock_nanosleep_remain, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Check clock_nanosleep(2) remaining time"); +} + +ATF_TC_BODY(clock_nanosleep_remain, tc) +{ + struct timespec rqtp, rmtp; + + rqtp.tv_sec = 0; rqtp.tv_nsec = 0; + rmtp.tv_sec = -1; rmtp.tv_nsec = -1; + ATF_REQUIRE(clock_nanosleep(CLOCK_REALTIME, 0, &rqtp, &rmtp) == 0); + ATF_CHECK(rmtp.tv_sec == 0 && rmtp.tv_nsec == 0); + + ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &rqtp) == 0); + rmtp.tv_sec = -1; rmtp.tv_nsec = -1; + ATF_REQUIRE(clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &rqtp, &rmtp) == 0); + ATF_CHECK(rmtp.tv_sec == -1 && rmtp.tv_nsec == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clock_nanosleep_remain); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_connect.c b/contrib/netbsd-tests/lib/libc/sys/t_connect.c index 896b490..672a022 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_connect.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_connect.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_connect.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $ */ +/* $NetBSD: t_connect.c,v 1.2 2015/04/05 23:17:41 rtr Exp $ */ /* * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. * All rights reserved. @@ -102,10 +102,39 @@ ATF_TC_BODY(connect_low_port, tc) #endif } +ATF_TC(connect_foreign_family); +ATF_TC_HEAD(connect_foreign_family, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that connecting a socket " + "with a different address family fails"); +} +ATF_TC_BODY(connect_foreign_family, tc) +{ + struct sockaddr_in addr; + + /* addr.sin_family = AF_UNSPEC = 0 */ + memset(&addr, 0, sizeof(addr)); + + /* + * it is not necessary to initialize sin_{addr,port} since + * those structure members shall not be accessed if connect + * fails correctly. + */ + + int sock = socket(AF_LOCAL, SOCK_STREAM, 0); + ATF_REQUIRE(sock != -1); + + ATF_REQUIRE(-1 == connect(sock, (struct sockaddr *)&addr, sizeof(addr))); + ATF_REQUIRE(EAFNOSUPPORT == errno); + + close(sock); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, connect_low_port); + ATF_TP_ADD_TC(tp, connect_foreign_family); return atf_no_error(); } diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c index 46c0ff1..9f21b3e 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c @@ -53,6 +53,10 @@ run(int n, ...) va_start(va, n); #if defined(__FreeBSD__) && defined(__amd64__) for (i = 0; i < 5; i++) { +#elif defined(__FreeBSD__) && defined(__aarch64__) + for (i = 0; i < 7; i++) { +#elif defined(__FreeBSD__) && defined(__mips__) + for (i = 0; i < 5; i++) { #else for (i = 0; i < 9; i++) { #endif @@ -116,6 +120,14 @@ ATF_TC_BODY(setcontext_link, tc) /* FreeBSD/amd64 only permits up to 6 arguments. */ makecontext(&uc[i], (void *)run, 6, i, 0, 1, 2, 3, 4); +#elif defined(__FreeBSD__) && defined(__aarch64__) + /* FreeBSD/arm64 only permits up to 8 arguments. */ + makecontext(&uc[i], (void *)run, 8, i, + 0, 1, 2, 3, 4, 5, 6); +#elif defined(__FreeBSD__) && defined(__mips__) + /* FreeBSD/mips only permits up to 6 arguments. */ + makecontext(&uc[i], (void *)run, 6, i, + 0, 1, 2, 3, 4); #else makecontext(&uc[i], (void *)run, 10, i, 0, 1, 2, 3, 4, 5, 6, 7, 8); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c index 85eeac6..f4ee96b 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $ */ +/* $NetBSD: t_getrusage.c,v 1.4 2016/08/05 15:01:39 scole Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $"); +__RCSID("$NetBSD: t_getrusage.c,v 1.4 2016/08/05 15:01:39 scole Exp $"); #include <sys/resource.h> #include <sys/time.h> @@ -56,6 +56,10 @@ sighandler(int signo) /* Nothing. */ } +#ifdef __FreeBSD__ +#define asm __asm +#endif + static void work(void) { @@ -64,6 +68,8 @@ work(void) while (n > 0) { #ifdef __or1k__ asm volatile("l.nop"); /* Do something. */ +#elif defined(__ia64__) + asm volatile("nop 0"); /* Do something. */ #else asm volatile("nop"); /* Do something. */ #endif diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getsockname.c b/contrib/netbsd-tests/lib/libc/sys/t_getsockname.c new file mode 100644 index 0000000..01b1f8a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getsockname.c @@ -0,0 +1,82 @@ +/* $NetBSD: t_getsockname.c,v 1.1 2016/07/30 11:03:54 njoly Exp $ */ +/* + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/socket.h> +#include <sys/un.h> + +#include <string.h> +#include <unistd.h> + +#include <atf-c.h> + +ATF_TC(getsockname_unix); + +ATF_TC_HEAD(getsockname_unix, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks getsockname with UNIX domain"); +} + +ATF_TC_BODY(getsockname_unix, tc) +{ + const char *path = "sock.unix"; + int sd; + socklen_t len; + struct sockaddr_un sun; + + sd = socket(AF_UNIX, SOCK_STREAM, 0); + ATF_REQUIRE(sd != -1); + + len = sizeof(sun); + memset(&sun, 0, sizeof(sun)); + ATF_REQUIRE(getsockname(sd, (struct sockaddr *)&sun, &len) != -1); + ATF_CHECK(sun.sun_family == AF_UNIX); + ATF_CHECK(strcmp(sun.sun_path, "") == 0); + + len = sizeof(sun); + memset(&sun, 0, sizeof(sun)); + sun.sun_family = AF_UNIX; + strcpy(sun.sun_path, path); + ATF_REQUIRE(bind(sd, (struct sockaddr *)&sun, len) != -1); + + len = sizeof(sun); + memset(&sun, 0, sizeof(sun)); + ATF_REQUIRE(getsockname(sd, (struct sockaddr *)&sun, &len) != -1); + ATF_CHECK(sun.sun_family == AF_UNIX); + ATF_CHECK(strcmp(sun.sun_path, path) == 0); + + ATF_REQUIRE(close(sd) != -1); + ATF_REQUIRE(unlink(path) != -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getsockname_unix); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kevent.c b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c index c2fef44..8a20d63 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_kevent.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $ */ +/* $NetBSD: t_kevent.c,v 1.7 2015/02/05 13:55:37 isaki Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $"); +__RCSID("$NetBSD: t_kevent.c,v 1.7 2015/02/05 13:55:37 isaki Exp $"); #include <sys/types.h> #include <sys/event.h> @@ -182,8 +182,14 @@ ATF_TC_BODY(kqueue_unsupported_fd, tc) struct kevent ev; fd = open(DRVCTLDEV, O_RDONLY); - if (fd == -1 && errno == ENOENT) - atf_tc_skip("no " DRVCTLDEV " available for testing"); + if (fd == -1) { + switch (errno) { + case ENOENT: + case ENXIO: + atf_tc_skip("no " DRVCTLDEV " available for testing"); + break; + } + } ATF_REQUIRE(fd != -1); ATF_REQUIRE((kq = kqueue()) != -1); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mincore.c b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c index c31170f..ab8c33f 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_mincore.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $ */ +/* $NetBSD: t_mincore.c,v 1.9 2017/01/10 22:36:29 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -59,9 +59,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $"); +__RCSID("$NetBSD: t_mincore.c,v 1.9 2017/01/10 22:36:29 christos Exp $"); #include <sys/mman.h> +#include <sys/stat.h> #include <sys/shm.h> #include <atf-c.h> @@ -74,10 +75,6 @@ __RCSID("$NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $"); #include <unistd.h> #include <sys/resource.h> -#ifdef __FreeBSD__ -#include <sys/stat.h> -#endif - static long page = 0; static const char path[] = "mincore"; static size_t check_residency(void *, size_t); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mlock.c b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c index 85d82c7..dcfba2b 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_mlock.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $ */ +/* $NetBSD: t_mlock.c,v 1.6 2016/08/09 12:02:44 kre Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $"); +__RCSID("$NetBSD: t_mlock.c,v 1.6 2016/08/09 12:02:44 kre Exp $"); #ifdef __FreeBSD__ #include <sys/types.h> @@ -50,86 +50,13 @@ __RCSID("$NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $"); #include <limits.h> #define _KMEMUSER #include <machine/vmparam.h> + +void set_vm_max_wired(int); +void restore_vm_max_wired(void); #endif static long page = 0; -#ifdef __FreeBSD__ -#define VM_MAX_WIRED "vm.max_wired" - -static void -vm_max_wired_sysctl(int *old_value, int *new_value) -{ - size_t old_len; - size_t new_len = (new_value == NULL ? 0 : sizeof(int)); - - if (old_value == NULL) - printf("Setting the new value to %d\n", *new_value); - else { - ATF_REQUIRE_MSG(sysctlbyname(VM_MAX_WIRED, NULL, &old_len, - new_value, new_len) == 0, - "sysctlbyname(%s) failed: %s", VM_MAX_WIRED, strerror(errno)); - } - - ATF_REQUIRE_MSG(sysctlbyname(VM_MAX_WIRED, old_value, &old_len, - new_value, new_len) == 0, - "sysctlbyname(%s) failed: %s", VM_MAX_WIRED, strerror(errno)); - - if (old_value != NULL) - printf("Saved the old value (%d)\n", *old_value); -} - -static void -set_vm_max_wired(int new_value) -{ - FILE *fp; - int old_value; - - fp = fopen(VM_MAX_WIRED, "w"); - if (fp == NULL) { - atf_tc_skip("could not open %s for writing: %s", - VM_MAX_WIRED, strerror(errno)); - return; - } - - vm_max_wired_sysctl(&old_value, NULL); - - ATF_REQUIRE_MSG(fprintf(fp, "%d", old_value) > 0, - "saving %s failed", VM_MAX_WIRED); - - fclose(fp); - - vm_max_wired_sysctl(NULL, &new_value); -} - -static void -restore_vm_max_wired(void) -{ - FILE *fp; - int saved_max_wired; - - fp = fopen(VM_MAX_WIRED, "r"); - if (fp == NULL) { - perror("fopen failed\n"); - return; - } - - if (fscanf(fp, "%d", &saved_max_wired) != 1) { - perror("fscanf failed\n"); - fclose(fp); - return; - } - - fclose(fp); - printf("old value in %s: %d\n", VM_MAX_WIRED, saved_max_wired); - - if (saved_max_wired == 0) /* This will cripple the test host */ - return; - - vm_max_wired_sysctl(NULL, &saved_max_wired); -} -#endif - ATF_TC(mlock_clip); ATF_TC_HEAD(mlock_clip, tc) { @@ -178,6 +105,7 @@ ATF_TC_BODY(mlock_err, tc) #endif void *invalid_ptr; int null_errno = ENOMEM; /* error expected for NULL */ + void *buf; #ifdef __FreeBSD__ #ifdef VM_MIN_ADDRESS @@ -189,28 +117,48 @@ ATF_TC_BODY(mlock_err, tc) #else if (sysctlbyname("vm.minaddress", &vmin, &len, NULL, 0) != 0) atf_tc_fail("failed to read vm.minaddress"); + /* + * Any bad address must return ENOMEM (for lock & unlock) + */ + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mlock(NULL, page) == -1); if (vmin > 0) null_errno = EINVAL; /* NULL is not inside user VM */ #endif errno = 0; - ATF_REQUIRE_ERRNO(null_errno, mlock(NULL, page) == -1); + ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)0, page) == -1); errno = 0; - ATF_REQUIRE_ERRNO(null_errno, mlock((char *)0, page) == -1); + ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)-1, page) == -1); errno = 0; - ATF_REQUIRE_ERRNO(EINVAL, mlock((char *)-1, page) == -1); + ATF_REQUIRE_ERRNO(ENOMEM, munlock(NULL, page) == -1); errno = 0; - ATF_REQUIRE_ERRNO(null_errno, munlock(NULL, page) == -1); + ATF_REQUIRE_ERRNO(ENOMEM, munlock((char *)0, page) == -1); errno = 0; - ATF_REQUIRE_ERRNO(null_errno, munlock((char *)0, page) == -1); + ATF_REQUIRE_ERRNO(ENOMEM, munlock((char *)-1, page) == -1); + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + /* + * unlocking memory that is not locked is an error... + */ errno = 0; - ATF_REQUIRE_ERRNO(EINVAL, munlock((char *)-1, page) == -1); + ATF_REQUIRE_ERRNO(ENOMEM, munlock(buf, page) == -1); + + /* + * These are permitted to fail (EINVAL) but do not on NetBSD + */ + ATF_REQUIRE(mlock((void *)(((uintptr_t)buf) + page/3), page/5) == 0); + ATF_REQUIRE(munlock((void *)(((uintptr_t)buf) + page/3), page/5) == 0); + + (void)free(buf); /* * Try to create a pointer to an unmapped page - first after current diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mmap.c b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c index 5d821ec..738758c 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_mmap.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $ */ +/* $NetBSD: t_mmap.c,v 1.10 2017/01/10 22:36:29 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -55,10 +55,11 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $"); +__RCSID("$NetBSD: t_mmap.c,v 1.10 2017/01/10 22:36:29 christos Exp $"); #include <sys/param.h> #include <sys/mman.h> +#include <sys/stat.h> #include <sys/socket.h> #include <sys/sysctl.h> #include <sys/wait.h> @@ -78,7 +79,6 @@ __RCSID("$NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $"); #ifdef __FreeBSD__ #include <sys/disklabel.h> -#include <sys/stat.h> #include <stdint.h> #endif @@ -381,9 +381,13 @@ ATF_TC_BODY(mmap_prot_3, tc) * the access should generate SIGSEGV. */ fd = open(path, O_RDWR | O_CREAT, 0700); - if (fd < 0) +#ifdef __FreeBSD__ + atf_tc_skip("opening %s failed; skipping testcase: %s", + path, strerror(errno)); +#else return; +#endif ATF_REQUIRE(write(fd, "XXX", 3) == 3); ATF_REQUIRE(close(fd) == 0); @@ -409,6 +413,9 @@ ATF_TC_BODY(mmap_prot_3, tc) ATF_REQUIRE(WIFEXITED(sta) != 0); ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); ATF_REQUIRE(munmap(map, 3) == 0); +#ifdef __FreeBSD__ + (void)close(fd); +#endif } ATF_TC_CLEANUP(mmap_prot_3, tc) @@ -453,6 +460,9 @@ ATF_TC_BODY(mmap_truncate, tc) ATF_REQUIRE(ftruncate(fd, page / 12) == 0); ATF_REQUIRE(ftruncate(fd, page / 64) == 0); +#ifdef __FreeBSD__ + (void)munmap(map, page); +#endif ATF_REQUIRE(close(fd) == 0); } @@ -461,6 +471,76 @@ ATF_TC_CLEANUP(mmap_truncate, tc) (void)unlink(path); } +ATF_TC_WITH_CLEANUP(mmap_truncate_signal); +ATF_TC_HEAD(mmap_truncate_signal, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mmap(2) ftruncate(2) causing signal"); +} + +ATF_TC_BODY(mmap_truncate_signal, tc) +{ + char *map; + long i; + int fd, sta; + pid_t pid; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("testcase fails with SIGSEGV on FreeBSD; bug # 211924"); +#endif + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + return; + + ATF_REQUIRE(write(fd, "foo\n", 5) == 5); + + map = mmap(NULL, page, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + sta = 0; + for (i = 0; i < 5; i++) + sta += map[i]; + ATF_REQUIRE(sta == 334); + + ATF_REQUIRE(ftruncate(fd, 0) == 0); + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGBUS, map_sighandler) != SIG_ERR); + ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR); + sta = 0; + for (i = 0; i < page; i++) + sta += map[i]; + /* child never will get this far, but the compiler will + not know, so better use the values calculated to + prevent the access to be optimized out */ + ATF_REQUIRE(i == 0); + ATF_REQUIRE(sta == 0); +#ifdef __FreeBSD__ + (void)munmap(map, page); + (void)close(fd); +#endif + return; + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + if (WEXITSTATUS(sta) == SIGSEGV) + atf_tc_fail("child process got SIGSEGV instead of SIGBUS"); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGBUS); + ATF_REQUIRE(munmap(map, page) == 0); + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mmap_truncate_signal, tc) +{ + (void)unlink(path); +} + ATF_TC(mmap_va0); ATF_TC_HEAD(mmap_va0, tc) { @@ -518,6 +598,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, mmap_prot_2); ATF_TP_ADD_TC(tp, mmap_prot_3); ATF_TP_ADD_TC(tp, mmap_truncate); + ATF_TP_ADD_TC(tp, mmap_truncate_signal); ATF_TP_ADD_TC(tp, mmap_va0); return atf_no_error(); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c index ee345aa..5dc3eae 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $ */ +/* $NetBSD: t_mprotect.c,v 1.4 2016/05/28 14:34:49 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $"); +__RCSID("$NetBSD: t_mprotect.c,v 1.4 2016/05/28 14:34:49 christos Exp $"); #include <sys/param.h> #include <sys/mman.h> @@ -78,10 +78,7 @@ paxinit(void) rv = sysctlbyname("security.pax.mprotect.enabled", &pax_enabled, &len, NULL, 0); - if (rv != 0) - return false; - - return paxset(1, 1); + return rv == 0; } static bool @@ -194,6 +191,12 @@ ATF_TC_BODY(mprotect_exec, tc) break; } + if (!paxinit()) + return; + if (pax_enabled == 1 && pax_global == 1) + atf_tc_skip("PaX MPROTECT restrictions enabled"); + + /* * Map a page read/write and copy a trivial assembly function inside. * We will then change the mapping rights: @@ -262,7 +265,7 @@ ATF_TC_BODY(mprotect_pax, tc) size_t i; int rv; - if (paxinit() != true) + if (!paxinit() || !paxset(1, 1)) return; /* diff --git a/contrib/netbsd-tests/lib/libc/sys/t_posix_fallocate.c b/contrib/netbsd-tests/lib/libc/sys/t_posix_fallocate.c new file mode 100644 index 0000000..b931ebd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_posix_fallocate.c @@ -0,0 +1,63 @@ +/* $NetBSD: t_posix_fallocate.c,v 1.1 2015/01/31 23:06:57 christos Exp $ */ + +/*- + * Copyright 2015, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_posix_fallocate.c,v 1.1 2015/01/31 23:06:57 christos Exp $"); + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + +ATF_TC_WITHOUT_HEAD(ebadf); +ATF_TC_BODY(ebadf, tc) +{ + int rc, saved; + + errno = 1111; + rc = posix_fallocate(-1, 0, 4096); + saved = errno; + if (rc == -1 && saved != 1111) + atf_tc_fail("Should return error %s without setting errno.", + strerror(saved)); + if (rc != EBADF) + atf_tc_fail("returned %s but expected %s.", + strerror(saved), strerror(EBADF)); + if (saved != 1111) + atf_tc_fail("errno should be %d but got changed to %d.", + 1111, saved); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, ebadf); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c index 4b21860..31db878 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $ */ +/* $NetBSD: t_setrlimit.c,v 1.5 2016/07/13 09:53:16 njoly Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $"); +__RCSID("$NetBSD: t_setrlimit.c,v 1.5 2016/07/13 09:53:16 njoly Exp $"); #include <sys/resource.h> #include <sys/mman.h> @@ -50,6 +50,11 @@ __RCSID("$NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $"); #include <ucontext.h> #include <unistd.h> +#ifdef __FreeBSD__ +void set_vm_max_wired(int); +void restore_vm_max_wired(void); +#endif + static void sighandler(int); static const char path[] = "setrlimit"; @@ -238,10 +243,18 @@ sighandler(int signo) _exit(EXIT_SUCCESS); } +#ifdef __FreeBSD__ +ATF_TC_WITH_CLEANUP(setrlimit_memlock); +#else ATF_TC(setrlimit_memlock); +#endif ATF_TC_HEAD(setrlimit_memlock, tc) { atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_MEMLOCK"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects"); + atf_tc_set_md_var(tc, "require.user", "root"); +#endif } ATF_TC_BODY(setrlimit_memlock, tc) @@ -252,6 +265,11 @@ ATF_TC_BODY(setrlimit_memlock, tc) pid_t pid; int sta; +#ifdef __FreeBSD__ + /* Set max_wired really really high to avoid EAGAIN */ + set_vm_max_wired(INT_MAX); +#endif + page = sysconf(_SC_PAGESIZE); ATF_REQUIRE(page >= 0); @@ -295,6 +313,14 @@ ATF_TC_BODY(setrlimit_memlock, tc) atf_tc_fail("RLIMIT_MEMLOCK not enforced"); } +#ifdef __FreeBSD__ +ATF_TC_CLEANUP(setrlimit_memlock, tc) +{ + + restore_vm_max_wired(); +} +#endif + ATF_TC(setrlimit_nofile_1); ATF_TC_HEAD(setrlimit_nofile_1, tc) { @@ -515,6 +541,25 @@ ATF_TC_BODY(setrlimit_perm, tc) } } +ATF_TC(setrlimit_stack); +ATF_TC_HEAD(setrlimit_stack, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_STACK"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setrlimit_stack, tc) +{ + struct rlimit res; + + /* Ensure soft limit is not bigger than hard limit */ + res.rlim_cur = res.rlim_max = 4192256; + ATF_REQUIRE(setrlimit(RLIMIT_STACK, &res) == 0); + ATF_REQUIRE(getrlimit(RLIMIT_STACK, &res) == 0); + ATF_CHECK(res.rlim_cur <= res.rlim_max); + +} + ATF_TP_ADD_TCS(tp) { @@ -530,6 +575,7 @@ ATF_TP_ADD_TCS(tp) #ifdef __NetBSD__ ATF_TP_ADD_TC(tp, setrlimit_nthr); #endif + ATF_TP_ADD_TC(tp, setrlimit_stack); return atf_no_error(); } diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c index 6686f02..e911d42 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c @@ -1,4 +1,4 @@ -/* $NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $ */ +/* $NetBSD: t_sigqueue.c,v 1.6 2016/08/04 06:43:43 christos Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -30,8 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $"); - +__RCSID("$NetBSD: t_sigqueue.c,v 1.6 2016/08/04 06:43:43 christos Exp $"); #include <atf-c.h> #include <errno.h> @@ -40,6 +39,11 @@ __RCSID("$NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $"); #include <sched.h> #include <unistd.h> +#ifdef __FreeBSD__ +#include <err.h> +#include <stdio.h> +#endif + static void handler(int, siginfo_t *, void *); #define VALUE (int)0xc001dad1 @@ -77,7 +81,7 @@ ATF_TC_BODY(sigqueue_basic, tc) sv.sival_int = VALUE; #ifdef __FreeBSD__ - /* + /* * From kern_sig.c: * Specification says sigqueue can only send signal to single process. */ @@ -99,17 +103,158 @@ ATF_TC_HEAD(sigqueue_err, tc) ATF_TC_BODY(sigqueue_err, tc) { - union sigval sv; + static union sigval sv; errno = 0; ATF_REQUIRE_ERRNO(EINVAL, sigqueue(getpid(), -1, sv) == -1); } +static int signals[] = { + SIGINT, SIGRTMIN + 1, SIGINT, SIGRTMIN + 0, SIGRTMIN + 2, + SIGQUIT, SIGRTMIN + 1 +}; +#ifdef __arraycount +#define CNT __arraycount(signals) +#else +#define CNT (sizeof(signals) / sizeof(signals[0])) +#endif + +static sig_atomic_t count = 0; +static int delivered[CNT]; + +static void +myhandler(int signo, siginfo_t *info, void *context) +{ + delivered[count++] = signo; +#ifdef __FreeBSD__ + printf("Signal #%zu: signo: %d\n", (size_t)count, signo); +#endif +} + +static int +asc(const void *a, const void *b) +{ + const int *ia = a, *ib = b; + return *ib - *ia; +} + +/* + * given a array of signals to be delivered in tosend of size len + * place in ordered the signals to be delivered in delivery order + * and return the number of signals that should be delivered + */ +static size_t +sigorder(int *ordered, const int *tosend, size_t len) +{ + memcpy(ordered, tosend, len * sizeof(*tosend)); + qsort(ordered, len, sizeof(*ordered), asc); + if (len == 1) + return len; + +#ifdef __FreeBSD__ + /* + * Don't dedupe signal numbers (bug 212173) + * + * Per kib's comment.. + * + * " + * OTOH, FreeBSD behaviour is to treat all signals as realtime while + * there is no mem shortage and siginfo can be allocated. In + * particular, signals < SIGRTMIN are not collapsed when queued more + * than once. + * " + */ + + return len; +#else + + size_t i, j; + for (i = 0, j = 0; i < len - 1; i++) { + if (ordered[i] >= SIGRTMIN) + continue; + if (j == 0) + j = i + 1; + while (ordered[i] == ordered[j] && j < len) + j++; + if (j == len) + break; + ordered[i + 1] = ordered[j]; + } + return i + 1; +#endif +} + +ATF_TC(sigqueue_rt); +ATF_TC_HEAD(sigqueue_rt, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test queuing of real-time signals"); +} + +ATF_TC_BODY(sigqueue_rt, tc) +{ + pid_t pid; + union sigval val; + struct sigaction act; + int ordered[CNT]; + struct sigaction oact[CNT]; + size_t ndelivered; + + ndelivered = sigorder(ordered, signals, CNT); + + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = myhandler; + sigemptyset(&act.sa_mask); + for (size_t i = 0; i < ndelivered; i++) + ATF_REQUIRE(sigaction(ordered[i], &act, &oact[i]) != -1); + + val.sival_int = 0; + pid = getpid(); + + sigset_t mask, orig; + sigemptyset(&mask); + for (size_t i = 0; i < CNT; i++) +#ifdef __FreeBSD__ + if (sigaddset(&mask, signals[i]) == -1) + warn("sigaddset"); +#else + sigaddset(&mask, signals[i]); +#endif + + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &mask, &orig) != -1); + + for (size_t i = 0; i < CNT; i++) + ATF_REQUIRE(sigqueue(pid, signals[i], val) != -1); + + ATF_REQUIRE(sigprocmask(SIG_UNBLOCK, &mask, &orig) != -1); + sleep(1); +#ifdef __FreeBSD__ + ATF_CHECK_MSG((size_t)count == ndelivered, + "count %zu != ndelivered %zu", (size_t)count, ndelivered); +#else + ATF_REQUIRE_MSG((size_t)count == ndelivered, + "count %zu != ndelivered %zu", (size_t)count, ndelivered); +#endif + for (size_t i = 0; i < ndelivered; i++) + ATF_REQUIRE_MSG(ordered[i] == delivered[i], + "%zu: ordered %d != delivered %d", + i, ordered[i], delivered[i]); + +#ifdef __FreeBSD__ + if (count > ndelivered) + for (size_t i = ndelivered; i < count; i++) + printf("Undelivered signal #%zu: %d\n", i, ordered[i]); +#endif + + for (size_t i = 0; i < ndelivered; i++) + ATF_REQUIRE(sigaction(signals[i], &oact[i], NULL) != -1); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, sigqueue_basic); ATF_TP_ADD_TC(tp, sigqueue_err); + ATF_TP_ADD_TC(tp, sigqueue_rt); return atf_no_error(); } diff --git a/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c index cc85307..364daaa 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c @@ -116,6 +116,61 @@ timer_signal_create(clockid_t cid, bool expire) ATF_REQUIRE(timer_delete(t) == 0); } +#ifdef __FreeBSD__ +static void +timer_callback(union sigval value) +{ + timer_t *tp; + + tp = value.sival_ptr; + + if (*tp == t) + fail = false; +} + +static void +timer_thread_create(clockid_t cid, bool expire) +{ + struct itimerspec tim; + struct sigevent evt; + + t = 0; + fail = true; + + (void)memset(&evt, 0, sizeof(struct sigevent)); + (void)memset(&tim, 0, sizeof(struct itimerspec)); + + /* + * Create the timer (SIGEV_THREAD). + */ + evt.sigev_notify_function = timer_callback; + evt.sigev_value.sival_ptr = &t; + evt.sigev_notify = SIGEV_THREAD; + + ATF_REQUIRE(timer_create(cid, &evt, &t) == 0); + + /* + * Start the timer. + */ + tim.it_value.tv_sec = expire ? 5 : 1; + tim.it_value.tv_nsec = 0; + + ATF_REQUIRE(timer_settime(t, 0, &tim, NULL) == 0); + + (void)sleep(2); + + if (expire) { + if (!fail) + atf_tc_fail("timer fired too soon"); + } else { + if (fail) + atf_tc_fail("timer failed to fire"); + } + + ATF_REQUIRE(timer_delete(t) == 0); +} +#endif + ATF_TC(timer_create_err); ATF_TC_HEAD(timer_create_err, tc) { @@ -198,6 +253,64 @@ ATF_TC_BODY(timer_create_mono_expire, tc) timer_signal_create(CLOCK_MONOTONIC, true); } +ATF_TC(timer_thread_create_real); +ATF_TC_HEAD(timer_thread_create_real, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), " + "SIGEV_THREAD"); +} + +#ifdef __FreeBSD__ +ATF_TC_BODY(timer_thread_create_real, tc) +{ + timer_thread_create(CLOCK_REALTIME, false); +} + +ATF_TC(timer_thread_create_mono); +ATF_TC_HEAD(timer_thread_create_mono, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), " + "SIGEV_THREAD"); +} + +ATF_TC_BODY(timer_thread_create_mono, tc) +{ + timer_thread_create(CLOCK_MONOTONIC, false); +} + +ATF_TC(timer_thread_create_real_expire); +ATF_TC_HEAD(timer_thread_create_real_expire, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), " + "SIGEV_THREAD, with expiration"); +} + +ATF_TC_BODY(timer_thread_create_real_expire, tc) +{ + timer_thread_create(CLOCK_REALTIME, true); +} + +ATF_TC(timer_thread_create_mono_expire); +ATF_TC_HEAD(timer_thread_create_mono_expire, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), " + "SIGEV_THREAD, with expiration"); +} + +ATF_TC_BODY(timer_thread_create_mono_expire, tc) +{ + timer_thread_create(CLOCK_MONOTONIC, true); +} +#endif + ATF_TP_ADD_TCS(tp) { @@ -206,6 +319,12 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, timer_create_mono); ATF_TP_ADD_TC(tp, timer_create_real_expire); ATF_TP_ADD_TC(tp, timer_create_mono_expire); +#ifdef __FreeBSD__ + ATF_TP_ADD_TC(tp, timer_thread_create_real); + ATF_TP_ADD_TC(tp, timer_thread_create_mono); + ATF_TP_ADD_TC(tp, timer_thread_create_real_expire); + ATF_TP_ADD_TC(tp, timer_thread_create_mono_expire); +#endif return atf_no_error(); } diff --git a/contrib/netbsd-tests/lib/libc/sys/t_wait.c b/contrib/netbsd-tests/lib/libc/sys/t_wait.c new file mode 100644 index 0000000..8653265 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_wait.c @@ -0,0 +1,323 @@ +/* $NetBSD: t_wait.c,v 1.7 2016/11/06 15:04:14 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_wait.c,v 1.7 2016/11/06 15:04:14 kamil Exp $"); + +#include <sys/wait.h> +#include <sys/resource.h> + +#include <stdio.h> +#include <errno.h> +#include <limits.h> +#include <pwd.h> +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> + +#include <atf-c.h> + +#ifdef __FreeBSD__ +#define wrusage __wrusage +#endif + +ATF_TC(wait6_invalid); +ATF_TC_HEAD(wait6_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) returns EINVAL with 0 options"); +} + +ATF_TC_BODY(wait6_invalid, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + ATF_REQUIRE(wait6(P_ALL, 0, &st, 0, &wru, &si) == -1 + && errno == EINVAL); +} + +ATF_TC(wait6_exited); +ATF_TC_HEAD(wait6_exited, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled exiting process and code"); +} + +ATF_TC_BODY(wait6_exited, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + + switch (pid = fork()) { + case -1: + ATF_REQUIRE(pid > 0); + case 0: + exit(0x5a5a5a5a); + /*NOTREACHED*/ + default: + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(WIFEXITED(st) && WEXITSTATUS(st) == 0x5a); + ATF_REQUIRE(si.si_status = 0x5a5a5a5a); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_EXITED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + break; + } +} + +ATF_TC(wait6_terminated); +ATF_TC_HEAD(wait6_terminated, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled terminated process and code"); +} + +ATF_TC_BODY(wait6_terminated, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + + switch (pid = fork()) { + case 0: + sleep(100); + /*FALLTHROUGH*/ + case -1: + ATF_REQUIRE(pid > 0); + default: + ATF_REQUIRE(kill(pid, SIGTERM) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGTERM); + ATF_REQUIRE(si.si_status == SIGTERM); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_KILLED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + break; + } +} + +ATF_TC(wait6_coredumped); +ATF_TC_HEAD(wait6_coredumped, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled coredumped process and code"); +} + +ATF_TC_BODY(wait6_coredumped, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + static const struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; + + switch (pid = fork()) { + case 0: + ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); + *(char *)8 = 0; + /*FALLTHROUGH*/ + case -1: + ATF_REQUIRE(pid > 0); + default: + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGSEGV + && WCOREDUMP(st)); + ATF_REQUIRE(si.si_status == SIGSEGV); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_DUMPED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + break; + } +} + +ATF_TC(wait6_stop_and_go); +ATF_TC_HEAD(wait6_stop_and_go, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled stopped/continued process and code"); +} + +ATF_TC_BODY(wait6_stop_and_go, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + static const struct rlimit rl = { 0, 0 }; + + ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); + switch (pid = fork()) { + case 0: + sleep(100); + /*FALLTHROUGH*/ + case -1: + ATF_REQUIRE(pid > 0); + default: + ATF_REQUIRE(kill(pid, SIGSTOP) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(!WIFSIGNALED(st)); + ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP); + ATF_REQUIRE(!WIFCONTINUED(st)); + ATF_REQUIRE(si.si_status == SIGSTOP); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_STOPPED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + + ATF_REQUIRE(kill(pid, SIGCONT) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(!WIFSIGNALED(st)); + ATF_REQUIRE(WIFCONTINUED(st)); + ATF_REQUIRE(!WIFSTOPPED(st)); + ATF_REQUIRE(si.si_status == SIGCONT); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_CONTINUED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + + ATF_REQUIRE(kill(pid, SIGQUIT) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT); + ATF_REQUIRE(!WIFSTOPPED(st)); + ATF_REQUIRE(!WIFCONTINUED(st)); + ATF_REQUIRE(si.si_status == SIGQUIT); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_KILLED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + break; + } +} + +ATF_TC(wait6_stopgo_loop); +ATF_TC_HEAD(wait6_stopgo_loop, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled stopped/continued process loop"); +} + +ATF_TC_BODY(wait6_stopgo_loop, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + static const struct rlimit rl = { 0, 0 }; + size_t N = 100; + + ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); + switch (pid = fork()) { + case 0: + sleep(100); + /*FALLTHROUGH*/ + case -1: + ATF_REQUIRE(pid > 0); + } + + printf("Before loop of SIGSTOP/SIGCONT sequence %zu times\n", N); + while (N --> 0) { + ATF_REQUIRE(kill(pid, SIGSTOP) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(!WIFSIGNALED(st)); + ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP); + ATF_REQUIRE(!WIFCONTINUED(st)); + ATF_REQUIRE(si.si_status == SIGSTOP); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_STOPPED); + + ATF_REQUIRE(kill(pid, SIGCONT) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(!WIFSIGNALED(st)); + ATF_REQUIRE(WIFCONTINUED(st)); + ATF_REQUIRE(!WIFSTOPPED(st)); + ATF_REQUIRE(si.si_status == SIGCONT); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_CONTINUED); + } + ATF_REQUIRE(kill(pid, SIGQUIT) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT); + ATF_REQUIRE(!WIFSTOPPED(st)); + ATF_REQUIRE(!WIFCONTINUED(st)); + ATF_REQUIRE(si.si_status == SIGQUIT); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_KILLED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wait6_invalid); + ATF_TP_ADD_TC(tp, wait6_exited); + ATF_TP_ADD_TC(tp, wait6_terminated); + ATF_TP_ADD_TC(tp, wait6_coredumped); + ATF_TP_ADD_TC(tp, wait6_stop_and_go); + ATF_TP_ADD_TC(tp, wait6_stopgo_loop); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc.c b/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc.c new file mode 100644 index 0000000..e5ddcbd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc.c @@ -0,0 +1,345 @@ +/* $NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $"); + +#ifdef __FreeBSD__ +#include <sys/param.h> /* For NBBY -- it's in sys/types.h on NetBSD */ +#endif +#include <sys/wait.h> +#include <sys/resource.h> + +#include <errno.h> +#include <stdio.h> + +#include <atf-c.h> + +#ifndef TWAIT_OPTION +#define TWAIT_OPTION 0 +#endif + +#if TWAIT_OPTION == 0 +ATF_TC(wait); +ATF_TC_HEAD(wait, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait(2) returns ECHILD for no child"); +} + +ATF_TC_BODY(wait, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, wait(NULL) == -1); +} +#endif + +ATF_TC(waitpid); +ATF_TC_HEAD(waitpid, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that waitpid(2) returns ECHILD for WAIT_ANY and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(waitpid, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, waitpid(WAIT_ANY, NULL, TWAIT_OPTION) == -1); +} + +ATF_TC(waitid); +ATF_TC_HEAD(waitid, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that waitid(2) returns ECHILD for P_ALL and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(waitid, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, + waitid(P_ALL, 0, NULL, + WTRAPPED | WEXITED | TWAIT_OPTION) == -1); +} + +ATF_TC(wait3); +ATF_TC_HEAD(wait3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait3(2) returns ECHILD for no child"); +} + +ATF_TC_BODY(wait3, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, wait3(NULL, TWAIT_OPTION, NULL) == -1); +} + +ATF_TC(wait4); +ATF_TC_HEAD(wait4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(wait4, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, + wait4(WAIT_ANY, NULL, TWAIT_OPTION, NULL) == -1); +} + +ATF_TC(wait6); +ATF_TC_HEAD(wait6, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) returns ECHILD for P_ALL and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(wait6, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, + wait6(P_ALL, 0, NULL, + WTRAPPED | WEXITED | TWAIT_OPTION, NULL, NULL) == -1); +} + +/* + * Generator of valid combinations of options + * Usage: i = 0; while ((o = get_options_wait6(i++)) != -1) {} + */ +static int +get_options6(size_t pos) +{ + int rv = 0; + size_t n; + + /* + * waitid(2) must specify at least one of WEXITED, WUNTRACED, + * WSTOPPED, WTRAPPED or WCONTINUED. Single option WNOWAIT + * isn't valid. + */ + + const int matrix[] = { + WNOWAIT, /* First in order to blacklist it easily */ + WEXITED, + WUNTRACED, + WSTOPPED, /* SUS compatibility, equal to WUNTRACED */ + WTRAPPED, + WCONTINUED + }; + + const size_t M = (1 << __arraycount(matrix)) - 1; + + /* Skip empty and sole WNOWAIT option */ + pos+=2; + + if (pos > M) + return -1; + + for (n = 0; n < __arraycount(matrix); n++) { + if (pos & __BIT(n)) + rv |= matrix[n]; + } + + return rv; +} + +/* + * Generator of valid combinations of options + * Usage: i = 0; while ((o = get_options_wait4(i++)) != -1) {} + */ +static int +get_options4(size_t pos) +{ + int rv = 0; + size_t n; + + const int special[] = { + 0, +#ifdef __NetBSD__ + WALLSIG, + WALTSIG, + __WALL, /* Linux compatibility, equal to WALLSIG */ + __WCLONE /* Linux compatibility, equal to WALTSIG */ +#endif + }; + + const int matrix[] = { + WNOWAIT, + WEXITED, + WUNTRACED, + WSTOPPED, /* SUS compatibility, equal to WUNTRACED */ + WTRAPPED, + WCONTINUED + }; + + const size_t M = (1 << __arraycount(special)) - 1; + + if (pos < __arraycount(special)) + return special[pos]; + + pos -= __arraycount(special); + + ++pos; /* Don't start with empty mask */ + + if (pos > M) + return -1; + + for (n = 0; n < __arraycount(special); n++) { + if (pos & __BIT(n)) + rv |= matrix[n]; + } + + return rv; +} + +ATF_TC(waitpid_options); +ATF_TC_HEAD(waitpid_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that waitpid(2) returns ECHILD for WAIT_ANY and valid " + "combination of options with%s WNOHANG", + TWAIT_OPTION == 0 ? "out" : ""); +} + +ATF_TC_BODY(waitpid_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options4(i++)) != -1) { + printf("Testing waitpid(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + waitpid(WAIT_ANY, NULL, o | TWAIT_OPTION) == -1); + } +} + +ATF_TC(waitid_options); +ATF_TC_HEAD(waitid_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that waitid(2) returns ECHILD for P_ALL and valid " + "combination of options with%s WNOHANG", + TWAIT_OPTION == 0 ? "out" : ""); +} + +ATF_TC_BODY(waitid_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options6(i++)) != -1) { + printf("Testing waitid(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + waitid(P_ALL, 0, NULL, o | TWAIT_OPTION) == -1); + } +} + +ATF_TC(wait3_options); +ATF_TC_HEAD(wait3_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait3(2) returns ECHILD for no child"); +} + +ATF_TC_BODY(wait3_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options4(i++)) != -1) { + printf("Testing wait3(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + wait3(NULL, o | TWAIT_OPTION, NULL) == -1); + } +} + +ATF_TC(wait4_options); +ATF_TC_HEAD(wait4_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(wait4_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options4(i++)) != -1) { + printf("Testing wait4(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + wait4(WAIT_ANY, NULL, o | TWAIT_OPTION, NULL) == -1); + } +} + +ATF_TC(wait6_options); +ATF_TC_HEAD(wait6_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) returns ECHILD for P_ALL and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(wait6_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options6(i++)) != -1) { + printf("Testing wait6(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + wait6(P_ALL, 0, NULL, o | TWAIT_OPTION, NULL, NULL) == -1); + } +} + +ATF_TP_ADD_TCS(tp) +{ + +#if TWAIT_OPTION == 0 + ATF_TP_ADD_TC(tp, wait); +#endif + ATF_TP_ADD_TC(tp, waitpid); + ATF_TP_ADD_TC(tp, waitid); + ATF_TP_ADD_TC(tp, wait3); + ATF_TP_ADD_TC(tp, wait4); + ATF_TP_ADD_TC(tp, wait6); + + ATF_TP_ADD_TC(tp, waitpid_options); + ATF_TP_ADD_TC(tp, waitid_options); + ATF_TP_ADD_TC(tp, wait3_options); + ATF_TP_ADD_TC(tp, wait4_options); + ATF_TP_ADD_TC(tp, wait6_options); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc_wnohang.c b/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc_wnohang.c new file mode 100644 index 0000000..45a9998 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc_wnohang.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_wait_noproc_wnohang.c,v 1.1 2016/11/06 15:03:30 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define TWAIT_OPTION WNOHANG +#include "t_wait_noproc.c" |