[comp.unix.questions] getting the exit value of an exec'd program

atul@NCoast.ORG (Atul Parulekar) (08/16/90)

May be the answer is in the manual, but I have not been able to find it.
My problem is that if I run a program using fork and execvp, how do I get
the exit value of the exec'd program into the main program.

gt0178a@prism.gatech.EDU (BURNS,JIM) (08/16/90)

in article <1990Aug15.223952.1175@NCoast.ORG>, atul@NCoast.ORG (Atul Parulekar) says:
> May be the answer is in the manual, but I have not been able to find it.
> My problem is that if I run a program using fork and execvp, how do I get
> the exit value of the exec'd program into the main program.

Exec doesn't return a status - it doesn't return at all. Use wait(2) in
the parent program. Its man page describes the union wait status variable
returned by wait(2) and its variants. (Exact return type also varies
between wait() variants and diff. unices.)
-- 
BURNS,JIM
Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332
uucp:	  ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a
Internet: gt0178a@prism.gatech.edu

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/16/90)

In article <1990Aug15.223952.1175@NCoast.ORG> atul@NCoast.ORG (Atul Parulekar) writes:
>May be the answer is in the manual, but I have not been able to find it.
>My problem is that if I run a program using fork and execvp, how do I get
>the exit value of the exec'd program into the main program.

Via wait().

The general procedure for running a subprocess is, in outline:

	switch ( (pid = fork()) )
		{
	case -1:
		Punt( "unable to fork" );
		/*NOTREACHED*/

	case 0:		/* child */
		args[0] = "command";
		execvp( args[0], args );	/* WARNING: uses $PATH */
		_exit( 127 );
		/*NOTREACHED*/

	default:	/* parent */
		while ( (w = wait( &status )) != pid )
			if ( w == -1 && errno != EINTR )
				break;

		if ( w == -1 )
			{
			Punt( "child disappeared" );
			/*NOTREACHED*/
			}
		else if ( (status & 0xFF) != 0 )
			{
			/* (status & 0x7F) is the signal number */
			/* (status & 0x80) != 0 iff core dumped */
			Punt( "child terminated abnormally" );
			/*NOTREACHED*/
			}
		else
			status = status >> 8 & 0xFF;	/* exit status */
		}

guy@auspex.auspex.com (Guy Harris) (08/18/90)

>Its man page describes the union wait status variable
>returned by wait(2) and its variants. (Exact return type also varies
>between wait() variants and diff. unices.)

Don't waste time with "union wait".  BSD isn't *really* different from
other UNIX variants; "wait" *really* fills in an "int", not a "union
wait *".  (If you don't believe me, check out the kernel code that
implements "wait" - it fills in "u_rval2", which is an "int", with the
exit status.)  "union wait" is just a hack that gives the individual
bits of the "int" individual names; unfortunately, it does that with bit
fields, which are C-implementation-dependent, while the actual bits are
C-implementation-*in*dependent.

If you write code not using "union wait", it'll work just fine on BSD
systems - and even pass "lint" in 4.4BSD, although not in earlier
releases, because POSIX says it's an "int", period.  It'll also work on
systems that lack "union wait", e.g. vanilla S5 (at least prior to S5R4;
they may have stuck in "/usr/ucbinclude/sys/wait.h" in S5R4 to make it
easier to recompile BSD programs).  If you write code using "union
wait", and make it generally available, somebody'll probably try porting
it to S5 and have one more porting obstacle to deal with before it
works....