Add pselect()

This commit is contained in:
Sebastian Huber 2019-09-23 14:27:32 +02:00
parent 19b2402c40
commit cff1625f27
3 changed files with 174 additions and 1 deletions

View File

@ -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__ */
/*

View File

@ -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);

View File

@ -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();