goer@sophist.uucp (Richard Goerwitz) (02/10/90)
Silly question?
/* from jobs.h */
union wait {
struct { /* clever way of getting at
unsigned char low; * wait's high and low
unsigned char high; * status bytes
} * /
bytes;
short word;
};
#define WSTOPPED 0177
#define w_status word
#define w_termsig bytes.low & 0x7f /* mask out eighth bit */
#define w_stopsig bytes.high
#define w_retcode bytes.high
/* from nojobs.c, line 163 and following: */
while ((got_pid = wait (&status)) != pid)
{
if (got_pid < 0 && errno == ECHILD)
{
status.w_termsig = status.w_retcode = 0; /* <-- NOTE */
break;
}
else if (got_pid < 0 && errno != EINTR)
programming_error ("got errno %d while waiting for %d", errno, pid);
}
The hitch here is that w_termsig expands to bytes.low & 0x7f. Hence the
entire expression expands to
status.bytes.low & 0x7f = status.w_retcode = 0;
What is the intention here? I'm just curious. If the attempt is being
made to zero out the lower seven bits of status.bytes.low, wouldn't
status.bytes.low &= 0x80;
be more appropriate?
I don't claim to be a wizard. I'm just trying to compile Bash on my
Xenix box.
If this is a silly question, and I should have seen what was going on
I'd still like to know about my mistake.
-Richard L. Goerwitz goer%sophist@uchicago.bitnet
goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goerbfox@sbphy.mit.edu (Brian Fox) (02/10/90)
Date: 9 Feb 90 18:37:47 GMT
From: asuvax!ncar!tank!sophist!goer@cs.utexas.edu (Richard Goerwitz)
Organization: University of Chicago
Sender: bug-bash-request@prep.ai.mit.edu
Silly question?
No.
What is the intention here? I'm just curious. If the attempt is being
made to zero out the lower seven bits of status.bytes.low, wouldn't
status.bytes.low &= 0x80;
be more appropriate?
I don't claim to be a wizard. I'm just trying to compile Bash on my
Xenix box.
If this is a silly question, and I should have seen what was going on
I'd still like to know about my mistake.
You (among others) found this bug in Bash. The problem was a poor
description for the structure returned by wait () on little-endian
machines. We have since fixed the description, and here it is:
#ifdef NO_WAIT_H
#ifdef LITTLE_ENDIAN
union wait
{
int w_status; /* used in syscall */
/* Terminated process status. */
struct
{
unsigned short
w_Termsig : 7, /* termination signal */
w_Coredump : 1, /* core dump indicator */
w_Retcode : 8, /* exit code if w_termsig==0 */
w_Fill1 : 16; /* high 16 bits unused */
} w_T;
/* Stopped process status. Returned
only for traced children unless requested
with the WUNTRACED option bit. */
struct
{
unsigned short
w_Stopval : 8, /* == W_STOPPED if stopped */
w_Stopsig : 8, /* actually zero on XENIX */
w_Fill2 : 16; /* high 16 bits unused */
} w_S;
};
#endif /* LITTLE_ENDIAN */
#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 /* NO_WAIT_H */bengsig@oracle.nl (Bjorn Engsig) (02/13/90)
Article <7551@tank.uchicago.edu> by goer@sophist.UUCP (Richard Goerwitz) says: | struct { /* clever way of getting at | unsigned char low; * wait's high and low | } * / | bytes; |#define w_termsig bytes.low & 0x7f /* mask out eighth bit */ | status.w_termsig = status.w_retcode = 0; /* <-- NOTE */ | |[...] w_termsig expands to bytes.low & 0x7f [and the] expression expands to | | status.bytes.low & 0x7f = status.w_retcode = 0; In many systsem, a system header file will define the struct with bitfields named termsig, etc. but the bash implementors define these as masks to help those without the right header file. They then just this incorrectly, and you should use the masking status.bytes.low &= 0x80 as you suggest. -- Bjorn Engsig, Domain: bengsig@oracle.nl, bengsig@oracle.com Path: uunet!{mcsun!orcenl,oracle}!bengsig