|
|
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.