Hi,

Attached is the first patch for a 3-way split of hurdselect.c into three
cases: DELAY, POLL, SELECT leading to a more POSIX conforming POLL. The
Hurd servers pflocal and pfinet are already prepared for this update.

Starting point is the hurdselect.c created by all Debian patches applied
up to eglibc-2.13-38 + 3 additional patches:
[PATCH,HURD] hurdselect: remove dead code:
http://lists.gnu.org/archive/html/bug-hurd/2013-01/msg00004.html
unsubmitted-select-EINTR.diff
unsubmitted-setitimer_fix.diff

The patch does the following:
1) Introduce the ispoll enum
2) Create the three cases: DELAY, POLL, SELECT
3) Move the msg union definition to the definitions in the beginning.
4) Move the definitions of IO_SELECT_REPLY_MSGID and inttype to the
beginning.

Subsequent patches will be made relative to this patch if accepted.

--- hurdselect.c-38+patches	2013-01-22 16:09:25.000000000 +0100
+++ hurdselect_step1_1.c	2013-01-22 17:33:12.000000000 +0100
@@ -68,12 +68,74 @@ _hurd_select (int nfds,
   assert (sizeof (union typeword) == sizeof (mach_msg_type_t));
   assert (sizeof (uint32_t) == sizeof (mach_msg_type_t));
 
+  enum {
+    DELAY = -1,
+    SELECT = 0,
+    POLL = 1
+  } ispoll;
+
+  if (nfds == 0)
+    ispoll = DELAY;
+  else if (pollfds)
+    ispoll = POLL;
+  else
+    ispoll = SELECT;
+
+      union
+	{
+	  mach_msg_header_t head;
+#ifdef MACH_MSG_TRAILER_MINIMUM_SIZE
+	  struct
+	    {
+	      mach_msg_header_t head;
+	      NDR_record_t ndr;
+	      error_t err;
+	    } error;
+	  struct
+	    {
+	      mach_msg_header_t head;
+	      NDR_record_t ndr;
+	      error_t err;
+	      int result;
+	      mach_msg_trailer_t trailer;
+	    } success;
+#else
+	  struct
+	    {
+	      mach_msg_header_t head;
+	      union typeword err_type;
+	      error_t err;
+	    } error;
+	  struct
+	    {
+	      mach_msg_header_t head;
+	      union typeword err_type;
+	      error_t err;
+	      union typeword result_type;
+	      int result;
+	    } success;
+#endif
+	} msg;
+      mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT);
+      error_t msgerr;
+
+#define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
+#ifdef MACH_MSG_TYPE_BIT
+	  const union typeword inttype =
+	  { type:
+	    { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, 1, 1, 0, 0 }
+	  };
+#endif
+
   if (nfds < 0 || nfds > FD_SETSIZE)
     {
       errno = EINVAL;
       return -1;
     }
 
+  if (nfds > _hurd_dtablesize)
+    nfds = _hurd_dtablesize;
+
   if (timeout != NULL)
     {
       if (timeout->tv_sec < 0 || timeout->tv_nsec < 0)
@@ -123,13 +185,10 @@ _hurd_select (int nfds,
 	  {
 	    const int fd = (int) d[i].io_port;
 
-	    if (fd < _hurd_dtablesize)
-	      {
 		d[i].cell = _hurd_dtable[fd];
 		d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink);
 		if (d[i].io_port != MACH_PORT_NULL)
 		  continue;
-	      }
 
 	    /* If one descriptor is bogus, we fail completely.  */
 	    while (i-- > 0)
@@ -174,9 +233,6 @@ _hurd_select (int nfds,
       HURD_CRITICAL_BEGIN;
       __mutex_lock (&_hurd_dtable_lock);
 
-      if (nfds > _hurd_dtablesize)
-	nfds = _hurd_dtablesize;
-
       /* Collect the ports for interesting FDs.  */
       firstfd = lastfd = -1;
       for (i = 0; i < nfds; ++i)
@@ -296,57 +352,12 @@ _hurd_select (int nfds,
     {
       /* Now wait for io_select_reply messages on PORT,
 	 timing out as appropriate.  */
-
-      union
-	{
-	  mach_msg_header_t head;
-#ifdef MACH_MSG_TRAILER_MINIMUM_SIZE
-	  struct
-	    {
-	      mach_msg_header_t head;
-	      NDR_record_t ndr;
-	      error_t err;
-	    } error;
-	  struct
-	    {
-	      mach_msg_header_t head;
-	      NDR_record_t ndr;
-	      error_t err;
-	      int result;
-	      mach_msg_trailer_t trailer;
-	    } success;
-#else
-	  struct
-	    {
-	      mach_msg_header_t head;
-	      union typeword err_type;
-	      error_t err;
-	    } error;
-	  struct
-	    {
-	      mach_msg_header_t head;
-	      union typeword err_type;
-	      error_t err;
-	      union typeword result_type;
-	      int result;
-	    } success;
-#endif
-	} msg;
-      mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT);
-      error_t msgerr;
       while ((msgerr = __mach_msg (&msg.head,
 				   MACH_RCV_MSG | MACH_RCV_INTERRUPT | options,
 				   0, sizeof msg, portset, to,
 				   MACH_PORT_NULL)) == MACH_MSG_SUCCESS)
 	{
 	  /* We got a message.  Decode it.  */
-#define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
-#ifdef MACH_MSG_TYPE_BIT
-	  const union typeword inttype =
-	  { type:
-	    { MACH_MSG_TYPE_INTEGER_T, sizeof (integer_t) * 8, 1, 1, 0, 0 }
-	  };
-#endif
 	  if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID &&
 	      msg.head.msgh_size >= sizeof msg.error &&
 	      !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX) &&

Reply via email to