summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-10-23 16:10:26 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-10-31 13:18:50 +0100
commitfacf9dcea6ee0f97d4404a1734909c762e91559b (patch)
tree6eea3929a60657daad04b8b8c48400c2b569e6d3
parentsleep01: New test (diff)
downloadrtems-libbsd-facf9dcea6ee0f97d4404a1734909c762e91559b.tar.bz2
Use select() from FreeBSD
-rw-r--r--freebsd/sys/kern/sys_generic.c44
-rw-r--r--freebsd/sys/kern/sys_socket.c27
-rw-r--r--freebsd/sys/sys/file.h9
-rw-r--r--testsuite/syscalls01/test_main.c75
4 files changed, 129 insertions, 26 deletions
diff --git a/freebsd/sys/kern/sys_generic.c b/freebsd/sys/kern/sys_generic.c
index f666cb15..b7185d5b 100644
--- a/freebsd/sys/kern/sys_generic.c
+++ b/freebsd/sys/kern/sys_generic.c
@@ -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)
diff --git a/freebsd/sys/kern/sys_socket.c b/freebsd/sys/kern/sys_socket.c
index a748d8b1..19633aeb 100644
--- a/freebsd/sys/kern/sys_socket.c
+++ b/freebsd/sys/kern/sys_socket.c
@@ -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__ */
diff --git a/freebsd/sys/sys/file.h b/freebsd/sys/sys/file.h
index 68d3f27c..2c8312c5 100644
--- a/freebsd/sys/sys/file.h
+++ b/freebsd/sys/sys/file.h
@@ -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;
diff --git a/testsuite/syscalls01/test_main.c b/testsuite/syscalls01/test_main.c
index 6f64c21e..7e4db14a 100644
--- a/testsuite/syscalls01/test_main.c
+++ b/testsuite/syscalls01/test_main.c
@@ -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();