bill@elk.stat.washington.edu (Bill Dunlap) (05/07/89)
We have a 3/280 file server running SunOS 4.0 and some 3/50 clients are
running SunOS 3.2. The following program, when compiled (with -Bstatic)
on the 4.0 machine bombs when run on the 3.2 machine complaining about a
bad argument to wait(2). It works when compiled and run on the same
machine and when compiled on 3.2 and run on 4.0.
main()
{
system("ls -ls") ;
}
I checked the man pages and note that wait(2) took an int (the pid) in 3.2
but takes a (union wait *) in 4.0 and that system(3) calls wait(2).
Is there a fix for this problem? Should I not be expecting to be able to
run 4.0 binaries on a 3.2 system? The owner of the 3/50 (SunOS 3.2) is in
no hurry to downgrade his machine to 4.0.
Bill Dunlap
bill@elk.stat.washington.edu
[[ In general, I would not recommend trying to run 4.0 binaries under 3.2.
--wnl ]]
guy@uunet.uu.net (Guy Harris) (05/11/89)
>I checked the man pages and note that wait(2) took an int (the pid) in 3.2 >but takes a (union wait *) in 4.0 and that system(3) calls wait(2). I'm somewhat surprised about this; I thought the 3.2 man page was *more* insistent than the 4.0 man page about using the stupid "union wait" (in fact, I remember making the 4.0 man page less insistent...). "union wait" was the idea of some well-intentioned chap at Berkeley. (S)he wanted, apparently, to provide a nice way of dissecting an status from "wait" - no, "wait(2)" never took an "int" as an argument; it has, since time immemorial in UNIX, or at least since V6, taken an "int *", which points to a variable into which the exit status from the program is stuffed. The *return value* of "wait" is the PID of the process that exited. Unfortunately, (s)he used bitfields, which depend on the C implementation; some implementations go from most-significant-bit to least-significant-bit in assigning bit fields, and others go the other way around. However, UNIX has always specified the bit fields of an exit status in an implementation-*independent* fashion. The "fix" was to put "#ifdef"s into the bit-field definitions. Furthermore, UNIX systems other than BSD use just an "int *" as the argument to "wait"; if you use the "union wait" stuff, your code is not portable to those systems. However, since the "union wait" stuff represents only a change in: 1) the manual pages; 2) the include files (<wait.h> was added); 3) the "lint" library and *not* a change in the BSD kernel - the kernel still thinks it works the traditional way, with an "int *" - you can still use the "int *" and have it work, the "union wait *" glop nonwithstanding. The 4.0 man page describes this: The other members of the wait() union merely provide an alternate way of analyzing the status. The value stored in the w_status field is compatible with the values stored by other versions of the UNIX system, and an argument of type int * may be provided instead of an argument of type union wait * for compatibility with those versions. The underlying problem lies elsewhere: >Is there a fix for this problem? Should I not be expecting to be able to >run 4.0 binaries on a 3.2 system? The owner of the 3/50 (SunOS 3.2) is in >no hurry to downgrade his machine to 4.0. > >[[ In general, I would not recommend trying to run 4.0 binaries under 3.2. >--wnl ]] William is right; no guarantees are offered that binaries built under 4.0 will run under *any* 3.x release (not even if linked statically - they obviously won't work if linked dynamically). In 4.0, "wait" and "wait3" are wrappers around the new "wait4" system call; as such, code using "wait" won't work under 3.x systems lacking "wait4".