Use select() from FreeBSD

This commit is contained in:
Sebastian Huber 2013-10-23 16:10:26 +02:00
parent 0967858024
commit facf9dcea6
4 changed files with 129 additions and 26 deletions

View File

@ -94,9 +94,7 @@ static int pollrescan(struct thread *);
#endif /* __rtems__ */
static int selscan(struct thread *, fd_mask **, fd_mask **, int);
static int selrescan(struct thread *, fd_mask **, fd_mask **);
#ifndef __rtems__
static void selfdalloc(struct thread *, void *);
#endif /* __rtems__ */
static void selfdfree(struct seltd *, struct selfd *);
#ifndef __rtems__
static int dofileread(struct thread *, int, struct file *, struct uio *,
@ -851,9 +849,7 @@ int
kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits)
{
#ifndef __rtems__
struct filedesc *fdp;
#endif /* __rtems__ */
/*
* The magic 2048 here is chosen to be just enough for FD_SETSIZE
* infds with the new FD_SETSIZE of 1024, and more than enough for
@ -866,10 +862,6 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
int error, timo;
u_int nbufbytes, ncpbytes, ncpubytes, nfdbits;
#ifdef __rtems__
if (td == NULL)
return (ENOMEM);
#endif /* __rtems__ */
if (nd < 0)
return (EINVAL);
#ifndef __rtems__
@ -877,6 +869,7 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
if (nd > fdp->fd_lastfile + 1)
nd = fdp->fd_lastfile + 1;
#else /* __rtems__ */
(void) fdp;
if (nd > rtems_libio_number_iops)
nd = rtems_libio_number_iops;
#endif /* __rtems__ */
@ -1019,12 +1012,18 @@ done:
}
#ifdef __rtems__
int
select(int nfds, fd_set *restrict readfds, fd_set *__restrict writefds, fd_set
*__restrict errorfds, struct timeval *__restrict timeout)
select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds,
struct timeval *timeout)
{
struct thread *td = rtems_bsd_get_curthread_or_null();
int error = kern_select(td, nfds, readfds, writefds, errorfds, timeout,
NFDBITS);
int error;
if (td != NULL) {
error = kern_select(td, nfds, readfds, writefds, errorfds,
timeout, NFDBITS);
} else {
error = ENOMEM;
}
if (error == 0) {
return td->td_retval[0];
@ -1033,7 +1032,7 @@ select(int nfds, fd_set *restrict readfds, fd_set *__restrict writefds, fd_set
}
}
#endif /* __rtems__ */
#ifndef __rtems__
/*
* Convert a select bit set to poll flags.
*
@ -1099,7 +1098,6 @@ selsetbits(fd_mask **ibits, fd_mask **obits, int idx, fd_mask bit, int events)
return (n);
}
#endif /* __rtems__ */
/*
* Traverse the list of fds attached to this thread's seltd and check for
@ -1108,7 +1106,6 @@ selsetbits(fd_mask **ibits, fd_mask **obits, int idx, fd_mask bit, int events)
static int
selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
{
#ifndef __rtems__
struct filedesc *fdp;
struct selinfo *si;
struct seltd *stp;
@ -1118,7 +1115,11 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
fd_mask bit;
int fd, ev, n, idx;
#ifndef __rtems__
fdp = td->td_proc->p_fd;
#else /* __rtems__ */
fdp = NULL;
#endif /* __rtems__ */
stp = td->td_sel;
n = 0;
STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) {
@ -1140,9 +1141,6 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
stp->st_flags = 0;
td->td_retval[0] = n;
return (0);
#else /* __rtems__ */
return (ENOMEM);
#endif /* __rtems__ */
}
/*
@ -1155,14 +1153,17 @@ selscan(td, ibits, obits, nfd)
fd_mask **ibits, **obits;
int nfd;
{
#ifndef __rtems__
struct filedesc *fdp;
struct file *fp;
fd_mask bit;
int ev, flags, end, fd;
int n, idx;
#ifndef __rtems__
fdp = td->td_proc->p_fd;
#else /* __rtems__ */
fdp = NULL;
#endif /* __rtems__ */
n = 0;
for (idx = 0, fd = 0; fd < nfd; idx++) {
end = imin(fd + NFDBITS, nfd);
@ -1183,9 +1184,6 @@ selscan(td, ibits, obits, nfd)
td->td_retval[0] = n;
return (0);
#else /* __rtems__ */
return (ENOMEM);
#endif /* __rtems__ */
}
#ifndef __rtems__
@ -1466,6 +1464,7 @@ selsocket(struct socket *so, int events, struct timeval *tvp, struct thread *td)
error = 0;
return (error);
}
#endif /* __rtems__ */
/*
* Preallocate two selfds associated with 'cookie'. Some fo_poll routines
@ -1486,7 +1485,6 @@ selfdalloc(struct thread *td, void *cookie)
stp->st_free2->sf_td = stp;
stp->st_free2->sf_cookie = cookie;
}
#endif /* __rtems__ */
static void
selfdfree(struct seltd *stp, struct selfd *sfp)

