home *** CD-ROM | disk | FTP | other *** search
- #include <bsd/libc.h> /* first to get rid of pre-comp warning */
- #include <mach/mach.h> /* first to get rid of pre-comp warning */
- #include "stdio.h"
- #include <signal.h>
- #include <sys/wait.h>
- #include "stuff/errors.h"
- #include "stuff/allocate.h"
- #include "stuff/execute.h"
-
- /*
- * execute() does an execvp using the argv passed to it. If the parameter
- * verbose is non-zero the command is printed to stderr. A non-zero return
- * value indicates success zero indicates failure.
- */
- __private_extern__
- int
- execute(
- char **argv,
- long verbose)
- {
- char *name, **p;
- int forkpid, waitpid, termsig;
- #ifdef __TEFLON__
- int waitstatus;
- #else
- union wait waitstatus;
- #endif
-
- name = argv[0];
-
- if(verbose){
- fprintf(stderr, "+ %s ", name);
- p = &(argv[1]);
- while(*p != (char *)0)
- fprintf(stderr, "%s ", *p++);
- fprintf(stderr, "\n");
- }
-
- forkpid = fork();
- if(forkpid == -1)
- system_fatal("can't fork a new process to execute: %s", name);
-
- if(forkpid == 0){
- if(execvp(name, argv) == -1)
- system_fatal("can't find or exec: %s", name);
- return(1); /* can't get here, removes a warning from the compiler */
- }
- else{
- waitpid = wait(&waitstatus);
- if(waitpid == -1)
- system_fatal("wait on forked process %d failed", forkpid);
- #ifdef __TEFLON__
- termsig = WTERMSIG(waitstatus);
- #else
- termsig = waitstatus.w_termsig;
- #endif
- if(termsig != 0 && termsig != SIGINT)
- fatal("fatal error in %s", name);
- return(
- #ifdef __TEFLON__
- WEXITSTATUS(waitstatus) &&
- #else
- waitstatus.w_retcode == 0 &&
- #endif
- termsig == 0);
- }
- }
-
- /*
- * runlist is used by the routine execute_list() to execute a program and it
- * contains the command line arguments. Strings are added to it by
- * add_execute_list(). The routine reset_execute_list() resets it for new use.
- */
- static struct {
- int size;
- int next;
- char **strings;
- } runlist;
-
- /*
- * This routine is passed a string to be added to the list of strings for
- * command line arguments.
- */
- __private_extern__
- void
- add_execute_list(
- char *str)
- {
- if(runlist.strings == (char **)0){
- runlist.next = 0;
- runlist.size = 128;
- runlist.strings = allocate(runlist.size * sizeof(char **));
- }
- if(runlist.next + 1 >= runlist.size){
- runlist.strings = reallocate(runlist.strings,
- (runlist.size * 2) * sizeof(char **));
- runlist.size *= 2;
- }
- runlist.strings[runlist.next++] = str;
- runlist.strings[runlist.next] = (char *)0;
- }
-
- /*
- * This routine reset the list of strings of command line arguments so that
- * an new command line argument list can be built.
- */
- __private_extern__
- void
- reset_execute_list(void)
- {
- runlist.next = 0;
- }
-
- /*
- * This routine calls execute() to run the command built up in the runlist
- * strings.
- */
- __private_extern__
- int
- execute_list(
- long verbose)
- {
- return(execute(runlist.strings, verbose));
- }
-