summaryrefslogtreecommitdiff
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
parent18926cf415b65008c849b592209a85f733be39f7 (diff)
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.
-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]);