#include #include #include #include #include /* needed for vfork(), _exit() prototypes */ #include #include #include #include #include char* string = ""; #define MAXARGC 80 #define DEBUG_EXECCMD 0 #define EXITBAD 1 int main() { static int initialized = 0; int out[2]; int err[2]; int slot; int len; char * argv[ MAXARGC + 1 ]; /* +1 for NULL */ { argv[ 0 ] = "/bin/sh"; argv[ 1 ] = "-c"; argv[ 2 ] = string; argv[ 3 ] = 0; if ( DEBUG_EXECCMD ) { int i; for(i = 0; i < 3; ++i) { printf( "argv[%d] = '%s'\n", i, argv[ i ] ); } } } /* Create pipes from child to parent. */ { if ( pipe( out ) < 0 ) exit( EXITBAD ); fcntl( out[0], F_SETFL, O_NONBLOCK ); fcntl( out[1], F_SETFL, O_NONBLOCK ); if ( pipe( err ) < 0 ) exit( EXITBAD ); fcntl( err[0], F_SETFL, O_NONBLOCK ); fcntl( err[1], F_SETFL, O_NONBLOCK ); } /* Start the command */ int pid; if ( (pid = fork()) == 0 ) { int pid = getpid(); dup2( out[1], STDOUT_FILENO ); if ( 0 ) { dup2( out[1], STDERR_FILENO ); close( err[1] ); } else dup2( err[1], STDERR_FILENO ); /* Make this process a process group leader so that when we kill it, all * child processes of this process are terminated as well. We use * killpg(pid, SIGKILL) to kill the process group leader and all its * children. */ setpgid( pid,pid ); execvp( argv[0], argv ); perror( "execvp" ); _exit( 127 ); } else { int exit_code; wait(&exit_code); printf("%d\n", exit_code); } }