chip@ateng.ateng.com (Chip Salzenberg) (01/23/90)
As distributed, Bash 1.04 includes a SysV emulation of the BSD "union wait".
This emulation is slightly broken. It is also unnecessarily complex and
non-portable. This patch fixes the bugs and implements the wait() call in a
way that should be portable even to BSD. (After all, "union wait" is an
optional sugar-coating on the raw V7 semantics of wait().)
Index: jobs.h
***************
*** 6,73 ****
#include <sys/wait.h>
#else
-
- #if defined (i386) || defined (ATT3B) || defined (ATT386)
-
- union wait {
- struct {
- unsigned char low;
- unsigned char high;
- }
- bytes;
- short word;
- };
-
- #define WSTOPPED 0177
- #define w_status word
- #define w_termsig bytes.low & 0x7f
- #define w_stopsig bytes.high
- #define w_retcode bytes.high
- #define w_coredump w_termsig & ~0x7f
- #define WIFEXITED(wstat) ((wstat).bytes.low == 0)
- #define WIFSTOPPED(wstat) ((wstat).bytes.low == 0177)
- #define WIFTERMINATED(wstat) ((wstat).bytes.high == 0)
-
- #else /* i386 || ATT3B || ATT386 */
-
- #ifdef NO_WAIT_H
union wait
{
! int w_status; /* used in syscall */
!
! /* Terminated process status. */
! struct
! {
! unsigned short
! w_Fill1 : 16, /* high 16 bits unused */
! w_Retcode : 8, /* exit code if w_termsig==0 */
! w_Coredump : 1, /* core dump indicator */
! w_Termsig : 7; /* termination signal */
! } w_T;
!
! /* Stopped process status. Returned
! only for traced children unless requested
! with the WUNTRACED option bit. */
! struct
! {
! unsigned short
! w_Fill2 : 16, /* high 16 bits unused */
! w_Stopsig : 8, /* signal that stopped us */
! w_Stopval : 8; /* == W_STOPPED if stopped */
! } w_S;
};
-
- #define w_termsig w_T.w_Termsig
- #define w_coredump w_T.w_Coredump
- #define w_retcode w_T.w_Retcode
- #define w_stopval w_S.w_Stopval
- #define w_stopsig w_S.w_Stopsig
-
- #define WSTOPPED 0177
- #define WIFSTOPPED(x) (((x) . w_stopval) == WSTOPPED)
- #define WIFEXITED(x) ((! (WIFSTOPPED (x))) && (((x) . w_termsig) == 0))
- #define WIFSIGNALED(x) ((! (WIFSTOPPED (x))) && (((x) . w_termsig) != 0))
-
- #endif /* HPUX */
- #endif /* i386 || ATT3B || ATT386 */
#endif /* !defined (SYSV) || defined (UNIXPC) */
--- 6,13 ----
#include <sys/wait.h>
#else
union wait
{
! int w_status;
};
#endif /* !defined (SYSV) || defined (UNIXPC) */
Index: nojobs.c
***************
*** 150,154 ****
int pid;
{
! int got_pid, return_val, oldmask;
union wait status;
#ifndef SYSV
--- 150,154 ----
int pid;
{
! int got_pid, retcode, coredump, termsig, return_val, oldmask;
union wait status;
#ifndef SYSV
***************
*** 162,170 ****
#endif
! while ((got_pid = wait (&status)) != pid)
{
if (got_pid < 0 && errno == ECHILD)
{
! status.w_termsig = status.w_retcode = 0;
break;
}
--- 162,170 ----
#endif
! while ((got_pid = wait (&status.w_status)) != pid)
{
if (got_pid < 0 && errno == ECHILD)
{
! status.w_status = 0;
break;
}
***************
*** 181,194 ****
/* Default return value. */
! return_val = status.w_retcode & 0x7f;
! if (status.w_termsig != 0 && status.w_termsig != WSTOPPED)
{
extern char *sys_siglist[];
! fprintf (stderr, "%s", sys_siglist[status.w_termsig]);
! if (status.w_coredump)
fprintf (stderr, " (core dumped)");
fprintf (stderr, "\n");
! return_val = status.w_termsig + 128;
get_tty_state ();
}
--- 181,208 ----
/* Default return value. */
! #ifdef WSTOPPED
! retcode = status.w_retcode;
! coredump = status.w_coredump
! termsig = status.w_termsig;
! #else
! retcode = (status.w_status >> 8) & 0xff;
! coredump = (status.w_status & 0x80) ? 1 : 0;
! termsig = status.w_status & 0x7f;
! #endif
! return_val = retcode & 0x7f;
!
! if (termsig
! #ifdef WSTOPPED
! && termsig != WSTOPPED
! #endif
! )
{
extern char *sys_siglist[];
! fprintf (stderr, "%s", sys_siglist[termsig]);
! if (coredump)
fprintf (stderr, " (core dumped)");
fprintf (stderr, "\n");
! return_val = termsig + 128;
get_tty_state ();
}