Mercurial > hg > CbC > CbC_gcc
annotate libiberty/pex-unix.c @ 119:9d1ff3ae1824
fix conv1 example
author | kono |
---|---|
date | Thu, 08 Mar 2018 12:20:02 +0900 |
parents | 04ced10e8804 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 /* Utilities to execute a program in a subprocess (possibly linked by pipes |
2 with other subprocesses), and wait for it. Generic Unix version | |
3 (also used for UWIN and VMS). | |
111 | 4 Copyright (C) 1996-2017 Free Software Foundation, Inc. |
0 | 5 |
6 This file is part of the libiberty library. | |
7 Libiberty is free software; you can redistribute it and/or | |
8 modify it under the terms of the GNU Library General Public | |
9 License as published by the Free Software Foundation; either | |
10 version 2 of the License, or (at your option) any later version. | |
11 | |
12 Libiberty is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 Library General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU Library General Public | |
18 License along with libiberty; see the file COPYING.LIB. If not, | |
19 write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, | |
20 Boston, MA 02110-1301, USA. */ | |
21 | |
22 #include "config.h" | |
23 #include "libiberty.h" | |
24 #include "pex-common.h" | |
111 | 25 #include "environ.h" |
0 | 26 |
27 #include <stdio.h> | |
28 #include <signal.h> | |
29 #include <errno.h> | |
30 #ifdef NEED_DECLARATION_ERRNO | |
31 extern int errno; | |
32 #endif | |
33 #ifdef HAVE_STDLIB_H | |
34 #include <stdlib.h> | |
35 #endif | |
36 #ifdef HAVE_STRING_H | |
37 #include <string.h> | |
38 #endif | |
39 #ifdef HAVE_UNISTD_H | |
40 #include <unistd.h> | |
41 #endif | |
42 | |
43 #include <sys/types.h> | |
44 | |
45 #ifdef HAVE_FCNTL_H | |
46 #include <fcntl.h> | |
47 #endif | |
48 #ifdef HAVE_SYS_WAIT_H | |
49 #include <sys/wait.h> | |
50 #endif | |
51 #ifdef HAVE_GETRUSAGE | |
52 #include <sys/time.h> | |
53 #include <sys/resource.h> | |
54 #endif | |
55 #ifdef HAVE_SYS_STAT_H | |
56 #include <sys/stat.h> | |
57 #endif | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
58 #ifdef HAVE_PROCESS_H |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
59 #include <process.h> |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
60 #endif |
0 | 61 |
62 #ifdef vfork /* Autoconf may define this to fork for us. */ | |
63 # define VFORK_STRING "fork" | |
64 #else | |
65 # define VFORK_STRING "vfork" | |
66 #endif | |
67 #ifdef HAVE_VFORK_H | |
68 #include <vfork.h> | |
69 #endif | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
70 #if defined(VMS) && defined (__LONG_POINTERS) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
71 #ifndef __CHAR_PTR32 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
72 typedef char * __char_ptr32 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
73 __attribute__ ((mode (SI))); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
74 #endif |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
75 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
76 typedef __char_ptr32 *__char_ptr_char_ptr32 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
77 __attribute__ ((mode (SI))); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
78 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
79 /* Return a 32 bit pointer to an array of 32 bit pointers |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
80 given a 64 bit pointer to an array of 64 bit pointers. */ |
0 | 81 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
82 static __char_ptr_char_ptr32 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
83 to_ptr32 (char **ptr64) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
84 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
85 int argc; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
86 __char_ptr_char_ptr32 short_argv; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
87 |
111 | 88 /* Count number of arguments. */ |
89 for (argc = 0; ptr64[argc] != NULL; argc++) | |
90 ; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
91 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
92 /* Reallocate argv with 32 bit pointers. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
93 short_argv = (__char_ptr_char_ptr32) decc$malloc |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
94 (sizeof (__char_ptr32) * (argc + 1)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
95 |
111 | 96 for (argc = 0; ptr64[argc] != NULL; argc++) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
97 short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
98 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
99 short_argv[argc] = (__char_ptr32) 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
100 return short_argv; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
101 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
102 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
103 #else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
104 #define to_ptr32(argv) argv |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
105 #endif |
0 | 106 |
107 /* File mode to use for private and world-readable files. */ | |
108 | |
109 #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH) | |
110 #define PUBLIC_MODE \ | |
111 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) | |
112 #else | |
113 #define PUBLIC_MODE 0666 | |
114 #endif | |
115 | |
116 /* Get the exit status of a particular process, and optionally get the | |
117 time that it took. This is simple if we have wait4, slightly | |
118 harder if we have waitpid, and is a pain if we only have wait. */ | |
119 | |
120 static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *); | |
121 | |
122 #ifdef HAVE_WAIT4 | |
123 | |
124 static pid_t | |
125 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, | |
126 struct pex_time *time) | |
127 { | |
128 pid_t ret; | |
129 struct rusage r; | |
130 | |
131 #ifdef HAVE_WAITPID | |
132 if (time == NULL) | |
133 return waitpid (pid, status, 0); | |
134 #endif | |
135 | |
136 ret = wait4 (pid, status, 0, &r); | |
137 | |
138 if (time != NULL) | |
139 { | |
140 time->user_seconds = r.ru_utime.tv_sec; | |
141 time->user_microseconds= r.ru_utime.tv_usec; | |
142 time->system_seconds = r.ru_stime.tv_sec; | |
143 time->system_microseconds= r.ru_stime.tv_usec; | |
144 } | |
145 | |
146 return ret; | |
147 } | |
148 | |
149 #else /* ! defined (HAVE_WAIT4) */ | |
150 | |
151 #ifdef HAVE_WAITPID | |
152 | |
153 #ifndef HAVE_GETRUSAGE | |
154 | |
155 static pid_t | |
156 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, | |
157 struct pex_time *time) | |
158 { | |
159 if (time != NULL) | |
160 memset (time, 0, sizeof (struct pex_time)); | |
161 return waitpid (pid, status, 0); | |
162 } | |
163 | |
164 #else /* defined (HAVE_GETRUSAGE) */ | |
165 | |
166 static pid_t | |
167 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status, | |
168 struct pex_time *time) | |
169 { | |
170 struct rusage r1, r2; | |
171 pid_t ret; | |
172 | |
173 if (time == NULL) | |
174 return waitpid (pid, status, 0); | |
175 | |
176 getrusage (RUSAGE_CHILDREN, &r1); | |
177 | |
178 ret = waitpid (pid, status, 0); | |
179 if (ret < 0) | |
180 return ret; | |
181 | |
182 getrusage (RUSAGE_CHILDREN, &r2); | |
183 | |
184 time->user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; | |
185 time->user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; | |
186 if (r2.ru_utime.tv_usec < r1.ru_utime.tv_usec) | |
187 { | |
188 --time->user_seconds; | |
189 time->user_microseconds += 1000000; | |
190 } | |
191 | |
192 time->system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; | |
193 time->system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; | |
194 if (r2.ru_stime.tv_usec < r1.ru_stime.tv_usec) | |
195 { | |
196 --time->system_seconds; | |
197 time->system_microseconds += 1000000; | |
198 } | |
199 | |
200 return ret; | |
201 } | |
202 | |
203 #endif /* defined (HAVE_GETRUSAGE) */ | |
204 | |
205 #else /* ! defined (HAVE_WAITPID) */ | |
206 | |
207 struct status_list | |
208 { | |
209 struct status_list *next; | |
210 pid_t pid; | |
211 int status; | |
212 struct pex_time time; | |
213 }; | |
214 | |
215 static pid_t | |
216 pex_wait (struct pex_obj *obj, pid_t pid, int *status, struct pex_time *time) | |
217 { | |
218 struct status_list **pp; | |
219 | |
220 for (pp = (struct status_list **) &obj->sysdep; | |
221 *pp != NULL; | |
222 pp = &(*pp)->next) | |
223 { | |
224 if ((*pp)->pid == pid) | |
225 { | |
226 struct status_list *p; | |
227 | |
228 p = *pp; | |
229 *status = p->status; | |
230 if (time != NULL) | |
231 *time = p->time; | |
232 *pp = p->next; | |
233 free (p); | |
234 return pid; | |
235 } | |
236 } | |
237 | |
238 while (1) | |
239 { | |
240 pid_t cpid; | |
241 struct status_list *psl; | |
242 struct pex_time pt; | |
243 #ifdef HAVE_GETRUSAGE | |
244 struct rusage r1, r2; | |
245 #endif | |
246 | |
247 if (time != NULL) | |
248 { | |
249 #ifdef HAVE_GETRUSAGE | |
250 getrusage (RUSAGE_CHILDREN, &r1); | |
251 #else | |
252 memset (&pt, 0, sizeof (struct pex_time)); | |
253 #endif | |
254 } | |
255 | |
256 cpid = wait (status); | |
257 | |
258 #ifdef HAVE_GETRUSAGE | |
259 if (time != NULL && cpid >= 0) | |
260 { | |
261 getrusage (RUSAGE_CHILDREN, &r2); | |
262 | |
263 pt.user_seconds = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; | |
264 pt.user_microseconds = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; | |
265 if (pt.user_microseconds < 0) | |
266 { | |
267 --pt.user_seconds; | |
268 pt.user_microseconds += 1000000; | |
269 } | |
270 | |
271 pt.system_seconds = r2.ru_stime.tv_sec - r1.ru_stime.tv_sec; | |
272 pt.system_microseconds = r2.ru_stime.tv_usec - r1.ru_stime.tv_usec; | |
273 if (pt.system_microseconds < 0) | |
274 { | |
275 --pt.system_seconds; | |
276 pt.system_microseconds += 1000000; | |
277 } | |
278 } | |
279 #endif | |
280 | |
281 if (cpid < 0 || cpid == pid) | |
282 { | |
283 if (time != NULL) | |
284 *time = pt; | |
285 return cpid; | |
286 } | |
287 | |
288 psl = XNEW (struct status_list); | |
289 psl->pid = cpid; | |
290 psl->status = *status; | |
291 if (time != NULL) | |
292 psl->time = pt; | |
293 psl->next = (struct status_list *) obj->sysdep; | |
294 obj->sysdep = (void *) psl; | |
295 } | |
296 } | |
297 | |
298 #endif /* ! defined (HAVE_WAITPID) */ | |
299 #endif /* ! defined (HAVE_WAIT4) */ | |
300 | |
301 static void pex_child_error (struct pex_obj *, const char *, const char *, int) | |
302 ATTRIBUTE_NORETURN; | |
303 static int pex_unix_open_read (struct pex_obj *, const char *, int); | |
111 | 304 static int pex_unix_open_write (struct pex_obj *, const char *, int, int); |
0 | 305 static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *, |
306 char * const *, char * const *, | |
307 int, int, int, int, | |
308 const char **, int *); | |
309 static int pex_unix_close (struct pex_obj *, int); | |
310 static int pex_unix_wait (struct pex_obj *, pid_t, int *, struct pex_time *, | |
311 int, const char **, int *); | |
312 static int pex_unix_pipe (struct pex_obj *, int *, int); | |
313 static FILE *pex_unix_fdopenr (struct pex_obj *, int, int); | |
314 static FILE *pex_unix_fdopenw (struct pex_obj *, int, int); | |
315 static void pex_unix_cleanup (struct pex_obj *); | |
316 | |
317 /* The list of functions we pass to the common routines. */ | |
318 | |
319 const struct pex_funcs funcs = | |
320 { | |
321 pex_unix_open_read, | |
322 pex_unix_open_write, | |
323 pex_unix_exec_child, | |
324 pex_unix_close, | |
325 pex_unix_wait, | |
326 pex_unix_pipe, | |
327 pex_unix_fdopenr, | |
328 pex_unix_fdopenw, | |
329 pex_unix_cleanup | |
330 }; | |
331 | |
332 /* Return a newly initialized pex_obj structure. */ | |
333 | |
334 struct pex_obj * | |
335 pex_init (int flags, const char *pname, const char *tempbase) | |
336 { | |
337 return pex_init_common (flags, pname, tempbase, &funcs); | |
338 } | |
339 | |
340 /* Open a file for reading. */ | |
341 | |
342 static int | |
343 pex_unix_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, | |
344 int binary ATTRIBUTE_UNUSED) | |
345 { | |
346 return open (name, O_RDONLY); | |
347 } | |
348 | |
349 /* Open a file for writing. */ | |
350 | |
351 static int | |
352 pex_unix_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, const char *name, | |
111 | 353 int binary ATTRIBUTE_UNUSED, int append) |
0 | 354 { |
355 /* Note that we can't use O_EXCL here because gcc may have already | |
356 created the temporary file via make_temp_file. */ | |
111 | 357 return open (name, O_WRONLY | O_CREAT |
358 | (append ? O_APPEND : O_TRUNC), PUBLIC_MODE); | |
0 | 359 } |
360 | |
361 /* Close a file. */ | |
362 | |
363 static int | |
364 pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) | |
365 { | |
366 return close (fd); | |
367 } | |
368 | |
369 /* Report an error from a child process. We don't use stdio routines, | |
370 because we might be here due to a vfork call. */ | |
371 | |
372 static void | |
373 pex_child_error (struct pex_obj *obj, const char *executable, | |
374 const char *errmsg, int err) | |
375 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
376 int retval = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
377 #define writeerr(s) retval |= (write (STDERR_FILE_NO, s, strlen (s)) < 0) |
0 | 378 writeerr (obj->pname); |
379 writeerr (": error trying to exec '"); | |
380 writeerr (executable); | |
381 writeerr ("': "); | |
382 writeerr (errmsg); | |
383 writeerr (": "); | |
384 writeerr (xstrerror (err)); | |
385 writeerr ("\n"); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
386 #undef writeerr |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
387 /* Exit with -2 if the error output failed, too. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
388 _exit (retval == 0 ? -1 : -2); |
0 | 389 } |
390 | |
391 /* Execute a child. */ | |
392 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
393 #if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
394 /* Implementation of pex->exec_child using the Cygwin spawn operation. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
395 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
396 /* Subroutine of pex_unix_exec_child. Move OLD_FD to a new file descriptor |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
397 to be stored in *PNEW_FD, save the flags in *PFLAGS, and arrange for the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
398 saved copy to be close-on-exec. Move CHILD_FD into OLD_FD. If CHILD_FD |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
399 is -1, OLD_FD is to be closed. Return -1 on error. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
400 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
401 static int |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
402 save_and_install_fd(int *pnew_fd, int *pflags, int old_fd, int child_fd) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
403 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
404 int new_fd, flags; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
405 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
406 flags = fcntl (old_fd, F_GETFD); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
407 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
408 /* If we could not retrieve the flags, then OLD_FD was not open. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
409 if (flags < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
410 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
411 new_fd = -1, flags = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
412 if (child_fd >= 0 && dup2 (child_fd, old_fd) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
413 return -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
414 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
415 /* If we wish to close OLD_FD, just mark it CLOEXEC. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
416 else if (child_fd == -1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
417 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
418 new_fd = old_fd; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
419 if ((flags & FD_CLOEXEC) == 0 && fcntl (old_fd, F_SETFD, FD_CLOEXEC) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
420 return -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
421 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
422 /* Otherwise we need to save a copy of OLD_FD before installing CHILD_FD. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
423 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
424 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
425 #ifdef F_DUPFD_CLOEXEC |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
426 new_fd = fcntl (old_fd, F_DUPFD_CLOEXEC, 3); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
427 if (new_fd < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
428 return -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
429 #else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
430 /* Prefer F_DUPFD over dup in order to avoid getting a new fd |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
431 in the range 0-2, right where a new stderr fd might get put. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
432 new_fd = fcntl (old_fd, F_DUPFD, 3); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
433 if (new_fd < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
434 return -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
435 if (fcntl (new_fd, F_SETFD, FD_CLOEXEC) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
436 return -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
437 #endif |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
438 if (dup2 (child_fd, old_fd) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
439 return -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
440 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
441 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
442 *pflags = flags; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
443 if (pnew_fd) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
444 *pnew_fd = new_fd; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
445 else if (new_fd != old_fd) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
446 abort (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
447 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
448 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
449 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
450 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
451 /* Subroutine of pex_unix_exec_child. Move SAVE_FD back to OLD_FD |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
452 restoring FLAGS. If SAVE_FD < 0, OLD_FD is to be closed. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
453 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
454 static int |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
455 restore_fd(int old_fd, int save_fd, int flags) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
456 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
457 /* For SAVE_FD < 0, all we have to do is restore the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
458 "closed-ness" of the original. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
459 if (save_fd < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
460 return close (old_fd); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
461 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
462 /* For SAVE_FD == OLD_FD, all we have to do is restore the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
463 original setting of the CLOEXEC flag. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
464 if (save_fd == old_fd) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
465 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
466 if (flags & FD_CLOEXEC) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
467 return 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
468 return fcntl (old_fd, F_SETFD, flags); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
469 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
470 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
471 /* Otherwise we have to move the descriptor back, restore the flags, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
472 and close the saved copy. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
473 #ifdef HAVE_DUP3 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
474 if (flags == FD_CLOEXEC) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
475 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
476 if (dup3 (save_fd, old_fd, O_CLOEXEC) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
477 return -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
478 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
479 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
480 #endif |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
481 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
482 if (dup2 (save_fd, old_fd) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
483 return -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
484 if (flags != 0 && fcntl (old_fd, F_SETFD, flags) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
485 return -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
486 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
487 return close (save_fd); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
488 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
489 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
490 static pid_t |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
491 pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
492 int flags, const char *executable, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
493 char * const * argv, char * const * env, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
494 int in, int out, int errdes, int toclose, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
495 const char **errmsg, int *err) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
496 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
497 int fl_in = 0, fl_out = 0, fl_err = 0, fl_tc = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
498 int save_in = -1, save_out = -1, save_err = -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
499 int max, retries; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
500 pid_t pid; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
501 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
502 if (flags & PEX_STDERR_TO_STDOUT) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
503 errdes = out; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
504 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
505 /* We need the three standard file descriptors to be set up as for |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
506 the child before we perform the spawn. The file descriptors for |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
507 the parent need to be moved and marked for close-on-exec. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
508 if (in != STDIN_FILE_NO |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
509 && save_and_install_fd (&save_in, &fl_in, STDIN_FILE_NO, in) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
510 goto error_dup2; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
511 if (out != STDOUT_FILE_NO |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
512 && save_and_install_fd (&save_out, &fl_out, STDOUT_FILE_NO, out) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
513 goto error_dup2; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
514 if (errdes != STDERR_FILE_NO |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
515 && save_and_install_fd (&save_err, &fl_err, STDERR_FILE_NO, errdes) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
516 goto error_dup2; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
517 if (toclose >= 0 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
518 && save_and_install_fd (NULL, &fl_tc, toclose, -1) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
519 goto error_dup2; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
520 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
521 /* Now that we've moved the file descriptors for the child into place, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
522 close the originals. Be careful not to close any of the standard |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
523 file descriptors that we just set up. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
524 max = -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
525 if (errdes >= 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
526 max = STDERR_FILE_NO; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
527 else if (out >= 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
528 max = STDOUT_FILE_NO; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
529 else if (in >= 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
530 max = STDIN_FILE_NO; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
531 if (in > max) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
532 close (in); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
533 if (out > max) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
534 close (out); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
535 if (errdes > max && errdes != out) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
536 close (errdes); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
537 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
538 /* If we were not given an environment, use the global environment. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
539 if (env == NULL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
540 env = environ; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
541 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
542 /* Launch the program. If we get EAGAIN (normally out of pid's), try |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
543 again a few times with increasing backoff times. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
544 retries = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
545 while (1) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
546 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
547 typedef const char * const *cc_cp; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
548 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
549 if (flags & PEX_SEARCH) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
550 pid = spawnvpe (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
551 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
552 pid = spawnve (_P_NOWAITO, executable, (cc_cp)argv, (cc_cp)env); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
553 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
554 if (pid > 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
555 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
556 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
557 *err = errno; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
558 *errmsg = "spawn"; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
559 if (errno != EAGAIN || ++retries == 4) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
560 return (pid_t) -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
561 sleep (1 << retries); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
562 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
563 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
564 /* Success. Restore the parent's file descriptors that we saved above. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
565 if (toclose >= 0 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
566 && restore_fd (toclose, toclose, fl_tc) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
567 goto error_dup2; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
568 if (in != STDIN_FILE_NO |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
569 && restore_fd (STDIN_FILE_NO, save_in, fl_in) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
570 goto error_dup2; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
571 if (out != STDOUT_FILE_NO |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
572 && restore_fd (STDOUT_FILE_NO, save_out, fl_out) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
573 goto error_dup2; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
574 if (errdes != STDERR_FILE_NO |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
575 && restore_fd (STDERR_FILE_NO, save_err, fl_err) < 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
576 goto error_dup2; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
577 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
578 return pid; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
579 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
580 error_dup2: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
581 *err = errno; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
582 *errmsg = "dup2"; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
583 return (pid_t) -1; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
584 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
585 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
586 #else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
587 /* Implementation of pex->exec_child using standard vfork + exec. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
588 |
0 | 589 static pid_t |
590 pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, | |
591 char * const * argv, char * const * env, | |
592 int in, int out, int errdes, | |
593 int toclose, const char **errmsg, int *err) | |
594 { | |
595 pid_t pid; | |
596 | |
597 /* We declare these to be volatile to avoid warnings from gcc about | |
598 them being clobbered by vfork. */ | |
599 volatile int sleep_interval; | |
600 volatile int retries; | |
601 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
602 /* We vfork and then set environ in the child before calling execvp. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
603 This clobbers the parent's environ so we need to restore it. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
604 It would be nice to use one of the exec* functions that takes an |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
605 environment as a parameter, but that may have portability issues. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
606 char **save_environ = environ; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
607 |
0 | 608 sleep_interval = 1; |
609 pid = -1; | |
610 for (retries = 0; retries < 4; ++retries) | |
611 { | |
612 pid = vfork (); | |
613 if (pid >= 0) | |
614 break; | |
615 sleep (sleep_interval); | |
616 sleep_interval *= 2; | |
617 } | |
618 | |
619 switch (pid) | |
620 { | |
621 case -1: | |
622 *err = errno; | |
623 *errmsg = VFORK_STRING; | |
624 return (pid_t) -1; | |
625 | |
626 case 0: | |
627 /* Child process. */ | |
628 if (in != STDIN_FILE_NO) | |
629 { | |
630 if (dup2 (in, STDIN_FILE_NO) < 0) | |
631 pex_child_error (obj, executable, "dup2", errno); | |
632 if (close (in) < 0) | |
633 pex_child_error (obj, executable, "close", errno); | |
634 } | |
635 if (out != STDOUT_FILE_NO) | |
636 { | |
637 if (dup2 (out, STDOUT_FILE_NO) < 0) | |
638 pex_child_error (obj, executable, "dup2", errno); | |
639 if (close (out) < 0) | |
640 pex_child_error (obj, executable, "close", errno); | |
641 } | |
642 if (errdes != STDERR_FILE_NO) | |
643 { | |
644 if (dup2 (errdes, STDERR_FILE_NO) < 0) | |
645 pex_child_error (obj, executable, "dup2", errno); | |
646 if (close (errdes) < 0) | |
647 pex_child_error (obj, executable, "close", errno); | |
648 } | |
649 if (toclose >= 0) | |
650 { | |
651 if (close (toclose) < 0) | |
652 pex_child_error (obj, executable, "close", errno); | |
653 } | |
654 if ((flags & PEX_STDERR_TO_STDOUT) != 0) | |
655 { | |
656 if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0) | |
657 pex_child_error (obj, executable, "dup2", errno); | |
658 } | |
659 | |
660 if (env) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
661 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
662 /* NOTE: In a standard vfork implementation this clobbers the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
663 parent's copy of environ "too" (in reality there's only one copy). |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
664 This is ok as we restore it below. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
665 environ = (char**) env; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
666 } |
0 | 667 |
668 if ((flags & PEX_SEARCH) != 0) | |
669 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
670 execvp (executable, to_ptr32 (argv)); |
0 | 671 pex_child_error (obj, executable, "execvp", errno); |
672 } | |
673 else | |
674 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
675 execv (executable, to_ptr32 (argv)); |
0 | 676 pex_child_error (obj, executable, "execv", errno); |
677 } | |
678 | |
679 /* NOTREACHED */ | |
680 return (pid_t) -1; | |
681 | |
682 default: | |
683 /* Parent process. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
684 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
685 /* Restore environ. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
686 Note that the parent either doesn't run until the child execs/exits |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
687 (standard vfork behaviour), or if it does run then vfork is behaving |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
688 more like fork. In either case we needn't worry about clobbering |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
689 the child's copy of environ. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
690 environ = save_environ; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
691 |
0 | 692 if (in != STDIN_FILE_NO) |
693 { | |
694 if (close (in) < 0) | |
695 { | |
696 *err = errno; | |
697 *errmsg = "close"; | |
698 return (pid_t) -1; | |
699 } | |
700 } | |
701 if (out != STDOUT_FILE_NO) | |
702 { | |
703 if (close (out) < 0) | |
704 { | |
705 *err = errno; | |
706 *errmsg = "close"; | |
707 return (pid_t) -1; | |
708 } | |
709 } | |
710 if (errdes != STDERR_FILE_NO) | |
711 { | |
712 if (close (errdes) < 0) | |
713 { | |
714 *err = errno; | |
715 *errmsg = "close"; | |
716 return (pid_t) -1; | |
717 } | |
718 } | |
719 | |
720 return pid; | |
721 } | |
722 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
723 #endif /* SPAWN */ |
0 | 724 |
725 /* Wait for a child process to complete. */ | |
726 | |
727 static int | |
728 pex_unix_wait (struct pex_obj *obj, pid_t pid, int *status, | |
729 struct pex_time *time, int done, const char **errmsg, | |
730 int *err) | |
731 { | |
732 /* If we are cleaning up when the caller didn't retrieve process | |
733 status for some reason, encourage the process to go away. */ | |
734 if (done) | |
735 kill (pid, SIGTERM); | |
736 | |
737 if (pex_wait (obj, pid, status, time) < 0) | |
738 { | |
739 *err = errno; | |
740 *errmsg = "wait"; | |
741 return -1; | |
742 } | |
743 | |
744 return 0; | |
745 } | |
746 | |
747 /* Create a pipe. */ | |
748 | |
749 static int | |
750 pex_unix_pipe (struct pex_obj *obj ATTRIBUTE_UNUSED, int *p, | |
751 int binary ATTRIBUTE_UNUSED) | |
752 { | |
753 return pipe (p); | |
754 } | |
755 | |
756 /* Get a FILE pointer to read from a file descriptor. */ | |
757 | |
758 static FILE * | |
759 pex_unix_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, | |
760 int binary ATTRIBUTE_UNUSED) | |
761 { | |
762 return fdopen (fd, "r"); | |
763 } | |
764 | |
765 static FILE * | |
766 pex_unix_fdopenw (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd, | |
767 int binary ATTRIBUTE_UNUSED) | |
768 { | |
769 if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0) | |
770 return NULL; | |
771 return fdopen (fd, "w"); | |
772 } | |
773 | |
774 static void | |
775 pex_unix_cleanup (struct pex_obj *obj ATTRIBUTE_UNUSED) | |
776 { | |
777 #if !defined (HAVE_WAIT4) && !defined (HAVE_WAITPID) | |
778 while (obj->sysdep != NULL) | |
779 { | |
780 struct status_list *this; | |
781 struct status_list *next; | |
782 | |
783 this = (struct status_list *) obj->sysdep; | |
784 next = this->next; | |
785 free (this); | |
786 obj->sysdep = (void *) next; | |
787 } | |
788 #endif | |
789 } |