summaryrefslogtreecommitdiffstats
path: root/cpukit/libnetworking/rtems/rtems_select.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libnetworking/rtems/rtems_select.c')
-rw-r--r--cpukit/libnetworking/rtems/rtems_select.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/cpukit/libnetworking/rtems/rtems_select.c b/cpukit/libnetworking/rtems/rtems_select.c
index 927c07daa6..b8915b64df 100644
--- a/cpukit/libnetworking/rtems/rtems_select.c
+++ b/cpukit/libnetworking/rtems/rtems_select.c
@@ -30,6 +30,11 @@
#include <net/if.h>
#include <net/route.h>
+RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_OTHER == 0, other);
+RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_READ == FREAD, fread);
+RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_WRITE == FWRITE, fwrite);
+RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_EVENT == SBWAIT_EVENT, sbwait_event);
+
/*
*********************************************************************
* RTEMS implementation of select() system call *
@@ -88,6 +93,11 @@ selscan (rtems_id tid, fd_mask **ibits, fd_mask **obits, int nfd, int *retval)
fd_mask bits, bit;
int n = 0;
static int flag[3] = { FREAD, FWRITE, 0 };
+ int update_obits;
+ int rv;
+ rtems_ioctl_select_request select_request;
+
+ select_request.request_task_id = tid;
for (msk = 0; msk < 3; msk++) {
if (ibits[msk] == NULL)
@@ -98,10 +108,26 @@ selscan (rtems_id tid, fd_mask **ibits, fd_mask **obits, int nfd, int *retval)
if ((bits & bit) == 0)
continue;
bits &= ~bit;
+ update_obits = 0;
so = rtems_bsdnet_fdToSocket (fd);
- if (so == NULL)
- return (EBADF);
- if (socket_select (so, flag[msk], tid)) {
+ if (so != NULL) {
+ if (socket_select (so, flag[msk], tid)) {
+ update_obits = 1;
+ }
+ } else {
+ select_request.kind = flag[msk];
+
+ rtems_bsdnet_semaphore_release();
+ rv = ioctl (fd, RTEMS_IOCTL_SELECT, &select_request);
+ rtems_bsdnet_semaphore_obtain();
+ if (rv == 1) {
+ update_obits = 1;
+ } else if (rv != 0) {
+ return (EBADF);
+ }
+ }
+
+ if (update_obits) {
obits[msk][fd/NFDBITS] |=
(1 << (fd % NFDBITS));
n++;