[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] 3.0: Unimplemented WCONTINUED causing a hang
From: |
Maciej W. Rozycki |
Subject: |
[PATCH] 3.0: Unimplemented WCONTINUED causing a hang |
Date: |
Tue, 17 May 2005 18:38:59 +0100 (BST) |
Hello,
I've triggered this problem using glibc 2.3.5 and Linux 2.4.29 with a
mips64el-linux-gnu host. With such a configuration bash 3.0 (release,
patch level 16) hangs in the interactive mode when a command resulting in
forking a subprocess in the foreground concludes. I've tracked it down to
the WCONTINUED waitpid() flag (for this host it gets actually translated
to the wait4() syscall) that's used by bash, but unimplemented by this
version of Linux (it's only implemented by Linux 2.6.x and actually not
processor-dependent). As a result the syscall (and its wrapping library
function) returns unsuccessfully with the EINVAL error code. A search of
the net reveals this error code for invalid options for the function
(syscall) is not specific to Linux, so it should be safe to be used here.
I've implemented a fix as follows which works for me. If unimplemented
the WCONTINUED flag is tried only once -- this helps performance. Note
that glibc cannot determine which version of Linux it's going to be run
on, so it cannot define the flag in its headers conditionally.
2005-05-17 Maciej W. Rozycki <macro@linux-mips.org>
* jobs.c (waitchld): Detect WCONTINUED being unimplemented and
stop using it if so.
Please apply.
Maciej
bash-3.0-wcontinued.patch
diff -up --recursive --new-file bash-3.0.macro/jobs.c bash-3.0/jobs.c
--- bash-3.0.macro/jobs.c 2004-04-23 20:28:25.000000000 +0000
+++ bash-3.0/jobs.c 2005-05-16 03:55:32.000000000 +0000
@@ -2467,6 +2467,7 @@ waitchld (wpid, block)
pid_t wpid;
int block;
{
+ static int wcontinued = WCONTINUED;
WAIT status;
PROCESS *child;
pid_t pid;
@@ -2480,12 +2481,19 @@ waitchld (wpid, block)
/* We don't want to be notified about jobs stopping if job control
is not active. XXX - was interactive_shell instead of job_control */
waitpid_flags = (job_control && subshell_environment == 0)
- ? (WUNTRACED|WCONTINUED)
+ ? (WUNTRACED|wcontinued)
: 0;
if (sigchld || block == 0)
waitpid_flags |= WNOHANG;
pid = WAITPID (-1, &status, waitpid_flags);
+ /* WCONTINUED may not always be accepted. */
+ if (wcontinued && pid < 0 && errno == EINVAL)
+ {
+ wcontinued = 0;
+ continue; /* jumps right to the test */
+ }
+
/* The check for WNOHANG is to make sure we decrement sigchld only
if it was non-zero before we called waitpid. */
if (sigchld > 0 && (waitpid_flags & WNOHANG))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] 3.0: Unimplemented WCONTINUED causing a hang,
Maciej W. Rozycki <=