Mercurial > hg > CbC > CbC_gcc
annotate libiberty/pex-djgpp.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | 77e2b8dfacca |
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. DJGPP specialization. | |
111 | 3 Copyright (C) 1996-2017 Free Software Foundation, Inc. |
0 | 4 |
5 This file is part of the libiberty library. | |
6 Libiberty is free software; you can redistribute it and/or | |
7 modify it under the terms of the GNU Library General Public | |
8 License as published by the Free Software Foundation; either | |
9 version 2 of the License, or (at your option) any later version. | |
10 | |
11 Libiberty is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 Library General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU Library General Public | |
17 License along with libiberty; see the file COPYING.LIB. If not, | |
18 write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, | |
19 Boston, MA 02110-1301, USA. */ | |
20 | |
21 #include "pex-common.h" | |
22 | |
23 #include <stdio.h> | |
24 #include <errno.h> | |
25 #ifdef NEED_DECLARATION_ERRNO | |
26 extern int errno; | |
27 #endif | |
28 #ifdef HAVE_STDLIB_H | |
29 #include <stdlib.h> | |
30 #endif | |
31 #include <string.h> | |
32 #include <fcntl.h> | |
33 #include <unistd.h> | |
34 #include <sys/stat.h> | |
35 #include <process.h> | |
36 | |
37 /* Use ECHILD if available, otherwise use EINVAL. */ | |
38 #ifdef ECHILD | |
39 #define PWAIT_ERROR ECHILD | |
40 #else | |
41 #define PWAIT_ERROR EINVAL | |
42 #endif | |
43 | |
44 static int pex_djgpp_open_read (struct pex_obj *, const char *, int); | |
111 | 45 static int pex_djgpp_open_write (struct pex_obj *, const char *, int, int); |
0 | 46 static pid_t pex_djgpp_exec_child (struct pex_obj *, int, const char *, |
47 char * const *, char * const *, | |
48 int, int, int, int, | |
49 const char **, int *); | |
50 static int pex_djgpp_close (struct pex_obj *, int); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
51 static pid_t pex_djgpp_wait (struct pex_obj *, pid_t, int *, struct pex_time *, |
0 | 52 int, const char **, int *); |
53 | |
54 /* The list of functions we pass to the common routines. */ | |
55 | |
56 const struct pex_funcs funcs = | |
57 { | |
58 pex_djgpp_open_read, | |
59 pex_djgpp_open_write, | |
60 pex_djgpp_exec_child, | |
61 pex_djgpp_close, | |
62 pex_djgpp_wait, | |
63 NULL, /* pipe */ | |
64 NULL, /* fdopenr */ | |
65 NULL, /* fdopenw */ | |
66 NULL /* cleanup */ | |
67 }; | |
68 | |
69 /* Return a newly initialized pex_obj structure. */ | |
70 | |
71 struct pex_obj * | |
72 pex_init (int flags, const char *pname, const char *tempbase) | |
73 { | |
74 /* DJGPP does not support pipes. */ | |
75 flags &= ~ PEX_USE_PIPES; | |
76 return pex_init_common (flags, pname, tempbase, &funcs); | |
77 } | |
78 | |
79 /* Open a file for reading. */ | |
80 | |
81 static int | |
82 pex_djgpp_open_read (struct pex_obj *obj ATTRIBUTE_UNUSED, | |
83 const char *name, int binary) | |
84 { | |
85 return open (name, O_RDONLY | (binary ? O_BINARY : O_TEXT)); | |
86 } | |
87 | |
88 /* Open a file for writing. */ | |
89 | |
90 static int | |
91 pex_djgpp_open_write (struct pex_obj *obj ATTRIBUTE_UNUSED, | |
111 | 92 const char *name, int binary, int append) |
0 | 93 { |
94 /* Note that we can't use O_EXCL here because gcc may have already | |
95 created the temporary file via make_temp_file. */ | |
111 | 96 if (append) |
97 return -1; | |
0 | 98 return open (name, |
99 (O_WRONLY | O_CREAT | O_TRUNC | |
100 | (binary ? O_BINARY : O_TEXT)), | |
101 S_IRUSR | S_IWUSR); | |
102 } | |
103 | |
104 /* Close a file. */ | |
105 | |
106 static int | |
107 pex_djgpp_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) | |
108 { | |
109 return close (fd); | |
110 } | |
111 | |
112 /* Execute a child. */ | |
113 | |
114 static pid_t | |
115 pex_djgpp_exec_child (struct pex_obj *obj, int flags, const char *executable, | |
116 char * const * argv, char * const * env, | |
117 int in, int out, int errdes, | |
118 int toclose ATTRIBUTE_UNUSED, const char **errmsg, | |
119 int *err) | |
120 { | |
121 int org_in, org_out, org_errdes; | |
122 int status; | |
123 int *statuses; | |
124 | |
125 org_in = -1; | |
126 org_out = -1; | |
127 org_errdes = -1; | |
128 | |
129 if (in != STDIN_FILE_NO) | |
130 { | |
131 org_in = dup (STDIN_FILE_NO); | |
132 if (org_in < 0) | |
133 { | |
134 *err = errno; | |
135 *errmsg = "dup"; | |
136 return (pid_t) -1; | |
137 } | |
138 if (dup2 (in, STDIN_FILE_NO) < 0) | |
139 { | |
140 *err = errno; | |
141 *errmsg = "dup2"; | |
142 return (pid_t) -1; | |
143 } | |
144 if (close (in) < 0) | |
145 { | |
146 *err = errno; | |
147 *errmsg = "close"; | |
148 return (pid_t) -1; | |
149 } | |
150 } | |
151 | |
152 if (out != STDOUT_FILE_NO) | |
153 { | |
154 org_out = dup (STDOUT_FILE_NO); | |
155 if (org_out < 0) | |
156 { | |
157 *err = errno; | |
158 *errmsg = "dup"; | |
159 return (pid_t) -1; | |
160 } | |
161 if (dup2 (out, STDOUT_FILE_NO) < 0) | |
162 { | |
163 *err = errno; | |
164 *errmsg = "dup2"; | |
165 return (pid_t) -1; | |
166 } | |
167 if (close (out) < 0) | |
168 { | |
169 *err = errno; | |
170 *errmsg = "close"; | |
171 return (pid_t) -1; | |
172 } | |
173 } | |
174 | |
175 if (errdes != STDERR_FILE_NO | |
176 || (flags & PEX_STDERR_TO_STDOUT) != 0) | |
177 { | |
178 org_errdes = dup (STDERR_FILE_NO); | |
179 if (org_errdes < 0) | |
180 { | |
181 *err = errno; | |
182 *errmsg = "dup"; | |
183 return (pid_t) -1; | |
184 } | |
185 if (dup2 ((flags & PEX_STDERR_TO_STDOUT) != 0 ? STDOUT_FILE_NO : errdes, | |
186 STDERR_FILE_NO) < 0) | |
187 { | |
188 *err = errno; | |
189 *errmsg = "dup2"; | |
190 return (pid_t) -1; | |
191 } | |
192 if (errdes != STDERR_FILE_NO) | |
193 { | |
194 if (close (errdes) < 0) | |
195 { | |
196 *err = errno; | |
197 *errmsg = "close"; | |
198 return (pid_t) -1; | |
199 } | |
200 } | |
201 } | |
202 | |
203 if (env) | |
204 status = (((flags & PEX_SEARCH) != 0 ? spawnvpe : spawnve) | |
205 (P_WAIT, executable, argv, env)); | |
206 else | |
207 status = (((flags & PEX_SEARCH) != 0 ? spawnvp : spawnv) | |
208 (P_WAIT, executable, argv)); | |
209 | |
210 if (status == -1) | |
211 { | |
212 *err = errno; | |
213 *errmsg = ((flags & PEX_SEARCH) != 0) ? "spawnvp" : "spawnv"; | |
214 } | |
215 | |
216 if (in != STDIN_FILE_NO) | |
217 { | |
218 if (dup2 (org_in, STDIN_FILE_NO) < 0) | |
219 { | |
220 *err = errno; | |
221 *errmsg = "dup2"; | |
222 return (pid_t) -1; | |
223 } | |
224 if (close (org_in) < 0) | |
225 { | |
226 *err = errno; | |
227 *errmsg = "close"; | |
228 return (pid_t) -1; | |
229 } | |
230 } | |
231 | |
232 if (out != STDOUT_FILE_NO) | |
233 { | |
234 if (dup2 (org_out, STDOUT_FILE_NO) < 0) | |
235 { | |
236 *err = errno; | |
237 *errmsg = "dup2"; | |
238 return (pid_t) -1; | |
239 } | |
240 if (close (org_out) < 0) | |
241 { | |
242 *err = errno; | |
243 *errmsg = "close"; | |
244 return (pid_t) -1; | |
245 } | |
246 } | |
247 | |
248 if (errdes != STDERR_FILE_NO | |
249 || (flags & PEX_STDERR_TO_STDOUT) != 0) | |
250 { | |
251 if (dup2 (org_errdes, STDERR_FILE_NO) < 0) | |
252 { | |
253 *err = errno; | |
254 *errmsg = "dup2"; | |
255 return (pid_t) -1; | |
256 } | |
257 if (close (org_errdes) < 0) | |
258 { | |
259 *err = errno; | |
260 *errmsg = "close"; | |
261 return (pid_t) -1; | |
262 } | |
263 } | |
264 | |
265 /* Save the exit status for later. When we are called, obj->count | |
266 is the number of children which have executed before this | |
267 one. */ | |
268 statuses = (int *) obj->sysdep; | |
269 statuses = XRESIZEVEC (int, statuses, obj->count + 1); | |
270 statuses[obj->count] = status; | |
271 obj->sysdep = (void *) statuses; | |
272 | |
273 return (pid_t) obj->count; | |
274 } | |
275 | |
276 /* Wait for a child process to complete. Actually the child process | |
277 has already completed, and we just need to return the exit | |
278 status. */ | |
279 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
280 static pid_t |
0 | 281 pex_djgpp_wait (struct pex_obj *obj, pid_t pid, int *status, |
282 struct pex_time *time, int done ATTRIBUTE_UNUSED, | |
283 const char **errmsg ATTRIBUTE_UNUSED, | |
284 int *err ATTRIBUTE_UNUSED) | |
285 { | |
286 int *statuses; | |
287 | |
288 if (time != NULL) | |
289 memset (time, 0, sizeof *time); | |
290 | |
291 statuses = (int *) obj->sysdep; | |
292 *status = statuses[pid]; | |
293 | |
294 return 0; | |
295 } |