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