From: andy@cs.caltech.edu (Andy Fyfe)
Newsgroups: comp.sys.3b1
Subject: Re: Taylor uucp 1.4 gamma on 3B1 with TCP (long)
Date: 23 Jan 1993 22:29:17 GMT
Organization: California Institute of Technology
NNTP-Posting-Host: kodiak.cs.caltech.edu

The following two excerpts turn out to be stangely related (even though
they're from the same thread!).

>In article <1993Jan19.054921.1557@ohare.Chicago.COM> kls@ohare.Chicago.COM (Karl Swartz) writes:
>If it links, the route must exist.  Unfortunately, the gcc
>version I have (1.40) returns 0 even if the link fails.  The includes
>are also not specified.  So, the very first step is to change configure.

In article <1993Jan23.050509.7515@d-and-d.com> dnichols@d-and-d.com (DoN. Nichols) writes:
>In article <1993Jan21.123039.8504@ohare.Chicago.COM> kls@ohare.Chicago.COM (Karl Swartz) writes:
>>And then there's <sys/wait.h> -- the Wollongong version is essentially
>>a no-op, so if you get that turkey you'll be missing all the stuff in
>>the standard version.
>
>	You're right - perhaps that should be changed to include
><sys/wait.h>.

The problem Karl (and at least one other person I recently talked to)
had with configure, caused by gcc erroneouly returning an exit status
of 0, is probably the result of using shld, which calls /bin/ld to do
the actual linking.  Shld uses wait() to wait for ld, and to get its
return status, which it then returns to gcc.  And it manipulates the
returned status from wait using the union defined in <sys/wait.h>, part
of which looks like
    struct {
	unsigned short	w_Termsig:7;	/* termination signal */
	unsigned short	w_Coredump:1;	/* core dump indicator */
	unsigned short	w_Retcode:8;	/* exit code if w_termsig==0 */
    } w_T;
Which would be perfect if only the 3b1 were a little-endian machine!

To work on the 3b1, the struct needs to be reversed, and padding
added to skip the high 16 bits, namely
    struct {
	unsigned short	w_padding:16;	/* ignore the high order 16 bits */
	unsigned short	w_Retcode:8;	/* exit code if w_termsig==0 */
	unsigned short	w_Coredump:1;	/* core dump indicator */
	unsigned short	w_Termsig:7;	/* termination signal */
    } w_T;

Code that doesn't use <sys/wait.h> may very well be better off!

I've changed shld to skip the "union wait" business altogether, and
updated the copy on ftp.cs.caltech.edu:pub/3b1/gcc-1.42/shld.shar.Z
(This only applies to gcc 1.x, which is why shld is in with gcc 1.42.
(shld can be used with other version of gcc 1.x.)  Gcc 2.x uses a
patched version of the collect program.)  I'm including the patch here,
as well as a short test program if you want to check out your copy of
<sys/wait.h>.

Andy Fyfe					andy@cs.caltech.edu

#!/bin/sh
# This is a shell archive (shar 3.46)
# made 01/23/1993 22:20 UTC by andy@kodiak
# Source directory /tmp_mnt/ufs/vortex/andy
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#    997 -rw-r--r-- shld.diff
#    567 -rw-r--r-- test.c
#
# ============= shld.diff ==============
if test -f 'shld.diff' -a X"$1" != X"-c"; then
	echo 'x - skipping shld.diff (File already exists)'
else
echo 'x - extracting shld.diff (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'shld.diff' &&
diff -c2 old/ld.c new/ld.c
*** old/ld.c	Wed Jan 20 15:49:22 1993
--- new/ld.c	Wed Jan 20 15:49:26 1993
***************
*** 10,14 ****
X  #include <signal.h>
X  #include <sys/types.h>
- #include <sys/wait.h>
X  #include <sys/stat.h>
X  
--- 10,13 ----
***************
*** 153,157 ****
X  #endif
X      int pid;
!     union wait status;
X  
X  #ifdef DEBUG
--- 152,156 ----
X  #endif
X      int pid;
!     int status;
X  
X  #ifdef DEBUG
***************
*** 177,186 ****
X  	while (pid != wait(&status))
X  	    ;
! 	if (status.w_termsig == 0)
! 	    return status.w_retcode;
X  	else {
X  	    fprintf(stderr, "%s: caught signal %d%s\n",
! 		cmd_name, status.w_termsig,
! 		(status.w_coredump ? " (core dumped)" : ""));
X  	    return 1;
X  	}
--- 176,185 ----
X  	while (pid != wait(&status))
X  	    ;
! 	if ((status & 0x7f) == 0)
! 	    return status >> 8;
X  	else {
X  	    fprintf(stderr, "%s: caught signal %d%s\n",
! 		cmd_name, status & 0x7f,
! 		(status & 0x80 ? " (core dumped)" : ""));
X  	    return 1;
X  	}
SHAR_EOF
chmod 0644 shld.diff ||
echo 'restore of shld.diff failed'
Wc_c="`wc -c < 'shld.diff'`"
test 997 -eq "$Wc_c" ||
	echo 'shld.diff: original size 997, current size' "$Wc_c"
fi
# ============= test.c ==============
if test -f 'test.c' -a X"$1" != X"-c"; then
	echo 'x - skipping test.c (File already exists)'
else
echo 'x - extracting test.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'test.c' &&
#include <sys/wait.h>
main(argc, argv)
int argc;
char *argv[];
{
X    int pid;
X    union wait status;
X
X    pid = fork();
X    if (pid == -1) {
X	printf("fork failed\n");
X	exit(1);
X    }
X    if (pid == 0) { /* child */
X	pid = atoi(argv[1]);
X	if (pid >= 0) exit(pid);
X	kill(getpid(), -pid);
X    }
X    wait(&status);
X    printf("status is %d\n", status.w_status);
X    if (status.w_termsig == 0)
X	printf("child exits %d\n", status.w_retcode);
X    else
X	printf("child caught signal %d%s\n", status.w_termsig,
X	    (status.w_coredump ? " (core dumped)" : ""));
X    exit(0);
}
SHAR_EOF
chmod 0644 test.c ||
echo 'restore of test.c failed'
Wc_c="`wc -c < 'test.c'`"
test 567 -eq "$Wc_c" ||
	echo 'test.c: original size 567, current size' "$Wc_c"
fi
exit 0
Newsgroups: comp.sys.3b1