[rtems-libbsd commit] Add pselect()

Sebastian Huber sebh at rtems.org
Mon Sep 23 12:39:20 UTC 2019


Module:    rtems-libbsd
Branch:    5-freebsd-12
Commit:    d06c638d7ba9511460f48f4815686cef7cc80593
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=d06c638d7ba9511460f48f4815686cef7cc80593

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Sep 23 14:27:32 2019 +0200

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 dc7f3f7..5032fa9 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 fc05643..244f5b5 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 b95a6c2..3254ba5 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();
 




More information about the vc mailing list