View File

@ -325,7 +325,9 @@ rtems_bsd_soo_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer)
}
#endif /* __rtems__ */
#ifndef __rtems__
#ifdef __rtems__
static
#endif /* __rtems__ */
int
soo_poll(struct file *fp, int events, struct ucred *active_cred,
struct thread *td)
@ -338,7 +340,27 @@ soo_poll(struct file *fp, int events, struct ucred *active_cred,
if (error)
return (error);
#endif
#ifndef __rtems__
return (sopoll(so, events, fp->f_cred, td));
#else /* __rtems__ */
return (sopoll(so, events, NULL, td));
#endif /* __rtems__ */
}
#ifdef __rtems__
static int
rtems_bsd_soo_poll(rtems_libio_t *iop, int events)
{
struct thread *td = rtems_bsd_get_curthread_or_null();
struct file *fp = rtems_bsd_iop_to_fp(iop);
int error;
if (td != NULL) {
error = soo_poll(fp, events, NULL, td);
} else {
error = ENOMEM;
}
return error;
}
#endif /* __rtems__ */
@ -451,6 +473,7 @@ const rtems_filesystem_file_handlers_r socketops = {
.ftruncate_h = rtems_filesystem_default_ftruncate,
.fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
.fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
.fcntl_h = rtems_filesystem_default_fcntl
.fcntl_h = rtems_filesystem_default_fcntl,
.poll_h = rtems_bsd_soo_poll
};
#endif /* __rtems__ */

View File

@ -408,7 +408,6 @@ fo_ioctl(fp, com, data, active_cred, td)
#endif /* __rtems__ */
}
#ifndef __rtems__
static __inline int
fo_poll(fp, events, active_cred, td)
struct file *fp;
@ -417,9 +416,17 @@ fo_poll(fp, events, active_cred, td)
struct thread *td;
{
#ifndef __rtems__
return ((*fp->f_ops->fo_poll)(fp, events, active_cred, td));
#else /* __rtems__ */
(void) active_cred;
(void) td;
return ((*fp->f_io.pathinfo.handlers->poll_h)(&fp->f_io, events));
#endif /* __rtems__ */
}
#ifndef __rtems__
static __inline int
fo_stat(fp, sb, active_cred, td)
struct file *fp;

View File

@ -32,6 +32,7 @@
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/filio.h>
#include <netinet/in.h>
@ -1206,6 +1207,79 @@ test_socket_recv_and_recvfrom_and_recvmsg(void)
assert(rtems_resource_snapshot_check(&snapshot));
}
static void
no_mem_socket_select(int fd)
{
struct fd_set set;
int nfds;
int rv;
FD_ZERO(&set);
FD_SET(fd, &set);
nfds = fd + 1;
errno = 0;
rv = select(nfds, &set, NULL, NULL, NULL);
assert(rv == -1);
assert(errno == ENOMEM);
}
static void
test_socket_select(void)
{
rtems_resource_snapshot snapshot;
struct fd_set set;
int nfds;
int sd;
int rv;
puts("test socket select");
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 = select(nfds, &set, NULL, NULL, NULL);
assert(rv == -1);
assert(errno == EBADF);
rtems_resource_snapshot_take(&snapshot);
sd = socket(PF_INET, SOCK_DGRAM, 0);
assert(sd >= 0);
do_no_mem_test(no_mem_socket_select, sd);
FD_ZERO(&set);
nfds = -1;
errno = 0;
rv = select(nfds, &set, 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 = select(nfds, &set, NULL, NULL, NULL);
assert(rv == -1);
assert(errno == EBADF);
assert(rtems_resource_snapshot_check(&snapshot));
}
static const char prog_name[] = "prog";
static int
@ -1412,6 +1486,7 @@ test_main(void)
test_socket_read_and_write();
test_socket_send_and_sendto_and_sendmsg();
test_socket_recv_and_recvfrom_and_recvmsg();
test_socket_select();
test_bsd_program();
test_warn();