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) &&