00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "pex-common.h"
00023
00024 #include <stdio.h>
00025 #include <errno.h>
00026 #ifdef NEED_DECLARATION_ERRNO
00027 extern int errno;
00028 #endif
00029 #ifdef HAVE_STDLIB_H
00030 #include <stdlib.h>
00031 #endif
00032 #include <string.h>
00033 #include <fcntl.h>
00034 #include <unistd.h>
00035 #include <sys/stat.h>
00036 #include <process.h>
00037
00038
00039 #ifdef ECHILD
00040 #define PWAIT_ERROR ECHILD
00041 #else
00042 #define PWAIT_ERROR EINVAL
00043 #endif
00044
00045 static int pex_djgpp_open_read (struct pex_obj *, const char *, int);
00046 static int pex_djgpp_open_write (struct pex_obj *, const char *, int);
00047 static long pex_djgpp_exec_child (struct pex_obj *, int, const char *,
00048 char * const *, char * const *,
00049 int, int, int, int,
00050 const char **, int *);
00051 static int pex_djgpp_close (struct pex_obj *, int);
00052 static int pex_djgpp_wait (struct pex_obj *, long, int *, struct pex_time *,
00053 int, const char **, int *);
00054
00055
00056
00057 const struct pex_funcs funcs =
00058 {
00059 pex_djgpp_open_read,
00060 pex_djgpp_open_write,
00061 pex_djgpp_exec_child,
00062 pex_djgpp_close,
00063 pex_djgpp_wait,
00064 NULL,
00065 NULL,
00066 NULL,
00067 NULL
00068 };
00069
00070
00071
00072 struct pex_obj *
00073 pex_init (int flags, const char *pname, const char *tempbase)
00074 {
00075
00076 flags &= ~ PEX_USE_PIPES;
00077 return pex_init_common (flags, pname, tempbase, &funcs);
00078 }
00079
00080
00081
00082 static int
00083 pex_djgpp_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED,
00084 const char *name, int binary)
00085 {
00086 return open (name, O_RDONLY | (binary ? O_BINARY : O_TEXT));
00087 }
00088
00089
00090
00091 static int
00092 pex_djgpp_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED,
00093 const char *name, int binary)
00094 {
00095
00096
00097 return open (name,
00098 (O_WRONLY | O_CREAT | O_TRUNC
00099 | (binary ? O_BINARY : O_TEXT)),
00100 S_IRUSR | S_IWUSR);
00101 }
00102
00103
00104
00105 static int
00106 pex_djgpp_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd)
00107 {
00108 return close (fd);
00109 }
00110
00111
00112
00113 static long
00114 pex_djgpp_exec_child (struct pex_obj *obj, int flags, const char *executable,
00115 char * const * argv, char * const * env,
00116 int in, int out, int errdes,
00117 int toclose ATTRIBUTE_UNUSED, const char **errmsg,
00118 int *err)
00119 {
00120 int org_in, org_out, org_errdes;
00121 int status;
00122 int *statuses;
00123
00124 org_in = -1;
00125 org_out = -1;
00126 org_errdes = -1;
00127
00128 if (in != STDIN_FILE_NO)
00129 {
00130 org_in = dup (STDIN_FILE_NO);
00131 if (org_in < 0)
00132 {
00133 *err = errno;
00134 *errmsg = "dup";
00135 return -1;
00136 }
00137 if (dup2 (in, STDIN_FILE_NO) < 0)
00138 {
00139 *err = errno;
00140 *errmsg = "dup2";
00141 return -1;
00142 }
00143 if (close (in) < 0)
00144 {
00145 *err = errno;
00146 *errmsg = "close";
00147 return -1;
00148 }
00149 }
00150
00151 if (out != STDOUT_FILE_NO)
00152 {
00153 org_out = dup (STDOUT_FILE_NO);
00154 if (org_out < 0)
00155 {
00156 *err = errno;
00157 *errmsg = "dup";
00158 return -1;
00159 }
00160 if (dup2 (out, STDOUT_FILE_NO) < 0)
00161 {
00162 *err = errno;
00163 *errmsg = "dup2";
00164 return -1;
00165 }
00166 if (close (out) < 0)
00167 {
00168 *err = errno;
00169 *errmsg = "close";
00170 return -1;
00171 }
00172 }
00173
00174 if (errdes != STDERR_FILE_NO
00175 || (flags & PEX_STDERR_TO_STDOUT) != 0)
00176 {
00177 org_errdes = dup (STDERR_FILE_NO);
00178 if (org_errdes < 0)
00179 {
00180 *err = errno;
00181 *errmsg = "dup";
00182 return -1;
00183 }
00184 if (dup2 ((flags & PEX_STDERR_TO_STDOUT) != 0 ? STDOUT_FILE_NO : errdes,
00185 STDERR_FILE_NO) < 0)
00186 {
00187 *err = errno;
00188 *errmsg = "dup2";
00189 return -1;
00190 }
00191 if (errdes != STDERR_FILE_NO)
00192 {
00193 if (close (errdes) < 0)
00194 {
00195 *err = errno;
00196 *errmsg = "close";
00197 return -1;
00198 }
00199 }
00200 }
00201
00202 if (env)
00203 status = (((flags & PEX_SEARCH) != 0 ? spawnvpe : spawnve)
00204 (P_WAIT, executable, argv, env));
00205 else
00206 status = (((flags & PEX_SEARCH) != 0 ? spawnvp : spawnv)
00207 (P_WAIT, executable, argv));
00208
00209 if (status == -1)
00210 {
00211 *err = errno;
00212 *errmsg = ((flags & PEX_SEARCH) != 0) ? "spawnvp" : "spawnv";
00213 }
00214
00215 if (in != STDIN_FILE_NO)
00216 {
00217 if (dup2 (org_in, STDIN_FILE_NO) < 0)
00218 {
00219 *err = errno;
00220 *errmsg = "dup2";
00221 return -1;
00222 }
00223 if (close (org_in) < 0)
00224 {
00225 *err = errno;
00226 *errmsg = "close";
00227 return -1;
00228 }
00229 }
00230
00231 if (out != STDOUT_FILE_NO)
00232 {
00233 if (dup2 (org_out, STDOUT_FILE_NO) < 0)
00234 {
00235 *err = errno;
00236 *errmsg = "dup2";
00237 return -1;
00238 }
00239 if (close (org_out) < 0)
00240 {
00241 *err = errno;
00242 *errmsg = "close";
00243 return -1;
00244 }
00245 }
00246
00247 if (errdes != STDERR_FILE_NO
00248 || (flags & PEX_STDERR_TO_STDOUT) != 0)
00249 {
00250 if (dup2 (org_errdes, STDERR_FILE_NO) < 0)
00251 {
00252 *err = errno;
00253 *errmsg = "dup2";
00254 return -1;
00255 }
00256 if (close (org_errdes) < 0)
00257 {
00258 *err = errno;
00259 *errmsg = "close";
00260 return -1;
00261 }
00262 }
00263
00264
00265
00266
00267 statuses = (int *) obj->sysdep;
00268 statuses = XRESIZEVEC (int, statuses, obj->count + 1);
00269 statuses[obj->count] = status;
00270 obj->sysdep = (void *) statuses;
00271
00272 return obj->count;
00273 }
00274
00275
00276
00277
00278
00279 static int
00280 pex_djgpp_wait (struct pex_obj *obj, long pid, int *status,
00281 struct pex_time *time, int done ATTRIBUTE_UNUSED,
00282 const char **errmsg ATTRIBUTE_UNUSED,
00283 int *err ATTRIBUTE_UNUSED)
00284 {
00285 int *statuses;
00286
00287 if (time != NULL)
00288 memset (time, 0, sizeof *time);
00289
00290 statuses = (int *) obj->sysdep;
00291 *status = statuses[pid];
00292
00293 return 0;
00294 }