Add ppoll() a compatibility wrapper around pollts(2)

Submitted by Apurva Nandan.
This commit is contained in:
kamil 2020-07-17 15:34:16 +00:00
parent 8d51512d13
commit 07e8492e26
11 changed files with 341 additions and 176 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.2339 2020/07/10 02:27:13 thorpej Exp $
# $NetBSD: mi,v 1.2340 2020/07/17 15:34:17 kamil Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
./etc/mtree/set.comp comp-sys-root
@ -4529,6 +4529,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
@ -12822,6 +12823,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
@ -20943,6 +20945,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

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.324 2020/07/06 18:47:02 christos Exp $
# $NetBSD: mi,v 1.325 2020/07/17 15:34:17 kamil Exp $
./etc/mtree/set.debug comp-sys-root
./usr/lib comp-sys-usr compatdir
./usr/lib/i18n/libBIG5_g.a comp-c-debuglib debuglib,compatfile
@ -2169,8 +2169,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

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.873 2020/07/06 18:47:02 christos Exp $
# $NetBSD: mi,v 1.874 2020/07/17 15:34:17 kamil Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -3169,8 +3169,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

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.243 2020/05/16 18:31:47 christos Exp $
# $NetBSD: Makefile.inc,v 1.244 2020/07/17 15:34:17 kamil Exp $
# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
# sys sources
@ -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:
@ -359,7 +359,7 @@ MLINKS+=mount.2 unmount.2
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

View File

@ -1,6 +1,6 @@
.\" $NetBSD: poll.2,v 1.30 2019/05/06 06:56:36 wiz Exp $
.\" $NetBSD: poll.2,v 1.31 2020/07/17 15:34:17 kamil 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 @@ If
.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 to the
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 @@ The
.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

46
lib/libc/sys/ppoll.c Normal file
View File

@ -0,0 +1,46 @@
/* $NetBSD: ppoll.c,v 1.1 2020/07/17 15:34:17 kamil Exp $ */
/*-
* 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: ppoll.c,v 1.1 2020/07/17 15:34:17 kamil Exp $");
#include "namespace.h"
#include <sys/poll.h>
#include <sys/time.h>
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);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: poll.h,v 1.15 2009/11/11 09:48:51 rmind Exp $ */
/* $NetBSD: poll.h,v 1.16 2020/07/17 15:34:16 kamil Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -92,6 +92,8 @@ __BEGIN_DECLS
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 */

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.65 2020/06/17 22:07:21 rin Exp $
# $NetBSD: Makefile,v 1.66 2020/07/17 15:34:16 kamil Exp $
MKMAN= no
@ -53,7 +53,9 @@ TESTS_C+= t_nanosleep
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

View File

@ -1,4 +1,4 @@
/* $NetBSD: t_poll.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */
/* $NetBSD: t_poll.c,v 1.4 2020/07/17 15:34:16 kamil Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
@ -82,8 +82,8 @@ child3(void)
(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 @@ ATF_TC_HEAD(poll_3way, tc)
"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 @@ ATF_TC_BODY(poll_3way, tc)
(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_TC_BODY(poll_basic, tc)
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_TC_BODY(poll_err, tc)
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();
}

View File

@ -0,0 +1,201 @@
/* $NetBSD: t_pollts.c,v 1.1 2020/07/17 15:34:17 kamil Exp $ */
/*-
* 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();
}

View File

@ -0,0 +1,33 @@
/* $NetBSD: t_ppoll.c,v 1.1 2020/07/17 15:34:17 kamil Exp $ */
/*-
* 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"