Hi all, I have added ppoll(2) implementation to libc/sys, which is a wrapper around pollts(2) function (basically, pollts(2) and ppoll(2) are aliases, and NetBSD has pollts(2)). This is done to increase the compatibility with Linux, FreeBSD, OpenBSD, DragonFly and Illumos. Man page for poll(2) has been updated accordingly, new tests have been added to ATF for ppoll(2), and ppoll(2) function has been enabled in NSD (external/bsd/nsd). Please have a look on the patch attached hereby and commit it to base after a review.
Best regards, Apurva Nandan
? sys/arch/amd64/conf/QEMU Index: distrib/sets/lists/comp/mi =================================================================== RCS file: /pub/NetBSD-CVS/src/distrib/sets/lists/comp/mi,v retrieving revision 1.2322 diff -u -r1.2322 mi --- distrib/sets/lists/comp/mi 26 Apr 2020 18:53:31 -0000 1.2322 +++ distrib/sets/lists/comp/mi 24 May 2020 22:15:32 -0000 @@ -4511,6 +4511,7 @@ ./usr/share/man/cat2/posix_fadvise.0 comp-c-catman .cat ./usr/share/man/cat2/posix_fallocate.0 comp-c-catman .cat ./usr/share/man/cat2/posix_madvise.0 comp-c-catman .cat +./usr/share/man/cat2/ppoll.0 comp-c-catman .cat ./usr/share/man/cat2/pread.0 comp-c-catman .cat ./usr/share/man/cat2/preadv.0 comp-c-catman .cat ./usr/share/man/cat2/profil.0 comp-c-catman .cat @@ -12597,6 +12598,7 @@ ./usr/share/man/html2/posix_fadvise.html comp-c-htmlman html ./usr/share/man/html2/posix_fallocate.html comp-c-htmlman html ./usr/share/man/html2/posix_madvise.html comp-c-htmlman html +./usr/share/man/html2/ppoll.html comp-c-htmlman html ./usr/share/man/html2/pread.html comp-c-htmlman html ./usr/share/man/html2/preadv.html comp-c-htmlman html ./usr/share/man/html2/profil.html comp-c-htmlman html @@ -20511,6 +20513,7 @@ ./usr/share/man/man2/posix_fadvise.2 comp-c-man .man ./usr/share/man/man2/posix_fallocate.2 comp-c-man .man ./usr/share/man/man2/posix_madvise.2 comp-c-man .man +./usr/share/man/man2/ppoll.2 comp-c-man .man ./usr/share/man/man2/pread.2 comp-c-man .man ./usr/share/man/man2/preadv.2 comp-c-man .man ./usr/share/man/man2/profil.2 comp-c-man .man Index: distrib/sets/lists/debug/mi =================================================================== RCS file: /pub/NetBSD-CVS/src/distrib/sets/lists/debug/mi,v retrieving revision 1.307 diff -u -r1.307 mi --- distrib/sets/lists/debug/mi 26 Apr 2020 21:05:36 -0000 1.307 +++ distrib/sets/lists/debug/mi 24 May 2020 22:15:33 -0000 @@ -2157,8 +2157,10 @@ ./usr/libdata/debug/usr/tests/lib/libc/sys/t_pipe.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/sys/t_pipe2.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/sys/t_poll.debug tests-lib-debug debug,atf,compattestfile +./usr/libdata/debug/usr/tests/lib/libc/sys/t_pollts.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/sys/t_posix_fadvise.debug tests-lib-debug debug,atf,rump ./usr/libdata/debug/usr/tests/lib/libc/sys/t_posix_fallocate.debug tests-lib-debug debug,atf,compattestfile +./usr/libdata/debug/usr/tests/lib/libc/sys/t_ppoll.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/sys/t_ptrace.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/sys/t_ptrace_sigchld.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libc/sys/t_ptrace_wait.debug tests-lib-debug debug,atf,compattestfile Index: distrib/sets/lists/tests/mi =================================================================== RCS file: /pub/NetBSD-CVS/src/distrib/sets/lists/tests/mi,v retrieving revision 1.837 diff -u -r1.837 mi --- distrib/sets/lists/tests/mi 26 Apr 2020 18:53:32 -0000 1.837 +++ distrib/sets/lists/tests/mi 24 May 2020 22:15:34 -0000 @@ -3155,8 +3155,10 @@ ./usr/tests/lib/libc/sys/t_pipe tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/sys/t_pipe2 tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/sys/t_poll tests-lib-tests compattestfile,atf +./usr/tests/lib/libc/sys/t_pollts tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/sys/t_posix_fadvise tests-lib-tests atf,rump ./usr/tests/lib/libc/sys/t_posix_fallocate tests-lib-tests compattestfile,atf +./usr/tests/lib/libc/sys/t_ppoll tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/sys/t_ptrace tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/sys/t_ptrace_sigchld tests-lib-tests compattestfile,atf ./usr/tests/lib/libc/sys/t_ptrace_wait tests-lib-tests compattestfile,atf Index: external/bsd/nsd/include/config.h =================================================================== RCS file: /pub/NetBSD-CVS/src/external/bsd/nsd/include/config.h,v retrieving revision 1.8 diff -u -r1.8 config.h --- external/bsd/nsd/include/config.h 15 Dec 2019 16:26:04 -0000 1.8 +++ external/bsd/nsd/include/config.h 24 May 2020 22:16:46 -0000 @@ -249,7 +249,7 @@ #define HAVE_OPENSSL_SSL_H 1 /* Define to 1 if you have the `ppoll' function. */ -/* #undef HAVE_PPOLL */ +#define HAVE_PPOLL 1 /* Define to 1 if you have the `pselect' function. */ #define HAVE_PSELECT 1 Index: lib/libc/include/namespace.h =================================================================== RCS file: /pub/NetBSD-CVS/src/lib/libc/include/namespace.h,v retrieving revision 1.198 diff -u -r1.198 namespace.h --- lib/libc/include/namespace.h 18 Apr 2020 23:55:50 -0000 1.198 +++ lib/libc/include/namespace.h 24 May 2020 22:18:53 -0000 @@ -558,6 +558,7 @@ #define popen _popen #define posix2time _posix2time #define posix2time_z _posix2time_z +#define ppoll _ppoll #define pread _pread #define printf_l _printf_l #define pselect _pselect Index: lib/libc/sys/Makefile.inc =================================================================== RCS file: /pub/NetBSD-CVS/src/lib/libc/sys/Makefile.inc,v retrieving revision 1.242 diff -u -r1.242 Makefile.inc --- lib/libc/sys/Makefile.inc 22 Sep 2019 22:59:38 -0000 1.242 +++ lib/libc/sys/Makefile.inc 24 May 2020 22:18:53 -0000 @@ -8,8 +8,8 @@ SRCS+= cpuset.c # glue to offer userland wrappers for some syscalls SRCS+= accept4.c clock_getcpuclockid.c posix_fadvise.c posix_madvise.c \ - sched.c sigqueue.c sigtimedwait.c sigwait.c sigwaitinfo.c statvfs.c \ - swapon.c semctl.c vadvise.c + ppoll.c sched.c sigqueue.c sigtimedwait.c sigwait.c sigwaitinfo.c \ + statvfs.c swapon.c semctl.c vadvise.c .if ${RUMPRUN} != "yes" # modules with non-default implementations on at least one architecture: @@ -353,7 +353,7 @@ MLINKS+=open.2 openat.2 MLINKS+=ntp_adjtime.2 ntp_gettime.2 MLINKS+=pathconf.2 fpathconf.2 -MLINKS+=poll.2 pollts.2 +MLINKS+=poll.2 pollts.2 poll.2 ppoll.2 MLINKS+=read.2 readv.2 read.2 pread.2 read.2 preadv.2 MLINKS+=readlink.2 readlinkat.2 MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2 recv.2 recvmmsg.2 Index: lib/libc/sys/poll.2 =================================================================== RCS file: /pub/NetBSD-CVS/src/lib/libc/sys/poll.2,v retrieving revision 1.30 diff -u -r1.30 poll.2 --- lib/libc/sys/poll.2 6 May 2019 06:56:36 -0000 1.30 +++ lib/libc/sys/poll.2 24 May 2020 22:18:53 -0000 @@ -1,6 +1,6 @@ .\" $NetBSD: poll.2,v 1.30 2019/05/06 06:56:36 wiz Exp $ .\" -.\" Copyright (c) 1998, 2005 The NetBSD Foundation, Inc. +.\" Copyright (c) 1998, 2005, 2020 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation @@ -27,11 +27,11 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd May 5, 2019 +.Dd May 25, 2020 .Dt POLL 2 .Os .Sh NAME -.Nm poll, pollts +.Nm poll, pollts, ppoll .Nd synchronous I/O multiplexing .Sh LIBRARY .Lb libc @@ -44,10 +44,16 @@ .In time.h .Ft int .Fn pollts "struct pollfd * restrict fds" "nfds_t nfds" "const struct timespec * restrict ts" "const sigset_t * restrict sigmask" +.In poll.h +.In signal.h +.In time.h +.Ft int +.Fn ppoll "struct pollfd * restrict fds" "nfds_t nfds" "const struct timespec * restrict ts" "const sigset_t * restrict sigmask" .Sh DESCRIPTION -.Fn poll -and +.Fn poll , .Fn pollts +and +.Fn ppoll examine a set of file descriptors to see if some of them are ready for I/O. The @@ -161,17 +167,23 @@ .Fa ts is a null pointer, .Fn pollts +and +.Fn ppoll blocks indefinitely. If .Fa ts is a non-null pointer, referencing a zero-valued timespec structure, then .Fn pollts +and +.Fn ppoll will return without blocking. .Pp If .Fa sigmask is a non-null pointer, then the .Fn pollts +and +.Fn ppoll function shall replace the signal mask of the caller by the set of signals pointed to by .Fa sigmask @@ -206,6 +218,12 @@ bitmask. Attempting to perform I/O on this descriptor will then return an error. This behaviour is believed to be more useful. +.Pp +The +.Fn ppoll +function is an wrapper for +.Fn pollts +to provide compatiblity with the Linux implementation. .Sh ERRORS An error return from .Fn poll @@ -239,6 +257,10 @@ .Fn pollts function first appeared in .Nx 3.0 . +The +.Fn ppoll +function first appeared in +.Nx 10.0 . .Sh BUGS The distinction between some of the fields in the .Fa events Index: lib/libc/sys/ppoll.c =================================================================== RCS file: lib/libc/sys/ppoll.c diff -N lib/libc/sys/ppoll.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lib/libc/sys/ppoll.c 24 May 2020 22:18:53 -0000 @@ -0,0 +1,50 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2020 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Apurva Nandan. + * + * 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$"); + +#include "namespace.h" +#include <sys/poll.h> +#include <sys/time.h> + +#ifdef __weak_alias +__weak_alias(ppoll, _ppoll) +#endif + +int +ppoll(struct pollfd * restrict fds, nfds_t nfds, + const struct timespec * restrict timeout_ts, + const sigset_t * restrict sigmask) +{ + + return pollts(fds, nfds, timeout_ts, sigmask); +} Index: sys/sys/poll.h =================================================================== RCS file: /pub/NetBSD-CVS/src/sys/sys/poll.h,v retrieving revision 1.15 diff -u -r1.15 poll.h --- sys/sys/poll.h 11 Nov 2009 09:48:51 -0000 1.15 +++ sys/sys/poll.h 24 May 2020 22:19:29 -0000 @@ -92,6 +92,8 @@ int pollts(struct pollfd * __restrict, nfds_t, const struct timespec * __restrict, const sigset_t * __restrict) __RENAME(__pollts50); +int ppoll(struct pollfd * __restrict, nfds_t, + const struct timespec * __restrict, const sigset_t * __restrict); #endif /* __LIBC12_SOURCE__ */ __END_DECLS #endif /* _NETBSD_SOURCE */ Index: tests/lib/libc/sys/Makefile =================================================================== RCS file: /pub/NetBSD-CVS/src/tests/lib/libc/sys/Makefile,v retrieving revision 1.63 diff -u -r1.63 Makefile --- tests/lib/libc/sys/Makefile 26 Apr 2020 18:53:33 -0000 1.63 +++ tests/lib/libc/sys/Makefile 24 May 2020 22:19:31 -0000 @@ -53,7 +53,9 @@ TESTS_C+= t_pipe TESTS_C+= t_pipe2 TESTS_C+= t_poll +TESTS_C+= t_pollts TESTS_C+= t_posix_fallocate +TESTS_C+= t_ppoll TESTS_C+= t_ptrace TESTS_C+= t_ptrace_sigchld TESTS_C+= t_ptrace_wait Index: tests/lib/libc/sys/t_poll.c =================================================================== RCS file: /pub/NetBSD-CVS/src/tests/lib/libc/sys/t_poll.c,v retrieving revision 1.3 diff -u -r1.3 t_poll.c --- tests/lib/libc/sys/t_poll.c 18 Mar 2012 07:00:52 -0000 1.3 +++ tests/lib/libc/sys/t_poll.c 24 May 2020 22:19:31 -0000 @@ -82,8 +82,8 @@ (void)printf("child3 exit\n"); } -ATF_TC(poll_3way); -ATF_TC_HEAD(poll_3way, tc) +ATF_TC(3way); +ATF_TC_HEAD(3way, tc) { atf_tc_set_md_var(tc, "timeout", "15"); atf_tc_set_md_var(tc, "descr", @@ -94,7 +94,7 @@ "both be awaken. (kern/17517)"); } -ATF_TC_BODY(poll_3way, tc) +ATF_TC_BODY(3way, tc) { int pf[2]; int status, i; @@ -145,15 +145,15 @@ (void)printf("parent terminated\n"); } -ATF_TC(poll_basic); -ATF_TC_HEAD(poll_basic, tc) +ATF_TC(basic); +ATF_TC_HEAD(basic, tc) { atf_tc_set_md_var(tc, "timeout", "10"); atf_tc_set_md_var(tc, "descr", "Basis functionality test for poll(2)"); } -ATF_TC_BODY(poll_basic, tc) +ATF_TC_BODY(basic, tc) { int fds[2]; struct pollfd pfds[2]; @@ -212,13 +212,13 @@ ATF_REQUIRE_EQ(close(fds[1]), 0); } -ATF_TC(poll_err); -ATF_TC_HEAD(poll_err, tc) +ATF_TC(err); +ATF_TC_HEAD(err, tc) { atf_tc_set_md_var(tc, "descr", "Check errors from poll(2)"); } -ATF_TC_BODY(poll_err, tc) +ATF_TC_BODY(err, tc) { struct pollfd pfd; int fd = 0; @@ -233,160 +233,12 @@ ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1); } -ATF_TC(pollts_basic); -ATF_TC_HEAD(pollts_basic, tc) -{ - atf_tc_set_md_var(tc, "timeout", "10"); - atf_tc_set_md_var(tc, "descr", - "Basis functionality test for pollts(2)"); -} - -ATF_TC_BODY(pollts_basic, tc) -{ - int fds[2]; - struct pollfd pfds[2]; - struct timespec timeout; - int ret; - - ATF_REQUIRE_EQ(pipe(fds), 0); - - pfds[0].fd = fds[0]; - pfds[0].events = POLLIN; - pfds[1].fd = fds[1]; - pfds[1].events = POLLOUT; - - /* Use a timeout of 1 second. */ - timeout.tv_sec = 1; - timeout.tv_nsec = 0; - - /* - * Check that we get a timeout waiting for data on the read end - * of our pipe. - */ - pfds[0].revents = -1; - pfds[1].revents = -1; - ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[0], 1, &timeout, NULL), 0, - "got: %d", ret); - ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); - ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); - - /* Check that the write end of the pipe as reported as ready. */ - pfds[0].revents = -1; - pfds[1].revents = -1; - ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[1], 1, &timeout, NULL), 1, - "got: %d", ret); - ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); - ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ - pfds[1].revents); - - /* Check that only the write end of the pipe as reported as ready. */ - pfds[0].revents = -1; - pfds[1].revents = -1; - ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 1, - "got: %d", ret); - ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); - ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", - pfds[1].revents); - - /* Write data to our pipe. */ - ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); - - /* Check that both ends of our pipe are reported as ready. */ - pfds[0].revents = -1; - pfds[1].revents = -1; - ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 2, - "got: %d", ret); - ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", - pfds[0].revents); - ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", - pfds[1].revents); - - ATF_REQUIRE_EQ(close(fds[0]), 0); - ATF_REQUIRE_EQ(close(fds[1]), 0); -} - -ATF_TC(pollts_err); -ATF_TC_HEAD(pollts_err, tc) -{ - atf_tc_set_md_var(tc, "descr", "Check errors from pollts(2)"); -} - -ATF_TC_BODY(pollts_err, tc) -{ - struct timespec timeout; - struct pollfd pfd; - int fd = 0; - - pfd.fd = fd; - pfd.events = POLLIN; - - timeout.tv_sec = 1; - timeout.tv_nsec = 0; - - errno = 0; - ATF_REQUIRE_ERRNO(EFAULT, pollts((void *)-1, 1, &timeout, NULL) == -1); - - timeout.tv_sec = -1; - timeout.tv_nsec = -1; - - errno = 0; - ATF_REQUIRE_ERRNO(EINVAL, pollts(&pfd, 1, &timeout, NULL) == -1); -} - -ATF_TC(pollts_sigmask); -ATF_TC_HEAD(pollts_sigmask, tc) -{ - atf_tc_set_md_var(tc, "timeout", "10"); - atf_tc_set_md_var(tc, "descr", - "Check that pollts(2) restores the signal mask (PR kern/44986)"); -} - -ATF_TC_BODY(pollts_sigmask, tc) -{ - int fd; - struct pollfd pfd; - struct timespec timeout; - sigset_t mask; - int ret; - - fd = open(_PATH_DEVNULL, O_RDONLY); - ATF_REQUIRE(fd >= 0); - - pfd.fd = fd; - pfd.events = POLLIN; - - /* Use a timeout of 1 second. */ - timeout.tv_sec = 1; - timeout.tv_nsec = 0; - - /* Unblock all signals. */ - ATF_REQUIRE_EQ(sigfillset(&mask), 0); - ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0); - - /* - * Check that pollts(2) immediately returns. We block *all* - * signals during pollts(2). - */ - ATF_REQUIRE_EQ_MSG(ret = pollts(&pfd, 1, &timeout, &mask), 1, - "got: %d", ret); - - /* Check that signals are now longer blocked. */ - ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0); - ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0, - "signal mask was changed."); - - ATF_REQUIRE_EQ(close(fd), 0); -} - ATF_TP_ADD_TCS(tp) { - ATF_TP_ADD_TC(tp, poll_3way); - ATF_TP_ADD_TC(tp, poll_basic); - ATF_TP_ADD_TC(tp, poll_err); - ATF_TP_ADD_TC(tp, pollts_basic); - ATF_TP_ADD_TC(tp, pollts_err); - ATF_TP_ADD_TC(tp, pollts_sigmask); + ATF_TP_ADD_TC(tp, 3way); + ATF_TP_ADD_TC(tp, basic); + ATF_TP_ADD_TC(tp, err); return atf_no_error(); } Index: tests/lib/libc/sys/t_pollts.c =================================================================== RCS file: tests/lib/libc/sys/t_pollts.c diff -N tests/lib/libc/sys/t_pollts.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tests/lib/libc/sys/t_pollts.c 24 May 2020 22:19:31 -0000 @@ -0,0 +1,201 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2011, 2020 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * 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/time.h> +#include <sys/wait.h> + +#include <atf-c.h> +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <poll.h> +#include <stdio.h> +#include <signal.h> +#include <unistd.h> + +#ifndef POLLTS +#define POLLTS pollts +#endif + +ATF_TC(basic); +ATF_TC_HEAD(basic, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Basis functionality test for ppoll(2)/pollts(2)"); +} + +ATF_TC_BODY(basic, tc) +{ + int fds[2]; + struct pollfd pfds[2]; + struct timespec timeout; + int ret; + + ATF_REQUIRE_EQ(pipe(fds), 0); + + pfds[0].fd = fds[0]; + pfds[0].events = POLLIN; + pfds[1].fd = fds[1]; + pfds[1].events = POLLOUT; + + /* Use a timeout of 1 second. */ + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + /* + * Check that we get a timeout waiting for data on the read end + * of our pipe. + */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = POLLTS(&pfds[0], 1, &timeout, NULL), 0, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); + + /* Check that the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = POLLTS(&pfds[1], 1, &timeout, NULL), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ + pfds[1].revents); + + /* Check that only the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = POLLTS(pfds, 2, &timeout, NULL), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + /* Write data to our pipe. */ + ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); + + /* Check that both ends of our pipe are reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = POLLTS(pfds, 2, &timeout, NULL), 2, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", + pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + ATF_REQUIRE_EQ(close(fds[0]), 0); + ATF_REQUIRE_EQ(close(fds[1]), 0); +} + +ATF_TC(err); +ATF_TC_HEAD(err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check errors from ppoll(2)/pollts(2)"); +} + +ATF_TC_BODY(err, tc) +{ + struct timespec timeout; + struct pollfd pfd; + int fd = 0; + + pfd.fd = fd; + pfd.events = POLLIN; + + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, POLLTS((void *)-1, 1, &timeout, NULL) == -1); + + timeout.tv_sec = -1; + timeout.tv_nsec = -1; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, POLLTS(&pfd, 1, &timeout, NULL) == -1); +} + +ATF_TC(sigmask); +ATF_TC_HEAD(sigmask, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Check that ppoll(2)/pollts(2) restores the signal mask (PR kern/44986)"); +} + +ATF_TC_BODY(sigmask, tc) +{ + int fd; + struct pollfd pfd; + struct timespec timeout; + sigset_t mask; + int ret; + + fd = open(_PATH_DEVNULL, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + pfd.fd = fd; + pfd.events = POLLIN; + + /* Use a timeout of 1 second. */ + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + /* Unblock all signals. */ + ATF_REQUIRE_EQ(sigfillset(&mask), 0); + ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0); + + /* + * Check that ppoll(2)/pollts(2) immediately returns. We block *all* + * signals during ppoll(2)/pollts(2). + */ + ATF_REQUIRE_EQ_MSG(ret = POLLTS(&pfd, 1, &timeout, &mask), 1, + "got: %d", ret); + + /* Check that signals are now longer blocked. */ + ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0); + ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0, + "signal mask was changed."); + + ATF_REQUIRE_EQ(close(fd), 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, basic); + ATF_TP_ADD_TC(tp, err); + ATF_TP_ADD_TC(tp, sigmask); + + return atf_no_error(); +} Index: tests/lib/libc/sys/t_ppoll.c =================================================================== RCS file: tests/lib/libc/sys/t_ppoll.c diff -N tests/lib/libc/sys/t_ppoll.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tests/lib/libc/sys/t_ppoll.c 24 May 2020 22:19:31 -0000 @@ -0,0 +1,33 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2011, 2020 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * 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 POLLTS ppoll +#include "t_pollts.c"