00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "pex-common.h"
00027
00028 #ifdef HAVE_STRING_H
00029 #include <string.h>
00030 #endif
00031 #ifdef HAVE_UNISTD_H
00032 #include <unistd.h>
00033 #endif
00034 #ifdef HAVE_SYS_WAIT_H
00035 #include <sys/wait.h>
00036 #endif
00037
00038 #include <process.h>
00039 #include <io.h>
00040 #include <fcntl.h>
00041 #include <signal.h>
00042
00043
00044
00045 #ifndef _P_WAIT
00046 # define _P_WAIT 0
00047 # define _P_NOWAIT 1
00048 # define _P_OVERLAY 2
00049 # define _P_NOWAITO 3
00050 # define _P_DETACH 4
00051
00052 # define WAIT_CHILD 0
00053 # define WAIT_GRANDCHILD 1
00054 #endif
00055
00056
00057
00058
00059 static const char * const *
00060 fix_argv (argvec)
00061 char **argvec;
00062 {
00063 int i;
00064 char * command0 = argvec[0];
00065
00066
00067
00068
00069
00070
00071
00072 for (; *command0 != '\0'; command0++)
00073 if (*command0 == '/')
00074 *command0 = '\\';
00075
00076 for (i = 1; argvec[i] != 0; i++)
00077 {
00078 int len, j;
00079 char *temp, *newtemp;
00080
00081 temp = argvec[i];
00082 len = strlen (temp);
00083 for (j = 0; j < len; j++)
00084 {
00085 if (temp[j] == '"')
00086 {
00087 newtemp = xmalloc (len + 2);
00088 strncpy (newtemp, temp, j);
00089 newtemp [j] = '\\';
00090 strncpy (&newtemp [j+1], &temp [j], len-j);
00091 newtemp [len+1] = 0;
00092 temp = newtemp;
00093 len++;
00094 j++;
00095 }
00096 }
00097
00098 argvec[i] = temp;
00099 }
00100
00101 for (i = 0; argvec[i] != 0; i++)
00102 {
00103 if (strpbrk (argvec[i], " \t"))
00104 {
00105 int len, trailing_backslash;
00106 char *temp;
00107
00108 len = strlen (argvec[i]);
00109 trailing_backslash = 0;
00110
00111
00112
00113
00114
00115
00116
00117
00118 if (len > 1
00119 && argvec[i][len-1] == '\\'
00120 && argvec[i][len-2] != '\\')
00121 {
00122 trailing_backslash = 1;
00123 ++len;
00124 }
00125
00126 len += 2;
00127
00128 temp = xmalloc (len + 1);
00129 temp[0] = '"';
00130 strcpy (temp + 1, argvec[i]);
00131 if (trailing_backslash)
00132 temp[len-2] = '\\';
00133 temp[len-1] = '"';
00134 temp[len] = '\0';
00135
00136 argvec[i] = temp;
00137 }
00138 }
00139
00140 return (const char * const *) argvec;
00141 }
00142
00143
00144 int
00145 pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
00146 const char *program;
00147 char * const *argv;
00148 const char *this_pname ATTRIBUTE_UNUSED;
00149 const char *temp_base ATTRIBUTE_UNUSED;
00150 char **errmsg_fmt, **errmsg_arg;
00151 int flags;
00152 {
00153 int pid;
00154 int pdes[2];
00155 int org_stdin = -1;
00156 int org_stdout = -1;
00157 int input_desc, output_desc;
00158
00159
00160
00161
00162 static int last_pipe_input;
00163
00164
00165 if (flags & PEXECUTE_FIRST)
00166 last_pipe_input = STDIN_FILE_NO;
00167
00168 input_desc = last_pipe_input;
00169
00170
00171
00172 if (! (flags & PEXECUTE_LAST))
00173 {
00174 if (_pipe (pdes, 256, O_BINARY) < 0)
00175 {
00176 *errmsg_fmt = "pipe";
00177 *errmsg_arg = NULL;
00178 return -1;
00179 }
00180 output_desc = pdes[WRITE_PORT];
00181 last_pipe_input = pdes[READ_PORT];
00182 }
00183 else
00184 {
00185
00186 output_desc = STDOUT_FILE_NO;
00187 last_pipe_input = STDIN_FILE_NO;
00188 }
00189
00190 if (input_desc != STDIN_FILE_NO)
00191 {
00192 org_stdin = dup (STDIN_FILE_NO);
00193 dup2 (input_desc, STDIN_FILE_NO);
00194 close (input_desc);
00195 }
00196
00197 if (output_desc != STDOUT_FILE_NO)
00198 {
00199 org_stdout = dup (STDOUT_FILE_NO);
00200 dup2 (output_desc, STDOUT_FILE_NO);
00201 close (output_desc);
00202 }
00203
00204 pid = (flags & PEXECUTE_SEARCH ? _spawnvp : _spawnv)
00205 (_P_NOWAIT, program, fix_argv(argv));
00206
00207 if (input_desc != STDIN_FILE_NO)
00208 {
00209 dup2 (org_stdin, STDIN_FILE_NO);
00210 close (org_stdin);
00211 }
00212
00213 if (output_desc != STDOUT_FILE_NO)
00214 {
00215 dup2 (org_stdout, STDOUT_FILE_NO);
00216 close (org_stdout);
00217 }
00218
00219 if (pid == -1)
00220 {
00221 *errmsg_fmt = install_error_msg;
00222 *errmsg_arg = (char*) program;
00223 return -1;
00224 }
00225
00226 return pid;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 int
00237 pwait (pid, status, flags)
00238 int pid;
00239 int *status;
00240 int flags ATTRIBUTE_UNUSED;
00241 {
00242 int termstat;
00243
00244 pid = _cwait (&termstat, pid, WAIT_CHILD);
00245
00246
00247
00248
00249
00250
00251
00252
00253 if (termstat == 3)
00254 *status = SIGABRT;
00255 else
00256 *status = (((termstat) & 0xff) << 8);
00257
00258 return pid;
00259 }