|
|
1.1 ! root 1: #include <bsd/libc.h> /* first to get rid of pre-comp warning */ ! 2: #include <mach/mach.h> /* first to get rid of pre-comp warning */ ! 3: #include "stdio.h" ! 4: #include <signal.h> ! 5: #include <sys/wait.h> ! 6: #include "stuff/errors.h" ! 7: #include "stuff/allocate.h" ! 8: #include "stuff/execute.h" ! 9: ! 10: /* ! 11: * execute() does an execvp using the argv passed to it. If the parameter ! 12: * verbose is non-zero the command is printed to stderr. A non-zero return ! 13: * value indicates success zero indicates failure. ! 14: */ ! 15: int ! 16: execute( ! 17: char **argv, ! 18: long verbose) ! 19: { ! 20: char *name, **p; ! 21: int forkpid, waitpid, termsig; ! 22: union wait waitstatus; ! 23: ! 24: name = argv[0]; ! 25: ! 26: if(verbose){ ! 27: fprintf(stderr, "+ %s ", name); ! 28: p = &(argv[1]); ! 29: while(*p != (char *)0) ! 30: fprintf(stderr, "%s ", *p++); ! 31: fprintf(stderr, "\n"); ! 32: } ! 33: ! 34: forkpid = fork(); ! 35: if(forkpid == -1) ! 36: system_fatal("can't fork a new process to execute: %s", name); ! 37: ! 38: if(forkpid == 0){ ! 39: if(execvp(name, argv) == -1) ! 40: system_fatal("can't find or exec: %s", name); ! 41: return(1); /* can't get here, removes a warning from the compiler */ ! 42: } ! 43: else{ ! 44: waitpid = wait(&waitstatus); ! 45: if(waitpid == -1) ! 46: system_fatal("wait on forked process %d failed", forkpid); ! 47: termsig = waitstatus.w_termsig; ! 48: if(termsig != 0 && termsig != SIGINT) ! 49: fatal("fatal error in %s", name); ! 50: return(waitstatus.w_retcode == 0 && termsig == 0); ! 51: } ! 52: } ! 53: ! 54: /* ! 55: * runlist is used by the routine execute_list() to execute a program and it ! 56: * contains the command line arguments. Strings are added to it by ! 57: * add_execute_list(). The routine reset_execute_list() resets it for new use. ! 58: */ ! 59: static struct { ! 60: int size; ! 61: int next; ! 62: char **strings; ! 63: } runlist; ! 64: ! 65: /* ! 66: * This routine is passed a string to be added to the list of strings for ! 67: * command line arguments. ! 68: */ ! 69: void ! 70: add_execute_list( ! 71: char *str) ! 72: { ! 73: if(runlist.strings == (char **)0){ ! 74: runlist.next = 0; ! 75: runlist.size = 128; ! 76: runlist.strings = allocate(runlist.size * sizeof(char **)); ! 77: } ! 78: if(runlist.next + 1 >= runlist.size){ ! 79: runlist.strings = reallocate(runlist.strings, ! 80: (runlist.size * 2) * sizeof(char **)); ! 81: runlist.size *= 2; ! 82: } ! 83: runlist.strings[runlist.next++] = str; ! 84: runlist.strings[runlist.next] = (char *)0; ! 85: } ! 86: ! 87: /* ! 88: * This routine reset the list of strings of command line arguments so that ! 89: * an new command line argument list can be built. ! 90: */ ! 91: void ! 92: reset_execute_list(void) ! 93: { ! 94: runlist.next = 0; ! 95: } ! 96: ! 97: /* ! 98: * This routine calls execute() to run the command built up in the runlist ! 99: * strings. ! 100: */ ! 101: int ! 102: execute_list( ! 103: long verbose) ! 104: { ! 105: return(execute(runlist.strings, verbose)); ! 106: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.