[comp.os.minix] system

tholm@uvicctr.UUCP (Terrence W. Holm) (10/26/88)

EFTH MINIX report #52  - October 1988 -  system(3) fix


The MINIX 1.3 system(3) uses an exit() if the fork()
fails, and does not ignore sigint/sigquit in the waiting
process. These problems can cause strange behavior, see
the recently posted CKermit binary for an example.

The following should fix these problems.

----------------------------------------------------------
echo x - system.3
gres '^X' '' > system.3 << '/'
XSUBROUTINES
X    system(3)		- execute a shell command line
X
XINVOCATION
X    int system( command )
X      char *command;
X
XEXPLANATION
X    A process is created to execute <command>, using the Bourne
X    shell sh(1). The invoker waits with SIGINT and SIGQUIT ignored,
X    until the sub-shell terminates.
X
XRESULTS
X    o/w    : Result from wait(2).
X    0x7f00 : Insufficient memory to fork.
X    -1     : An unexpected signal occurred.
X
XREFERENCES
X    sh(1), signal(2), wait(2), popen(3)
/
echo x - system.c
gres '^X' '' > system.c << '/'
X/*  system.c
X *
X *  Changed to return() on fork failure, added signal()
X *  calls.          Terrence W. Holm      Oct. 1988
X */
X
X#include <stdio.h>
X#include <signal.h>
X
Xsystem(cmd)
Xchar *cmd;
X{
X    int retstat, procid, waitstat;
X    void (*sigint)(), (*sigquit)();
X
X    if ( (procid = fork()) == 0) {
X	/* Child does an exec of the command. */
X        execl( "/bin/sh", "sh", "-c", cmd, 0 );
X        exit( 127 );
X    }
X
X    /* Check to see if fork failed. */
X    if (procid < 0) return( 127 << 8 );
X
X    sigint  = signal( SIGINT,  SIG_IGN );
X    sigquit = signal( SIGQUIT, SIG_IGN );
X
X    while ( (waitstat = wait(&retstat)) != procid && waitstat != -1 ) ;
X    if (waitstat == -1) retstat = -1;
X
X    signal( SIGINT,  sigint );
X    signal( SIGQUIT, sigquit );
X
X    return(retstat);
X}
/
----------------------------------------------------------

		Terrence W. Holm
		  uw-beaver!uvicctr!tholm