Integrate cctools-822 changes
[striptease.git] / libstuff / execute.c
blobcbc58bb4f1d6196c5f1516dd76508ec0cfcf800c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 #ifndef RLD
24 #include <libc.h> /* first to get rid of pre-comp warning */
25 #include <mach/mach.h> /* first to get rid of pre-comp warning */
26 #include "stdio.h"
27 #include <signal.h>
28 #include <sys/wait.h>
29 #include <sys/file.h>
30 #include "stuff/errors.h"
31 #include "stuff/allocate.h"
32 #include "stuff/execute.h"
33 #include "mach-o/dyld.h"
36 * execute() does an execvp using the argv passed to it. If the parameter
37 * verbose is non-zero the command is printed to stderr. A non-zero return
38 * value indicates success zero indicates failure.
40 __private_extern__
41 int
42 execute(
43 char **argv,
44 int verbose)
46 char *name, **p;
47 int forkpid, waitpid, termsig;
48 #ifndef __OPENSTEP__
49 int waitstatus;
50 #else
51 union wait waitstatus;
52 #endif
54 name = argv[0];
56 if(verbose){
57 fprintf(stderr, "+ %s ", name);
58 p = &(argv[1]);
59 while(*p != (char *)0)
60 fprintf(stderr, "%s ", *p++);
61 fprintf(stderr, "\n");
64 forkpid = fork();
65 if(forkpid == -1)
66 system_fatal("can't fork a new process to execute: %s", name);
68 if(forkpid == 0){
69 if(execvp(name, argv) == -1)
70 system_fatal("can't find or exec: %s", name);
71 return(1); /* can't get here, removes a warning from the compiler */
73 else{
74 waitpid = wait(&waitstatus);
75 if(waitpid == -1)
76 system_fatal("wait on forked process %d failed", forkpid);
77 #ifndef __OPENSTEP__
78 termsig = WTERMSIG(waitstatus);
79 #else
80 termsig = waitstatus.w_termsig;
81 #endif
82 if(termsig != 0 && termsig != SIGINT)
83 fatal("fatal error in %s", name);
84 return(
85 #ifndef __OPENSTEP__
86 WEXITSTATUS(waitstatus) == 0 &&
87 #else
88 waitstatus.w_retcode == 0 &&
89 #endif
90 termsig == 0);
95 * runlist is used by the routine execute_list() to execute a program and it
96 * contains the command line arguments. Strings are added to it by
97 * add_execute_list(). The routine reset_execute_list() resets it for new use.
99 static struct {
100 int size;
101 int next;
102 char **strings;
103 } runlist;
106 * This routine is passed a string to be added to the list of strings for
107 * command line arguments.
109 __private_extern__
110 void
111 add_execute_list(
112 char *str)
114 if(runlist.strings == (char **)0){
115 runlist.next = 0;
116 runlist.size = 128;
117 runlist.strings = allocate(runlist.size * sizeof(char **));
119 if(runlist.next + 1 >= runlist.size){
120 runlist.strings = reallocate(runlist.strings,
121 (runlist.size * 2) * sizeof(char **));
122 runlist.size *= 2;
124 runlist.strings[runlist.next++] = str;
125 runlist.strings[runlist.next] = (char *)0;
129 * This routine is passed a string to be added to the list of strings for
130 * command line arguments and is then prefixed with the path of the executable.
132 __private_extern__
133 void
134 add_execute_list_with_prefix(
135 char *str)
137 add_execute_list(cmd_with_prefix(str));
141 * This routine is passed a string of a command name and a string is returned
142 * prefixed with the path of the executable and that command name.
144 __private_extern__
145 char *
146 cmd_with_prefix(
147 char *str)
149 int i;
150 char *p;
151 char *prefix, buf[MAXPATHLEN], resolved_name[PATH_MAX];
152 unsigned long bufsize;
155 * Construct the prefix to the program running.
157 bufsize = MAXPATHLEN;
158 p = buf;
159 i = _NSGetExecutablePath(p, &bufsize);
160 if(i == -1){
161 p = allocate(bufsize);
162 _NSGetExecutablePath(p, &bufsize);
164 prefix = realpath(p, resolved_name);
165 p = rindex(prefix, '/');
166 if(p != NULL)
167 p[1] = '\0';
169 return(makestr(prefix, str, NULL));
173 * This routine reset the list of strings of command line arguments so that
174 * an new command line argument list can be built.
176 __private_extern__
177 void
178 reset_execute_list(void)
180 runlist.next = 0;
184 * This routine calls execute() to run the command built up in the runlist
185 * strings.
187 __private_extern__
189 execute_list(
190 int verbose)
192 return(execute(runlist.strings, verbose));
194 #endif /* !defined(RLD) */