summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2019-09-23 14:27:32 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2019-09-23 14:29:00 +0200
commitcff1625f2787e08f33e67f949c0722c0aa05f618 (patch)
tree0874b63641d70eccd26af7a11c04b839c0157641
parenttest/syscalls01: Fix sporadic test failures (diff)
downloadrtems-libbsd-cff1625f2787e08f33e67f949c0722c0aa05f618.tar.bz2
Add pselect()
-rw-r--r--freebsd/sys/kern/sys_generic.c37
-rwxr-xr-xtestsuite/selectpollkqueue01/test_main.c62
-rw-r--r--testsuite/syscalls01/test_main.c76
3 files changed, 174 insertions, 1 deletions
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
@@ -522,6 +522,63 @@ test_select_close(test_context *ctx)
}
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)
{
static const short events[] = {
@@ -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
@@ -1329,6 +1329,81 @@ test_socket_select(void)
}
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)
{
struct pollfd pfd;
@@ -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();