Mercurial > hg > CbC > CbC_gcc
comparison libiberty/testsuite/test-pexecute.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Pexecute test program, | |
2 Copyright (C) 2005 Free Software Foundation, Inc. | |
3 Written by Ian Lance Taylor <ian@airs.com>. | |
4 | |
5 This file is part of GNU libiberty. | |
6 | |
7 This program is free software; you can redistribute it and/or modify | |
8 it under the terms of the GNU General Public License as published by | |
9 the Free Software Foundation; either version 2 of the License, or | |
10 (at your option) any later version. | |
11 | |
12 This program 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 | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with this program; if not, write to the Free Software | |
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 */ | |
21 | |
22 #ifdef HAVE_CONFIG_H | |
23 #include "config.h" | |
24 #endif | |
25 #include "ansidecl.h" | |
26 #include "libiberty.h" | |
27 #include <stdio.h> | |
28 #include <signal.h> | |
29 #include <errno.h> | |
30 #ifdef HAVE_STRING_H | |
31 #include <string.h> | |
32 #endif | |
33 #include <sys/types.h> | |
34 #ifdef HAVE_STDLIB_H | |
35 #include <stdlib.h> | |
36 #endif | |
37 #ifdef HAVE_UNISTD_H | |
38 #include <unistd.h> | |
39 #endif | |
40 #ifdef HAVE_SYS_WAIT_H | |
41 #include <sys/wait.h> | |
42 #endif | |
43 #ifdef HAVE_SYS_TIME_H | |
44 #include <sys/time.h> | |
45 #endif | |
46 #ifdef HAVE_SYS_RESOURCE_H | |
47 #include <sys/resource.h> | |
48 #endif | |
49 | |
50 #ifndef WIFSIGNALED | |
51 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f) | |
52 #endif | |
53 #ifndef WTERMSIG | |
54 #define WTERMSIG(S) ((S) & 0x7f) | |
55 #endif | |
56 #ifndef WIFEXITED | |
57 #define WIFEXITED(S) (((S) & 0xff) == 0) | |
58 #endif | |
59 #ifndef WEXITSTATUS | |
60 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8) | |
61 #endif | |
62 #ifndef WSTOPSIG | |
63 #define WSTOPSIG WEXITSTATUS | |
64 #endif | |
65 #ifndef WCOREDUMP | |
66 #define WCOREDUMP(S) ((S) & WCOREFLG) | |
67 #endif | |
68 #ifndef WCOREFLG | |
69 #define WCOREFLG 0200 | |
70 #endif | |
71 | |
72 #ifndef EXIT_SUCCESS | |
73 #define EXIT_SUCCESS 0 | |
74 #endif | |
75 | |
76 #ifndef EXIT_FAILURE | |
77 #define EXIT_FAILURE 1 | |
78 #endif | |
79 | |
80 /* When this program is run with no arguments, it runs some tests of | |
81 the libiberty pexecute functions. As a test program, it simply | |
82 invokes itself with various arguments. | |
83 | |
84 argv[1]: | |
85 *empty string* Run tests, exit with success status | |
86 exit Exit success | |
87 error Exit error | |
88 abort Abort | |
89 echo Echo remaining arguments, exit success | |
90 echoerr Echo next arg to stdout, next to stderr, repeat | |
91 copy Copy stdin to stdout | |
92 write Write stdin to file named in next argument | |
93 */ | |
94 | |
95 static void fatal_error (int, const char *, int) ATTRIBUTE_NORETURN; | |
96 static void error (int, const char *); | |
97 static void check_line (int, FILE *, const char *); | |
98 static void do_cmd (int, char **) ATTRIBUTE_NORETURN; | |
99 | |
100 /* The number of errors we have seen. */ | |
101 | |
102 static int error_count; | |
103 | |
104 /* Print a fatal error and exit. LINE is the line number where we | |
105 detected the error, ERRMSG is the error message to print, and ERR | |
106 is 0 or an errno value to print. */ | |
107 | |
108 static void | |
109 fatal_error (int line, const char *errmsg, int err) | |
110 { | |
111 fprintf (stderr, "test-pexecute:%d: %s", line, errmsg); | |
112 if (errno != 0) | |
113 fprintf (stderr, ": %s", xstrerror (err)); | |
114 fprintf (stderr, "\n"); | |
115 exit (EXIT_FAILURE); | |
116 } | |
117 | |
118 #define FATAL_ERROR(ERRMSG, ERR) fatal_error (__LINE__, ERRMSG, ERR) | |
119 | |
120 /* Print an error message and bump the error count. LINE is the line | |
121 number where we detected the error, ERRMSG is the error to | |
122 print. */ | |
123 | |
124 static void | |
125 error (int line, const char *errmsg) | |
126 { | |
127 fprintf (stderr, "test-pexecute:%d: %s\n", line, errmsg); | |
128 ++error_count; | |
129 } | |
130 | |
131 #define ERROR(ERRMSG) error (__LINE__, ERRMSG) | |
132 | |
133 /* Check a line in a file. */ | |
134 | |
135 static void | |
136 check_line (int line, FILE *e, const char *str) | |
137 { | |
138 const char *p; | |
139 int c; | |
140 char buf[1000]; | |
141 | |
142 p = str; | |
143 while (1) | |
144 { | |
145 c = getc (e); | |
146 | |
147 if (*p == '\0') | |
148 { | |
149 if (c != '\n') | |
150 { | |
151 snprintf (buf, sizeof buf, "got '%c' when expecting newline", c); | |
152 fatal_error (line, buf, 0); | |
153 } | |
154 c = getc (e); | |
155 if (c != EOF) | |
156 { | |
157 snprintf (buf, sizeof buf, "got '%c' when expecting EOF", c); | |
158 fatal_error (line, buf, 0); | |
159 } | |
160 return; | |
161 } | |
162 | |
163 if (c != *p) | |
164 { | |
165 snprintf (buf, sizeof buf, "expected '%c', got '%c'", *p, c); | |
166 fatal_error (line, buf, 0); | |
167 } | |
168 | |
169 ++p; | |
170 } | |
171 } | |
172 | |
173 #define CHECK_LINE(E, STR) check_line (__LINE__, E, STR) | |
174 | |
175 /* Main function for the pexecute tester. Run the tests. */ | |
176 | |
177 int | |
178 main (int argc, char **argv) | |
179 { | |
180 int trace; | |
181 struct pex_obj *test_pex_tmp; | |
182 int test_pex_status; | |
183 FILE *test_pex_file; | |
184 struct pex_obj *pex1; | |
185 char *subargv[10]; | |
186 int status; | |
187 FILE *e; | |
188 int statuses[10]; | |
189 | |
190 trace = 0; | |
191 if (argc > 1 && strcmp (argv[1], "-t") == 0) | |
192 { | |
193 trace = 1; | |
194 --argc; | |
195 ++argv; | |
196 } | |
197 | |
198 if (argc > 1) | |
199 do_cmd (argc, argv); | |
200 | |
201 #define TEST_PEX_INIT(FLAGS, TEMPBASE) \ | |
202 (((test_pex_tmp = pex_init (FLAGS, "test-pexecute", TEMPBASE)) \ | |
203 != NULL) \ | |
204 ? test_pex_tmp \ | |
205 : (FATAL_ERROR ("pex_init failed", 0), NULL)) | |
206 | |
207 #define TEST_PEX_RUN(PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME, ERRNAME) \ | |
208 do \ | |
209 { \ | |
210 int err; \ | |
211 const char *pex_run_err; \ | |
212 if (trace) \ | |
213 fprintf (stderr, "Line %d: running %s %s\n", \ | |
214 __LINE__, EXECUTABLE, ARGV[0]); \ | |
215 pex_run_err = pex_run (PEXOBJ, FLAGS, EXECUTABLE, ARGV, OUTNAME, \ | |
216 ERRNAME, &err); \ | |
217 if (pex_run_err != NULL) \ | |
218 FATAL_ERROR (pex_run_err, err); \ | |
219 } \ | |
220 while (0) | |
221 | |
222 #define TEST_PEX_GET_STATUS_1(PEXOBJ) \ | |
223 (pex_get_status (PEXOBJ, 1, &test_pex_status) \ | |
224 ? test_pex_status \ | |
225 : (FATAL_ERROR ("pex_get_status failed", errno), 1)) | |
226 | |
227 #define TEST_PEX_GET_STATUS(PEXOBJ, COUNT, VECTOR) \ | |
228 do \ | |
229 { \ | |
230 if (!pex_get_status (PEXOBJ, COUNT, VECTOR)) \ | |
231 FATAL_ERROR ("pex_get_status failed", errno); \ | |
232 } \ | |
233 while (0) | |
234 | |
235 #define TEST_PEX_READ_OUTPUT(PEXOBJ) \ | |
236 ((test_pex_file = pex_read_output (PEXOBJ, 0)) != NULL \ | |
237 ? test_pex_file \ | |
238 : (FATAL_ERROR ("pex_read_output failed", errno), NULL)) | |
239 | |
240 remove ("temp.x"); | |
241 remove ("temp.y"); | |
242 | |
243 memset (subargv, 0, sizeof subargv); | |
244 | |
245 subargv[0] = "./test-pexecute"; | |
246 | |
247 pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL); | |
248 subargv[1] = "exit"; | |
249 subargv[2] = NULL; | |
250 TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL); | |
251 status = TEST_PEX_GET_STATUS_1 (pex1); | |
252 if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS) | |
253 ERROR ("exit failed"); | |
254 pex_free (pex1); | |
255 | |
256 pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL); | |
257 subargv[1] = "error"; | |
258 subargv[2] = NULL; | |
259 TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, NULL); | |
260 status = TEST_PEX_GET_STATUS_1 (pex1); | |
261 if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_FAILURE) | |
262 ERROR ("error test failed"); | |
263 pex_free (pex1); | |
264 | |
265 /* We redirect stderr to a file to avoid an error message which is | |
266 printed on mingw32 when the child calls abort. */ | |
267 pex1 = TEST_PEX_INIT (PEX_USE_PIPES, NULL); | |
268 subargv[1] = "abort"; | |
269 subargv[2] = NULL; | |
270 TEST_PEX_RUN (pex1, PEX_LAST, "./test-pexecute", subargv, NULL, "temp.z"); | |
271 status = TEST_PEX_GET_STATUS_1 (pex1); | |
272 if (!WIFSIGNALED (status) || WTERMSIG (status) != SIGABRT) | |
273 ERROR ("abort failed"); | |
274 pex_free (pex1); | |
275 remove ("temp.z"); | |
276 | |
277 pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp"); | |
278 subargv[1] = "echo"; | |
279 subargv[2] = "foo"; | |
280 subargv[3] = NULL; | |
281 TEST_PEX_RUN (pex1, 0, "./test-pexecute", subargv, NULL, NULL); | |
282 e = TEST_PEX_READ_OUTPUT (pex1); | |
283 CHECK_LINE (e, "foo"); | |
284 if (TEST_PEX_GET_STATUS_1 (pex1) != 0) | |
285 ERROR ("echo exit status failed"); | |
286 pex_free (pex1); | |
287 | |
288 pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp"); | |
289 subargv[1] = "echo"; | |
290 subargv[2] = "bar"; | |
291 subargv[3] = NULL; | |
292 TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL); | |
293 subargv[1] = "copy"; | |
294 subargv[2] = NULL; | |
295 TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL); | |
296 e = TEST_PEX_READ_OUTPUT (pex1); | |
297 CHECK_LINE (e, "bar"); | |
298 TEST_PEX_GET_STATUS (pex1, 2, statuses); | |
299 if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS | |
300 || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS) | |
301 ERROR ("copy exit status failed"); | |
302 pex_free (pex1); | |
303 if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL) | |
304 ERROR ("temporary files exist"); | |
305 | |
306 pex1 = TEST_PEX_INIT (0, "temp"); | |
307 subargv[1] = "echo"; | |
308 subargv[2] = "bar"; | |
309 subargv[3] = NULL; | |
310 TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL); | |
311 subargv[1] = "copy"; | |
312 subargv[2] = NULL; | |
313 TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL); | |
314 e = TEST_PEX_READ_OUTPUT (pex1); | |
315 CHECK_LINE (e, "bar"); | |
316 TEST_PEX_GET_STATUS (pex1, 2, statuses); | |
317 if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS | |
318 || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS) | |
319 ERROR ("copy exit status failed"); | |
320 pex_free (pex1); | |
321 if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL) | |
322 ERROR ("temporary files exist"); | |
323 | |
324 pex1 = TEST_PEX_INIT (PEX_SAVE_TEMPS, "temp"); | |
325 subargv[1] = "echo"; | |
326 subargv[2] = "quux"; | |
327 subargv[3] = NULL; | |
328 TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", NULL); | |
329 subargv[1] = "copy"; | |
330 subargv[2] = NULL; | |
331 TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL); | |
332 e = TEST_PEX_READ_OUTPUT (pex1); | |
333 CHECK_LINE (e, "quux"); | |
334 TEST_PEX_GET_STATUS (pex1, 2, statuses); | |
335 if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS | |
336 || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS) | |
337 ERROR ("copy temp exit status failed"); | |
338 e = fopen ("temp.x", "r"); | |
339 if (e == NULL) | |
340 FATAL_ERROR ("fopen temp.x failed in copy temp", errno); | |
341 CHECK_LINE (e, "quux"); | |
342 fclose (e); | |
343 e = fopen ("temp.y", "r"); | |
344 if (e == NULL) | |
345 FATAL_ERROR ("fopen temp.y failed in copy temp", errno); | |
346 CHECK_LINE (e, "quux"); | |
347 fclose (e); | |
348 pex_free (pex1); | |
349 remove ("temp.x"); | |
350 remove ("temp.y"); | |
351 | |
352 pex1 = TEST_PEX_INIT (PEX_USE_PIPES, "temp"); | |
353 subargv[1] = "echoerr"; | |
354 subargv[2] = "one"; | |
355 subargv[3] = "two"; | |
356 subargv[4] = NULL; | |
357 TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".x", "temp2.x"); | |
358 subargv[1] = "write"; | |
359 subargv[2] = "temp2.y"; | |
360 subargv[3] = NULL; | |
361 TEST_PEX_RUN (pex1, PEX_SUFFIX, "./test-pexecute", subargv, ".y", NULL); | |
362 TEST_PEX_GET_STATUS (pex1, 2, statuses); | |
363 if (!WIFEXITED (statuses[0]) || WEXITSTATUS (statuses[0]) != EXIT_SUCCESS | |
364 || !WIFEXITED (statuses[1]) || WEXITSTATUS (statuses[1]) != EXIT_SUCCESS) | |
365 ERROR ("echoerr exit status failed"); | |
366 pex_free (pex1); | |
367 if (fopen ("temp.x", "r") != NULL || fopen ("temp.y", "r") != NULL) | |
368 ERROR ("temporary files exist"); | |
369 e = fopen ("temp2.x", "r"); | |
370 if (e == NULL) | |
371 FATAL_ERROR ("fopen temp2.x failed in echoerr", errno); | |
372 CHECK_LINE (e, "two"); | |
373 fclose (e); | |
374 e = fopen ("temp2.y", "r"); | |
375 if (e == NULL) | |
376 FATAL_ERROR ("fopen temp2.y failed in echoerr", errno); | |
377 CHECK_LINE (e, "one"); | |
378 fclose (e); | |
379 remove ("temp2.x"); | |
380 remove ("temp2.y"); | |
381 | |
382 /* Test the old pexecute interface. */ | |
383 { | |
384 int pid1, pid2; | |
385 char *errmsg_fmt; | |
386 char *errmsg_arg; | |
387 char errbuf1[1000]; | |
388 char errbuf2[1000]; | |
389 | |
390 subargv[1] = "echo"; | |
391 subargv[2] = "oldpexecute"; | |
392 subargv[3] = NULL; | |
393 pid1 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp", | |
394 &errmsg_fmt, &errmsg_arg, PEXECUTE_FIRST); | |
395 if (pid1 < 0) | |
396 { | |
397 snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg); | |
398 snprintf (errbuf2, sizeof errbuf2, "pexecute 1 failed: %s", errbuf1); | |
399 FATAL_ERROR (errbuf2, 0); | |
400 } | |
401 | |
402 subargv[1] = "write"; | |
403 subargv[2] = "temp.y"; | |
404 subargv[3] = NULL; | |
405 pid2 = pexecute ("./test-pexecute", subargv, "test-pexecute", "temp", | |
406 &errmsg_fmt, &errmsg_arg, PEXECUTE_LAST); | |
407 if (pid2 < 0) | |
408 { | |
409 snprintf (errbuf1, sizeof errbuf1, errmsg_fmt, errmsg_arg); | |
410 snprintf (errbuf2, sizeof errbuf2, "pexecute 2 failed: %s", errbuf1); | |
411 FATAL_ERROR (errbuf2, 0); | |
412 } | |
413 | |
414 if (pwait (pid1, &status, 0) < 0) | |
415 FATAL_ERROR ("write pwait 1 failed", errno); | |
416 if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS) | |
417 ERROR ("write exit status 1 failed"); | |
418 | |
419 if (pwait (pid2, &status, 0) < 0) | |
420 FATAL_ERROR ("write pwait 1 failed", errno); | |
421 if (!WIFEXITED (status) || WEXITSTATUS (status) != EXIT_SUCCESS) | |
422 ERROR ("write exit status 2 failed"); | |
423 | |
424 e = fopen ("temp.y", "r"); | |
425 if (e == NULL) | |
426 FATAL_ERROR ("fopen temp.y failed in copy temp", errno); | |
427 CHECK_LINE (e, "oldpexecute"); | |
428 fclose (e); | |
429 | |
430 remove ("temp.y"); | |
431 } | |
432 | |
433 if (trace) | |
434 fprintf (stderr, "Exiting with status %d\n", error_count); | |
435 | |
436 return error_count; | |
437 } | |
438 | |
439 /* Execute one of the special testing commands. */ | |
440 | |
441 static void | |
442 do_cmd (int argc, char **argv) | |
443 { | |
444 const char *s; | |
445 | |
446 /* Try to prevent generating a core dump. */ | |
447 #ifdef RLIMIT_CORE | |
448 { | |
449 struct rlimit r; | |
450 | |
451 r.rlim_cur = 0; | |
452 r.rlim_max = 0; | |
453 setrlimit (RLIMIT_CORE, &r); | |
454 } | |
455 #endif | |
456 | |
457 s = argv[1]; | |
458 if (strcmp (s, "exit") == 0) | |
459 exit (EXIT_SUCCESS); | |
460 else if (strcmp (s, "echo") == 0) | |
461 { | |
462 int i; | |
463 | |
464 for (i = 2; i < argc; ++i) | |
465 { | |
466 if (i > 2) | |
467 putchar (' '); | |
468 fputs (argv[i], stdout); | |
469 } | |
470 putchar ('\n'); | |
471 exit (EXIT_SUCCESS); | |
472 } | |
473 else if (strcmp (s, "echoerr") == 0) | |
474 { | |
475 int i; | |
476 | |
477 for (i = 2; i < argc; ++i) | |
478 { | |
479 if (i > 3) | |
480 putc (' ', (i & 1) == 0 ? stdout : stderr); | |
481 fputs (argv[i], (i & 1) == 0 ? stdout : stderr); | |
482 } | |
483 putc ('\n', stdout); | |
484 putc ('\n', stderr); | |
485 exit (EXIT_SUCCESS); | |
486 } | |
487 else if (strcmp (s, "error") == 0) | |
488 exit (EXIT_FAILURE); | |
489 else if (strcmp (s, "abort") == 0) | |
490 abort (); | |
491 else if (strcmp (s, "copy") == 0) | |
492 { | |
493 int c; | |
494 | |
495 while ((c = getchar ()) != EOF) | |
496 putchar (c); | |
497 exit (EXIT_SUCCESS); | |
498 } | |
499 else if (strcmp (s, "write") == 0) | |
500 { | |
501 FILE *e; | |
502 int c; | |
503 | |
504 e = fopen (argv[2], "w"); | |
505 if (e == NULL) | |
506 FATAL_ERROR ("fopen for write failed", errno); | |
507 while ((c = getchar ()) != EOF) | |
508 putc (c, e); | |
509 if (fclose (e) != 0) | |
510 FATAL_ERROR ("fclose for write failed", errno); | |
511 exit (EXIT_SUCCESS); | |
512 } | |
513 else | |
514 { | |
515 char buf[1000]; | |
516 | |
517 snprintf (buf, sizeof buf, "unrecognized command %s", argv[1]); | |
518 FATAL_ERROR (buf, 0); | |
519 } | |
520 | |
521 exit (EXIT_FAILURE); | |
522 } |