summary refs log tree commit diff
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.gz
glibc-a993273c0d4d1907028adee7a2ae012826fd316c.tar.xz
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]);