From cff1625f2787e08f33e67f949c0722c0aa05f618 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 23 Sep 2019 14:27:32 +0200 Subject: Add pselect() --- freebsd/sys/kern/sys_generic.c | 37 ++++++++++++++++ testsuite/selectpollkqueue01/test_main.c | 62 +++++++++++++++++++++++++- testsuite/syscalls01/test_main.c | 76 ++++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 1 deletion(-) diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c index 24da3934..cc208d6e 100644 --- a/freebsd/sys/kern/sys_generic.c +++ b/freebsd/sys/kern/sys_generic.c @@ -1179,6 +1179,43 @@ select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, rtems_set_errno_and_return_minus_one(error); } } + +int +pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, + const struct timespec *timeout, const sigset_t *set) +{ + struct thread *td; + int error; + + if (set != NULL) { + rtems_set_errno_and_return_minus_one(ENOSYS); + } + + td = rtems_bsd_get_curthread_or_null(); + + if (td != NULL) { + struct timeval tv; + struct timeval *tvp; + + if (timeout != NULL) { + TIMESPEC_TO_TIMEVAL(&tv, timeout); + tvp = &tv; + } else { + tvp = NULL; + } + + error = kern_select(td, nfds, readfds, writefds, errorfds, + tvp, NFDBITS); + } else { + error = ENOMEM; + } + + if (error == 0) { + return td->td_retval[0]; + } else { + rtems_set_errno_and_return_minus_one(error); + } +} #endif /* __rtems__ */ /* diff --git a/testsuite/selectpollkqueue01/test_main.c b/testsuite/selectpollkqueue01/test_main.c index fc056432..244f5b50 100755 --- a/testsuite/selectpollkqueue01/test_main.c +++ b/testsuite/selectpollkqueue01/test_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013, 2019 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -521,6 +521,63 @@ test_select_close(test_context *ctx) assert(ctx->cfd == -1); } +static void +test_pselect_sigmask(void) +{ + int rv; + sigset_t set; + + puts("test pselect sigmask"); + + sigemptyset(&set); + errno = 0; + rv = pselect(0, NULL, NULL, NULL, NULL, &set); + assert(rv == -1); + assert(errno == ENOSYS); +} + +static void +test_pselect_timeout(test_context *ctx) +{ + struct timespec timeout = { + .tv_sec = 0, + .tv_nsec = 100000000 + }; + int fd = ctx->lfd; + int nfds = fd + 1; + struct fd_set set; + int rv; + int i; + + puts("test pselect timeout"); + + set_non_blocking(ctx->lfd, 0); + + FD_ZERO(&set); + FD_SET(fd, &set); + + rv = pselect(nfds, &set, NULL, NULL, &timeout, NULL); + assert(rv == 0); + + for (i = 0; i < nfds; ++i) { + assert(!FD_ISSET(i, &set)); + } + + rv = pselect(nfds, NULL, &set, NULL, &timeout, NULL); + assert(rv == 0); + + for (i = 0; i < nfds; ++i) { + assert(!FD_ISSET(i, &set)); + } + + rv = pselect(nfds, NULL, NULL, &set, &timeout, NULL); + assert(rv == 0); + + for (i = 0; i < nfds; ++i) { + assert(!FD_ISSET(i, &set)); + } +} + static void test_poll_timeout(test_context *ctx) { @@ -1199,6 +1256,9 @@ test_main(void) test_select_write(ctx); test_select_close(ctx); + test_pselect_sigmask(); + test_pselect_timeout(ctx); + test_poll_timeout(ctx); test_poll_connect(ctx); test_poll_read(ctx); diff --git a/testsuite/syscalls01/test_main.c b/testsuite/syscalls01/test_main.c index b95a6c24..3254ba5c 100644 --- a/testsuite/syscalls01/test_main.c +++ b/testsuite/syscalls01/test_main.c @@ -1328,6 +1328,81 @@ test_socket_select(void) assert(rtems_resource_snapshot_check(&snapshot)); } +static void +no_mem_socket_pselect(int fd) +{ + struct fd_set set; + int nfds; + int rv; + + FD_ZERO(&set); + FD_SET(fd, &set); + nfds = fd + 1; + + errno = 0; + rv = pselect(nfds, &set, NULL, NULL, NULL, NULL); + assert(rv == -1); + assert(errno == ENOMEM); +} + +static void +test_socket_pselect(void) +{ + rtems_resource_snapshot snapshot; + struct fd_set set; + int nfds; + int sd; + int rv; + + puts("test socket pselect"); + + sd = socket(PF_INET, SOCK_DGRAM, 0); + assert(sd >= 0); + + rv = close(sd); + assert(rv == 0); + + FD_ZERO(&set); + FD_SET(sd, &set); + nfds = sd + 1; + + errno = 0; + rv = pselect(nfds, &set, NULL, NULL, NULL, NULL); + assert(rv == -1); + assert(errno == EBADF); + + epoch_cleanup(); + rtems_resource_snapshot_take(&snapshot); + + sd = socket(PF_INET, SOCK_DGRAM, 0); + assert(sd >= 0); + + do_no_mem_test(no_mem_socket_pselect, sd); + + FD_ZERO(&set); + nfds = -1; + + errno = 0; + rv = pselect(nfds, &set, NULL, NULL, NULL, NULL); + assert(rv == -1); + assert(errno == EINVAL); + + rv = close(sd); + assert(rv == 0); + + FD_ZERO(&set); + FD_SET(sd, &set); + nfds = sd + 1; + + errno = 0; + rv = pselect(nfds, &set, NULL, NULL, NULL, NULL); + assert(rv == -1); + assert(errno == EBADF); + + epoch_cleanup(); + assert(rtems_resource_snapshot_check(&snapshot)); +} + static void no_mem_socket_poll(int fd) { @@ -1662,6 +1737,7 @@ test_main(void) test_socket_send_and_sendto_and_sendmsg(); test_socket_recv_and_recvfrom_and_recvmsg(); test_socket_select(); + test_socket_pselect(); test_socket_poll(); test_socket_pair(); -- cgit v1.2.3