#include /* open(2), O_RDONLY */ #include /* fprintf(3), perror(3) */ #if !defined EX_OK || !defined EX_OSERR || !defined EX_USAGE # include #endif #include /* dup(2), dup2(2), fork(2), STDIN_FILENO */ #include /* */ #include /* wait(2), WIFEXITED, WEXITSTATUS */ #include "libpsargs.h" int main(int argc, char *argv[]){ int child; char **corr; char **curr; int fd; int i; int r; if(argc < 2 || check_arg(curr = &argv[1]) != 2){ fprintf(stderr, "Usage: %s \"[\" [command (arguments...)] \"]\"" " \"[\" [command (arguments...)] \"]\"\n", argc == 0 ? "" : argv[0]); return EX_USAGE; } /* substitute standard input for /dev/null */ if((fd = dup(STDIN_FILENO)) < 0 || dup2(open("/dev/null", O_RDONLY), STDIN_FILENO) < 0){ perror(argv[0]); return EX_OSERR; } for(i = 0; ; ++i){ *(corr = corresponding_arg(curr++)) = NULL; if(i == 1 || (r = fork()) == 0) execvp(*curr, curr); if( r == -1 /* fork(2) failed */ || i == 1 || r == 0 /* exec(3) failed */ || dup2(fd, STDIN_FILENO) != STDIN_FILENO){ perror(argv[0]); return EX_OSERR; } wait(&child); if(!WIFEXITED(child) || WEXITSTATUS(child) != 0) return 1; curr = corr + 1; } /* UNREACHABLE */ }