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!goer
bfox@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