1 /* Guts of both `select' and `poll' for Hurd.
2 Copyright (C) 1991,92,93,94,95,96,97,98,99,2001
3 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 #include <sys/types.h>
30 /* All user select types. */
31 #define SELECT_ALL (SELECT_READ | SELECT_WRITE | SELECT_URG)
33 /* Used to record that a particular select rpc returned. Must be distinct
34 from SELECT_ALL (which better not have the high bit set). */
35 #define SELECT_RETURNED ((SELECT_ALL << 1) & ~SELECT_ALL)
37 /* Check the first NFDS descriptors either in POLLFDS (if nonnnull) or in
38 each of READFDS, WRITEFDS, EXCEPTFDS that is nonnull. If TIMEOUT is not
39 NULL, time out after waiting the interval specified therein. Returns
40 the number of ready descriptors, or -1 for errors. */
42 _hurd_select (int nfds,
43 struct pollfd *pollfds,
44 fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
45 const struct timespec *timeout, const sigset_t *sigmask)
51 fd_set rfds, wfds, xfds;
53 mach_msg_timeout_t to = (timeout != NULL ?
54 (timeout->tv_sec * 1000 +
55 timeout->tv_nsec / 1000000) :
59 struct hurd_userlink ulink;
63 mach_port_t reply_port;
67 if (sigmask && __sigprocmask (SIG_SETMASK, sigmask, &oset))
72 /* Collect interesting descriptors from the user's `pollfd' array.
73 We do a first pass that reads the user's array before taking
74 any locks. The second pass then only touches our own stack,
75 and gets the port references. */
77 for (i = 0; i < nfds; ++i)
78 if (pollfds[i].fd >= 0)
81 if (pollfds[i].events & POLLIN)
83 if (pollfds[i].events & POLLOUT)
85 if (pollfds[i].events & POLLPRI)
88 d[i].io_port = pollfds[i].fd;
95 __mutex_lock (&_hurd_dtable_lock);
97 for (i = 0; i < nfds; ++i)
100 const int fd = (int) d[i].io_port;
102 if (fd < _hurd_dtablesize)
104 d[i].cell = _hurd_dtable[fd];
105 d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink);
106 if (d[i].io_port != MACH_PORT_NULL)
110 /* If one descriptor is bogus, we fail completely. */
113 _hurd_port_free (&d[i].cell->port,
114 &d[i].ulink, d[i].io_port);
118 __mutex_unlock (&_hurd_dtable_lock);
124 __sigprocmask (SIG_SETMASK, &oset, NULL);
130 firstfd = i == 0 ? lastfd : 0;
134 /* Collect interested descriptors from the user's fd_set arguments.
135 Use local copies so we can't crash from user bogosity. */
141 if (writefds == NULL)
145 if (exceptfds == NULL)
151 __mutex_lock (&_hurd_dtable_lock);
153 if (nfds > _hurd_dtablesize)
154 nfds = _hurd_dtablesize;
156 /* Collect the ports for interesting FDs. */
157 firstfd = lastfd = -1;
158 for (i = 0; i < nfds; ++i)
161 if (readfds != NULL && FD_ISSET (i, &rfds))
163 if (writefds != NULL && FD_ISSET (i, &wfds))
164 type |= SELECT_WRITE;
165 if (exceptfds != NULL && FD_ISSET (i, &xfds))
170 d[i].cell = _hurd_dtable[i];
171 d[i].io_port = _hurd_port_get (&d[i].cell->port, &d[i].ulink);
172 if (d[i].io_port == MACH_PORT_NULL)
174 /* If one descriptor is bogus, we fail completely. */
177 _hurd_port_free (&d[i].cell->port, &d[i].ulink,
187 __mutex_unlock (&_hurd_dtable_lock);
193 __sigprocmask (SIG_SETMASK, &oset, NULL);
203 /* Send them all io_select request messages. */
206 /* But not if there were no ports to deal with at all.
207 We are just a pure timeout. */
208 portset = __mach_reply_port ();
211 portset = MACH_PORT_NULL;
213 for (i = firstfd; i <= lastfd; ++i)
216 int type = d[i].type;
217 d[i].reply_port = __mach_reply_port ();
218 err = __io_select (d[i].io_port, d[i].reply_port,
219 /* Poll only if there's a single descriptor. */
220 (firstfd == lastfd) ? to : 0,
224 case MACH_RCV_TIMED_OUT:
225 /* No immediate response. This is normal. */
227 if (firstfd == lastfd)
228 /* When there's a single descriptor, we don't need a
229 portset, so just pretend we have one, but really
230 use the single reply port. */
231 portset = d[i].reply_port;
233 /* We've got multiple reply ports, so we need a port set to
236 /* We will wait again for a reply later. */
237 if (portset == MACH_PORT_NULL)
238 /* Create the portset to receive all the replies on. */
239 err = __mach_port_allocate (__mach_task_self (),
240 MACH_PORT_RIGHT_PORT_SET,
243 /* Put this reply port in the port set. */
244 __mach_port_move_member (__mach_task_self (),
245 d[i].reply_port, portset);
250 /* No other error should happen. Callers of select
251 don't expect to see errors, so we simulate
252 readiness of the erring object and the next call
253 hopefully will get the error again. */
258 /* We got an answer. */
259 if ((type & SELECT_ALL) == 0)
260 /* Bogus answer; treat like an error, as a fake positive. */
263 /* This port is already ready already. */
265 d[i].type |= SELECT_RETURNED;
269 _hurd_port_free (&d[i].cell->port, &d[i].ulink, d[i].io_port);
273 /* Now wait for reply messages. */
274 if (!err && got == 0)
276 /* Now wait for io_select_reply messages on PORT,
277 timing out as appropriate. */
281 mach_msg_header_t head;
282 #ifdef MACH_MSG_TRAILER_MINIMUM_SIZE
285 mach_msg_header_t head;
291 mach_msg_header_t head;
295 mach_msg_trailer_t trailer;
300 mach_msg_header_t head;
301 mach_msg_type_t err_type;
306 mach_msg_header_t head;
307 mach_msg_type_t err_type;
309 mach_msg_type_t result_type;
314 mach_msg_option_t options = (timeout == NULL ? 0 : MACH_RCV_TIMEOUT);
316 while ((msgerr = __mach_msg (&msg.head,
317 MACH_RCV_MSG | options,
318 0, sizeof msg, portset, to,
319 MACH_PORT_NULL)) == MACH_MSG_SUCCESS)
321 /* We got a message. Decode it. */
322 #define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
323 #ifdef MACH_MSG_TYPE_BIT
324 const mach_msg_type_t inttype =
325 { MACH_MSG_TYPE_INTEGER_T, sizeof (MACH_MSG_TYPE_INTEGER_T) * 8,
328 if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID
329 && msg.head.msgh_size >= sizeof msg.error
330 && !(msg.head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
331 #ifdef MACH_MSG_TYPE_BIT
332 && *(int *) &msg.error.err_type == *(int *) &inttype
336 /* This is a properly formatted message so far.
337 See if it is a success or a failure. */
338 if (msg.error.err == EINTR &&
339 msg.head.msgh_size == sizeof msg.error)
341 /* EINTR response; poll for further responses
342 and then return quickly. */
347 msg.head.msgh_size != sizeof msg.success ||
348 #ifdef MACH_MSG_TYPE_BIT
349 *(int *) &msg.success.result_type != *(int *) &inttype ||
351 (msg.success.result & SELECT_ALL) == 0)
353 /* Error or bogus reply. Simulate readiness. */
354 __mach_msg_destroy (&msg.head);
355 msg.success.result = SELECT_ALL;
358 /* Look up the respondent's reply port and record its
363 for (i = firstfd; i <= lastfd; ++i)
365 && d[i].reply_port == msg.head.msgh_local_port)
367 d[i].type &= msg.success.result;
368 d[i].type |= SELECT_RETURNED;
375 if (msg.head.msgh_remote_port != MACH_PORT_NULL)
376 __mach_port_deallocate (__mach_task_self (),
377 msg.head.msgh_remote_port);
382 /* Poll for another message. */
384 options |= MACH_RCV_TIMEOUT;
388 if (err == MACH_RCV_TIMED_OUT)
389 /* This is the normal value for ERR. We might have timed out and
390 read no messages. Otherwise, after receiving the first message,
391 we poll for more messages. We receive with a timeout of 0 to
392 effect a poll, so ERR is MACH_RCV_TIMED_OUT when the poll finds no
397 /* At least one descriptor is known to be ready now, so we will
403 for (i = firstfd; i <= lastfd; ++i)
405 __mach_port_destroy (__mach_task_self (), d[i].reply_port);
406 if (firstfd == -1 || (firstfd != lastfd && portset != MACH_PORT_NULL))
407 /* Destroy PORTSET, but only if it's not actually the reply port for a
408 single descriptor (in which case it's destroyed in the previous loop;
409 not doing it here is just a bit more efficient). */
410 __mach_port_destroy (__mach_task_self (), portset);
415 __sigprocmask (SIG_SETMASK, &oset, NULL);
416 return __hurd_fail (err);
420 /* Fill in the `revents' members of the user's array. */
421 for (i = 0; i < nfds; ++i)
423 int type = d[i].type;
424 int_fast16_t revents = 0;
426 if (type & SELECT_RETURNED)
428 if (type & SELECT_READ)
430 if (type & SELECT_WRITE)
432 if (type & SELECT_URG)
436 pollfds[i].revents = revents;
440 /* Below we recalculate GOT to include an increment for each operation
441 allowed on each fd. */
444 /* Set the user bitarrays. We only ever have to clear bits, as all
445 desired ones are initially set. */
447 for (i = firstfd; i <= lastfd; ++i)
449 int type = d[i].type;
451 if ((type & SELECT_RETURNED) == 0)
454 if (type & SELECT_READ)
458 if (type & SELECT_WRITE)
461 FD_CLR (i, writefds);
462 if (type & SELECT_URG)
465 FD_CLR (i, exceptfds);
469 if (sigmask && __sigprocmask (SIG_SETMASK, &oset, NULL))