#include // for spawnvpe() (not specified by The Open Group) #include // for execvp() #include // for printf() #include // for errno #include // for strdup(), strerror() #include // for getenv() int main (int argc, const char *argv[]) { const char const *args[3]; char *mutable_args[3]; // See http://c-faq.com/ansi/constmismatch.html explaining that a promise // of constness of values pointed to by pointer elements requires constness // of pointers as well. In other words, a const char** parameter cannot // accept a char ** argument. const char *envp[2]; const char *pathvalue = NULL; char *pathenv = NULL; int ec; if ( argc < 2 ) { return 2; } args[ 0 ] = argv[1]; args[ 1 ] = "abc"; args[ 2 ] = NULL; mutable_args[ 0 ] = strdup( args[ 0 ] ); mutable_args[ 1 ] = strdup( args[ 1 ] ); mutable_args[ 2 ] = NULL; pathvalue = getenv( "PATH" ); if (pathvalue) { int pathlen = strlen( pathvalue ); pathenv = malloc( 5 + pathlen + 1 ); if ( pathenv ) { memcpy( pathenv, "PATH=", 5 ); memcpy( pathenv + 5, pathvalue, pathlen + 1 ); } } envp[ 0 ] = pathenv; envp[ 1 ] = NULL; setbuf( stdout, NULL ); setbuf( stderr, NULL ); printf( "Spawning %s with search in $PATH and a limited environment...\n", args[ 0 ] ); ec = spawnvpe( _P_WAIT, args[ 0 ], args, envp ); printf( "Exit code: %d\n\n", ec ); printf( "Loading %s with search in $PATH and inherited environment...\n", args[ 0 ] ); // The prototype in unistd.h differs from the one in process.h. The former // does not promise to keep the pointers intact. execvp( args[ 0 ], mutable_args ); ec = errno; printf( "Load error: %s (%d)\n", strerror( ec ), ec ); return ec; }