From a993273c0d4d1907028adee7a2ae012826fd316c Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 31 Aug 1995 00:02:32 +0000 Subject: Wed Aug 30 16:44:55 1995 Roland McGrath * 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. --- ChangeLog | 15 +++++++++++++++ hurd/intr-msg.c | 21 ++++++++++++++++----- posix/glob.c | 16 +++++++++++++--- sysdeps/i386/dl-machine.h | 1 + sysdeps/mach/hurd/select.c | 33 ++++++++++++++++++++++++++++----- 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 + + * 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 * 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]); -- cgit v1.2.3