summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--hurd/intr-msg.c21
-rw-r--r--posix/glob.c16
-rw-r--r--sysdeps/i386/dl-machine.h1
-rw-r--r--sysdeps/mach/hurd/select.c33
5 files changed, 73 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index b945b72d1b..37fdf9f7e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+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.
+
 Tue Aug 29 12:35:56 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
 	* time/australasia: Updated data from ADO.
diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c
index 024cbfbd3e..b345e72cc4 100644
--- a/hurd/intr-msg.c
+++ b/hurd/intr-msg.c
@@ -35,6 +35,9 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 {
   struct hurd_sigstate *ss = _hurd_self_sigstate ();
   error_t err;
+  /* Notice now if the user requested a timeout.  OPTION may have the bit
+     added by interruption semantics, and we must distinguish.  */
+  int user_timeout = option & MACH_RCV_TIMEOUT;
 
   /* Tell the signal thread that we are doing an interruptible RPC on
      this port.  If we get a signal and should return EINTR, the signal
@@ -64,6 +67,15 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 
   switch (err)
     {
+    case MACH_RCV_TIMED_OUT:
+      if (user_timeout)
+	/* The real user RPC timed out.  */
+	break;
+      else
+	/* The operation was supposedly interrupted, but still has
+	   not returned.  Declare it interrupted.  */
+	goto interrupted;
+
     case MACH_SEND_INTERRUPTED: /* RPC didn't get out.  */
       if (ss->intr_port != MACH_PORT_NULL)
 	/* If this signal was for us and it should interrupt calls, the
@@ -78,10 +90,7 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 	 so the signal thread destroyed the reply port.  */
       /* FALLTHROUGH */
 
-    case MACH_RCV_TIMED_OUT:
-      /* The operation was supposedly interrupted, but still has
-	 not returned.  Declare it interrupted.  */
-
+    interrupted:
       err = EINTR;
 
       /* The EINTR return indicates cancellation, so clear the flag.  */
@@ -95,7 +104,9 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg,
 	  /* This signal or cancellation was for us.  We need to wait for
              the reply, but not hang forever.  */
 	  option |= MACH_RCV_TIMEOUT;
-	  timeout = _hurd_interrupted_rpc_timeout;
+	  /* Never decrease the user's timeout.  */
+	  if (!user_timeout || timeout > _hurd_interrupted_rpc_timeout)
+	    timeout = _hurd_interrupted_rpc_timeout;
 	}
       goto message;		/* Retry the receive.  */
 
diff --git a/posix/glob.c b/posix/glob.c
index 1354150653..84fe19420b 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -417,7 +417,17 @@ glob (pattern, flags, errfunc, pglob)
       for (i = oldcount; i < pglob->gl_pathc; ++i)
 	if (__lstat (pglob->gl_pathv[i], &st) == 0 &&
 	    S_ISDIR (st.st_mode))
-	  strcat (pglob->gl_pathv[i], "/");
+	  {
+ 	    size_t len = strlen (pglob->gl_pathv[i]) + 2;
+	    char *new = realloc (pglob->gl_pathv[i], len);
+ 	    if (new == NULL)
+	      {
+		globfree (pglob);
+		return GLOB_NOSPACE;
+	      }
+	    strcpy (&new[len - 2], "/");
+	    pglob->gl_pathv[i] = new;
+	  }
     }
 
   if (!(flags & GLOB_NOSORT))
@@ -617,7 +627,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
 		if (len == 0)
 		  len = strlen (name);
 		new->name
-		  = (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1);
+		  = (char *) malloc (len + 1);
 		if (new->name == NULL)
 		  goto memory_error;
 		memcpy ((__ptr_t) new->name, name, len);
@@ -635,7 +645,7 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
       nfound = 1;
       names = (struct globlink *) __alloca (sizeof (struct globlink));
       names->next = NULL;
-      names->name = (char *) malloc (len + ((flags & GLOB_MARK) ? 1 : 0) + 1);
+      names->name = (char *) malloc (len + 1);
       if (names->name == NULL)
 	goto memory_error;
       memcpy (names->name, pattern, len);
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 57637a936f..d509e08b6f 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -66,6 +66,7 @@ elf_machine_load_address (void)
    we skip it to avoid trying to modify read-only text in this early stage.  */
 #define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
   ++(const Elf32_Rel *) (dynamic_info)[DT_REL]->d_un.d_ptr;
+  (dynamic_info)[DT_RELSZ]->d_un.d_val -= sizeof (Elf32_Rel);
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
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]);