aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/mach/hurd/select.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-08-31 00:02:32 +0000
committerRoland McGrath <roland@gnu.org>1995-08-31 00:02:32 +0000
commita993273c0d4d1907028adee7a2ae012826fd316c (patch)
tree3b1f5f64ea2b79fff7a61283d1ae60ac9291f38f /sysdeps/mach/hurd/select.c
parent18926cf415b65008c849b592209a85f733be39f7 (diff)
downloadglibc-a993273c0d4d1907028adee7a2ae012826fd316c.tar
glibc-a993273c0d4d1907028adee7a2ae012826fd316c.tar.gz
glibc-a993273c0d4d1907028adee7a2ae012826fd316c.tar.bz2
glibc-a993273c0d4d1907028adee7a2ae012826fd316c.zip
Wed Aug 30 16:44:55 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/select.c: Deal with out of order replies during io_select request loop. Handle MACH_RCV_TIMED_OUT error from requests. * hurd/intr-msg.c: If the user passed the MACH_RCV_TIMEOUT option, distinguish MACH_RCV_TIMED_OUT from EINTR. * posix/glob.c (glob): Use realloc to extend strings for GLOB_MARK slash. (glob_in_dir): Don't allocate extra byte here. * sysdeps/i386/dl-machine.h (ELF_MACHINE_BEFORE_RTLD_RELOC): Decrement the DT_RELSZ value for the skipped reloc.
Diffstat (limited to 'sysdeps/mach/hurd/select.c')
-rw-r--r--sysdeps/mach/hurd/select.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/sysdeps/mach/hurd/select.c b/sysdeps/mach/hurd/select.c
index d1c5913cb8..434cfbbec7 100644
--- a/sysdeps/mach/hurd/select.c
+++ b/sysdeps/mach/hurd/select.c
@@ -121,16 +121,39 @@ DEFUN(__select, (nfds, readfds, writefds, exceptfds, timeout),
if (!err)
{
int tag = i;
+ int type = types[i];
err = __io_select (ports[i], port,
/* Poll for each but the last. */
(i == lastfd && got == 0) ? to : 0,
- &types[i], &tag);
- if (!err)
+ &type, &tag);
+ switch (err)
{
- if (tag != i)
+ case MACH_RCV_TIMED_OUT:
+ /* No immediate response. This is normal. */
+ err = 0;
+ break;
+
+ case 0:
+ /* We got an answer. This is not necessarily the answer to
+ the query we sent just now. It may correspond to any
+ prior query which timed out before its answer arrived. */
+ if (tag < 0 || tag > i ||
+ (type & (SELECT_READ|SELECT_URG|SELECT_WRITE)) == 0)
+ /* This is not a proper answer to any query we have yet
+ made. */
err = EGRATUITOUS;
- else if (types[i] & (SELECT_READ|SELECT_URG|SELECT_WRITE))
- ++got;
+ else
+ {
+ /* Some port is ready. TAG tells us which. */
+ types[tag] &= type;
+ ++got;
+ }
+ break;
+
+ default:
+ /* Any other error kills us.
+ But we must continue to loop to free the ports. */
+ break;
}
}
_hurd_port_free (&cells[i]->port, &ulink[i], ports[i]);