Print this page
make: unifdef for MAKETOOL and DISTRIBUTED (undefined)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/lib/mksh/dosys.cc
+++ new/usr/src/cmd/make/lib/mksh/dosys.cc
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26
27 27 /*
28 28 * dosys.cc
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
29 29 *
30 30 * Execute one commandline
31 31 */
32 32
33 33 /*
34 34 * Included files
35 35 */
36 36 #include <sys/wait.h> /* WIFEXITED(status) */
37 37 #include <alloca.h> /* alloca() */
38 38
39 -#if defined(TEAMWARE_MAKE_CMN) || defined(MAKETOOL) /* tolik */
40 -#if defined(DISTRIBUTED)
41 -# include <dm/Avo_CmdOutput.h>
42 -# include <rw/xdrstrea.h>
43 -#endif
44 -#endif
45 -
46 39 #include <stdio.h> /* errno */
47 40 #include <errno.h> /* errno */
48 41 #include <fcntl.h> /* open() */
49 42 #include <mksh/dosys.h>
50 43 #include <mksh/macro.h> /* getvar() */
51 44 #include <mksh/misc.h> /* getmem(), fatal_mksh(), errmsg() */
52 45 #include <mksdmsi18n/mksdmsi18n.h> /* libmksdmsi18n_init() */
53 46 #include <sys/signal.h> /* SIG_DFL */
54 47 #include <sys/stat.h> /* open() */
55 48 #include <sys/wait.h> /* wait() */
56 49 #include <ulimit.h> /* ulimit() */
57 50 #include <unistd.h> /* close(), dup2() */
58 51
59 52
60 53
61 54 /*
62 55 * Defined macros
63 56 */
64 -#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
65 -#define SEND_MTOOL_MSG(cmds) \
66 - if (send_mtool_msgs) { \
67 - cmds \
68 - }
69 -#else
70 57 #define SEND_MTOOL_MSG(cmds)
71 -#endif
72 58
73 59 /*
74 60 * typedefs & structs
75 61 */
76 62
77 63 /*
78 64 * Static variables
79 65 */
80 66
81 67 /*
82 68 * File table of contents
83 69 */
84 70 static Boolean exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path);
85 71
86 72 /*
87 73 * Workaround for NFS bug. Sometimes, when running 'open' on a remote
88 74 * dmake server, it fails with "Stale NFS file handle" error.
89 75 * The second attempt seems to work.
90 76 */
91 77 int
92 78 my_open(const char *path, int oflag, mode_t mode) {
93 79 int res = open(path, oflag, mode);
94 80 if (res < 0 && (errno == ESTALE || errno == EAGAIN)) {
95 81 /* Stale NFS file handle. Try again */
96 82 res = open(path, oflag, mode);
97 83 }
98 84 return res;
99 85 }
100 86
101 87 /*
102 88 * void
103 89 * redirect_io(char *stdout_file, char *stderr_file)
104 90 *
105 91 * Redirects stdout and stderr for a child mksh process.
106 92 */
107 93 void
108 94 redirect_io(char *stdout_file, char *stderr_file)
109 95 {
110 96 long descriptor_limit;
111 97 int i;
112 98
113 99 if ((descriptor_limit = ulimit(UL_GDESLIM)) < 0) {
114 100 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 89, "ulimit() failed: %s"), errmsg(errno));
115 101 }
116 102 for (i = 3; i < descriptor_limit; i++) {
117 103 (void) close(i);
118 104 }
119 105 if ((i = my_open(stdout_file,
120 106 O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
121 107 S_IREAD | S_IWRITE)) < 0) {
122 108 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 90, "Couldn't open standard out temp file `%s': %s"),
123 109 stdout_file,
124 110 errmsg(errno));
125 111 } else {
126 112 if (dup2(i, 1) == -1) {
127 113 fatal_mksh(NOCATGETS("*** Error: dup2(3, 1) failed: %s"),
128 114 errmsg(errno));
129 115 }
130 116 close(i);
131 117 }
132 118 if (stderr_file == NULL) {
133 119 if (dup2(1, 2) == -1) {
134 120 fatal_mksh(NOCATGETS("*** Error: dup2(1, 2) failed: %s"),
135 121 errmsg(errno));
136 122 }
137 123 } else if ((i = my_open(stderr_file,
138 124 O_WRONLY | O_CREAT | O_TRUNC | O_DSYNC,
139 125 S_IREAD | S_IWRITE)) < 0) {
140 126 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 91, "Couldn't open standard error temp file `%s': %s"),
141 127 stderr_file,
142 128 errmsg(errno));
143 129 } else {
144 130 if (dup2(i, 2) == -1) {
145 131 fatal_mksh(NOCATGETS("*** Error: dup2(3, 2) failed: %s"),
146 132 errmsg(errno));
147 133 }
148 134 close(i);
149 135 }
150 136 }
151 137
152 138 /*
153 139 * dosys_mksh(command, ignore_error, call_make, silent_error, target)
154 140 *
155 141 * Check if command string contains meta chars and dispatch to
156 142 * the proper routine for executing one command line.
157 143 *
158 144 * Return value:
159 145 * Indicates if the command execution failed
160 146 *
161 147 * Parameters:
162 148 * command The command to run
163 149 * ignore_error Should we abort when an error is seen?
164 150 * call_make Did command reference $(MAKE) ?
165 151 * silent_error Should error messages be suppressed for dmake?
166 152 * target Target we are building
167 153 *
168 154 * Global variables used:
169 155 * do_not_exec_rule Is -n on?
170 156 * working_on_targets We started processing real targets
171 157 */
172 158 Doname
173 159 dosys_mksh(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
174 160 {
175 161 register int length = command->hash.length;
176 162 register wchar_t *p;
177 163 register wchar_t *q;
178 164 register wchar_t *cmd_string;
179 165 struct stat before;
180 166 Doname result;
181 167 Boolean working_on_targets_mksh = true;
182 168 Wstring wcb(command);
183 169 p = wcb.get_string();
184 170 cmd_string = p;
185 171
186 172 /* Strip spaces from head of command string */
187 173 while (iswspace(*p)) {
188 174 p++, length--;
189 175 }
190 176 if (*p == (int) nul_char) {
191 177 return build_failed;
192 178 }
193 179 /* If we are faking it we just return */
194 180 if (do_not_exec_rule &&
195 181 working_on_targets_mksh &&
196 182 !call_make &&
197 183 !always_exec) {
198 184 return build_ok;
199 185 }
200 186
201 187 /* Copy string to make it OK to write it. */
202 188 q = ALLOC_WC(length + 1);
203 189 (void) wscpy(q, p);
204 190 /* Write the state file iff this command uses make. */
205 191 /* XXX - currently does not support recursive make's, $(MAKE)'s
206 192 if (call_make && command_changed) {
207 193 write_state_file(0, false);
208 194 }
209 195 (void) stat(make_state->string_mb, &before);
210 196 */
211 197 /*
212 198 * Run command directly if it contains no shell meta chars,
213 199 * else run it using the shell.
214 200 */
215 201 /* XXX - command->meta *may* not be set correctly */
216 202 if (await(ignore_error,
217 203 silent_error,
218 204 target,
219 205 cmd_string,
220 206 command->meta ?
221 207 doshell(q, ignore_error, redirect_out_err, stdout_file, stderr_file, nice_prio) :
222 208 doexec(q, ignore_error, redirect_out_err, stdout_file, stderr_file, vroot_path, nice_prio),
223 209 false,
224 210 NULL,
225 211 -1)) {
226 212
227 213 #ifdef PRINT_EXIT_STATUS
228 214 warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_ok."));
229 215 #endif
230 216
231 217 result = build_ok;
232 218 } else {
233 219
234 220 #ifdef PRINT_EXIT_STATUS
235 221 warning_mksh(NOCATGETS("I'm in dosys_mksh(), and await() returned result of build_failed."));
236 222 #endif
237 223
238 224 result = build_failed;
239 225 }
240 226 retmem(q);
241 227
242 228 /* XXX - currently does not support recursive make's, $(MAKE)'s
243 229 if ((report_dependencies_level == 0) &&
244 230 call_make) {
245 231 make_state->stat.time = (time_t)file_no_time;
246 232 (void)exists(make_state);
247 233 if (before.st_mtime == make_state->stat.time) {
248 234 return result;
249 235 }
250 236 makefile_type = reading_statefile;
251 237 if (read_trace_level > 1) {
252 238 trace_reader = true;
253 239 }
254 240 (void) read_simple_file(make_state,
255 241 false,
256 242 false,
257 243 false,
258 244 false,
259 245 false,
260 246 true);
261 247 trace_reader = false;
262 248 }
263 249 */
264 250 return result;
265 251 }
266 252
267 253 /*
268 254 * doshell(command, ignore_error)
269 255 *
270 256 * Used to run command lines that include shell meta-characters.
271 257 * The make macro SHELL is supposed to contain a path to the shell.
272 258 *
273 259 * Return value:
274 260 * The pid of the process we started
275 261 *
276 262 * Parameters:
277 263 * command The command to run
278 264 * ignore_error Should we abort on error?
279 265 *
280 266 * Global variables used:
281 267 * filter_stderr If -X is on we redirect stderr
282 268 * shell_name The Name "SHELL", used to get the path to shell
283 269 */
284 270 int
285 271 doshell(wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, int nice_prio)
286 272 {
287 273 char *argv[6];
288 274 int argv_index = 0;
289 275 int cmd_argv_index;
290 276 int length;
291 277 char nice_prio_buf[MAXPATHLEN];
292 278 register Name shell = getvar(shell_name);
293 279 register char *shellname;
294 280 char *tmp_mbs_buffer;
295 281
296 282
297 283 if (IS_EQUAL(shell->string_mb, "")) {
298 284 shell = shell_name;
299 285 }
300 286 if ((shellname = strrchr(shell->string_mb, (int) slash_char)) == NULL) {
301 287 shellname = shell->string_mb;
302 288 } else {
303 289 shellname++;
304 290 }
305 291
306 292 /*
307 293 * Only prepend the /usr/bin/nice command to the original command
308 294 * if the nice priority, nice_prio, is NOT zero (0).
309 295 * Nice priorities can be a positive or a negative number.
310 296 */
311 297 if (nice_prio != 0) {
312 298 argv[argv_index++] = (char *)NOCATGETS("nice");
313 299 (void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
314 300 argv[argv_index++] = strdup(nice_prio_buf);
315 301 }
316 302 argv[argv_index++] = shellname;
317 303 argv[argv_index++] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
318 304 if ((length = wslen(command)) >= MAXPATHLEN) {
319 305 tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
320 306 (void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
321 307 cmd_argv_index = argv_index;
322 308 argv[argv_index++] = strdup(tmp_mbs_buffer);
323 309 retmem_mb(tmp_mbs_buffer);
324 310 } else {
325 311 WCSTOMBS(mbs_buffer, command);
326 312 cmd_argv_index = argv_index;
327 313 argv[argv_index++] = strdup(mbs_buffer);
328 314 }
329 315 argv[argv_index] = NULL;
330 316 (void) fflush(stdout);
331 317 if ((childPid = fork()) == 0) {
332 318 enable_interrupt((void (*) (int)) SIG_DFL);
333 319 if (redirect_out_err) {
334 320 redirect_io(stdout_file, stderr_file);
335 321 }
336 322 #if 0
337 323 if (filter_stderr) {
338 324 redirect_stderr();
339 325 }
340 326 #endif
341 327 if (nice_prio != 0) {
342 328 (void) execve(NOCATGETS("/usr/bin/nice"), argv, environ);
343 329 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 92, "Could not load `/usr/bin/nice': %s"),
344 330 errmsg(errno));
345 331 } else {
346 332 (void) execve(shell->string_mb, argv, environ);
347 333 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 93, "Could not load Shell from `%s': %s"),
348 334 shell->string_mb,
349 335 errmsg(errno));
350 336 }
351 337 }
352 338 if (childPid == -1) {
353 339 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 94, "fork failed: %s"),
354 340 errmsg(errno));
355 341 }
356 342 retmem_mb(argv[cmd_argv_index]);
357 343 return childPid;
358 344 }
359 345
360 346 /*
361 347 * exec_vp(name, argv, envp, ignore_error)
362 348 *
363 349 * Like execve, but does path search.
364 350 * This starts command when make invokes it directly (without a shell).
365 351 *
366 352 * Return value:
367 353 * Returns false if the exec failed
368 354 *
369 355 * Parameters:
370 356 * name The name of the command to run
371 357 * argv Arguments for the command
372 358 * envp The environment for it
373 359 * ignore_error Should we abort on error?
374 360 *
375 361 * Global variables used:
376 362 * shell_name The Name "SHELL", used to get the path to shell
377 363 * vroot_path The path used by the vroot package
378 364 */
379 365 static Boolean
380 366 exec_vp(register char *name, register char **argv, char **envp, register Boolean ignore_error, pathpt vroot_path)
381 367 {
382 368 register Name shell = getvar(shell_name);
383 369 register char *shellname;
384 370 char *shargv[4];
385 371 Name tmp_shell;
386 372
387 373 if (IS_EQUAL(shell->string_mb, "")) {
388 374 shell = shell_name;
389 375 }
390 376
391 377 for (int i = 0; i < 5; i++) {
392 378 (void) execve_vroot(name,
393 379 argv + 1,
394 380 envp,
395 381 vroot_path,
396 382 VROOT_DEFAULT);
397 383 switch (errno) {
398 384 case ENOEXEC:
399 385 case ENOENT:
400 386 /* That failed. Let the shell handle it */
401 387 shellname = strrchr(shell->string_mb, (int) slash_char);
402 388 if (shellname == NULL) {
403 389 shellname = shell->string_mb;
404 390 } else {
405 391 shellname++;
406 392 }
407 393 shargv[0] = shellname;
408 394 shargv[1] = (char*)(ignore_error ? NOCATGETS("-c") : NOCATGETS("-ce"));
409 395 shargv[2] = argv[0];
410 396 shargv[3] = NULL;
411 397 tmp_shell = getvar(shell_name);
412 398 if (IS_EQUAL(tmp_shell->string_mb, "")) {
413 399 tmp_shell = shell_name;
414 400 }
415 401 (void) execve_vroot(tmp_shell->string_mb,
416 402 shargv,
417 403 envp,
418 404 vroot_path,
419 405 VROOT_DEFAULT);
420 406 return failed;
421 407 case ETXTBSY:
422 408 /*
423 409 * The program is busy (debugged?).
424 410 * Wait and then try again.
425 411 */
426 412 (void) sleep((unsigned) i);
427 413 case EAGAIN:
428 414 break;
429 415 default:
430 416 return failed;
431 417 }
432 418 }
433 419 return failed;
434 420 }
435 421
436 422 /*
437 423 * doexec(command, ignore_error)
438 424 *
439 425 * Will scan an argument string and split it into words
440 426 * thus building an argument list that can be passed to exec_ve()
441 427 *
442 428 * Return value:
443 429 * The pid of the process started here
444 430 *
445 431 * Parameters:
446 432 * command The command to run
447 433 * ignore_error Should we abort on error?
448 434 *
449 435 * Global variables used:
450 436 * filter_stderr If -X is on we redirect stderr
451 437 */
452 438 int
453 439 doexec(register wchar_t *command, register Boolean ignore_error, Boolean redirect_out_err, char *stdout_file, char *stderr_file, pathpt vroot_path, int nice_prio)
454 440 {
455 441 int arg_count = 5;
456 442 char **argv;
457 443 int length;
458 444 char nice_prio_buf[MAXPATHLEN];
459 445 register char **p;
460 446 wchar_t *q;
461 447 register wchar_t *t;
462 448 char *tmp_mbs_buffer;
463 449
464 450 /*
465 451 * Only prepend the /usr/bin/nice command to the original command
466 452 * if the nice priority, nice_prio, is NOT zero (0).
467 453 * Nice priorities can be a positive or a negative number.
468 454 */
469 455 if (nice_prio != 0) {
470 456 arg_count += 2;
471 457 }
472 458 for (t = command; *t != (int) nul_char; t++) {
473 459 if (iswspace(*t)) {
474 460 arg_count++;
475 461 }
476 462 }
477 463 argv = (char **)alloca(arg_count * (sizeof(char *)));
478 464 /*
479 465 * Reserve argv[0] for sh in case of exec_vp failure.
480 466 * Don't worry about prepending /usr/bin/nice command to argv[0].
481 467 * In fact, doing it may cause the sh command to fail!
482 468 */
483 469 p = &argv[1];
484 470 if ((length = wslen(command)) >= MAXPATHLEN) {
485 471 tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
486 472 (void) wcstombs(tmp_mbs_buffer, command, (length * MB_LEN_MAX) + 1);
487 473 argv[0] = strdup(tmp_mbs_buffer);
488 474 retmem_mb(tmp_mbs_buffer);
489 475 } else {
490 476 WCSTOMBS(mbs_buffer, command);
491 477 argv[0] = strdup(mbs_buffer);
492 478 }
493 479
494 480 if (nice_prio != 0) {
495 481 *p++ = strdup(NOCATGETS("/usr/bin/nice"));
496 482 (void) sprintf(nice_prio_buf, NOCATGETS("-%d"), nice_prio);
497 483 *p++ = strdup(nice_prio_buf);
498 484 }
499 485 /* Build list of argument words. */
500 486 for (t = command; *t;) {
501 487 if (p >= &argv[arg_count]) {
502 488 /* This should never happen, right? */
503 489 WCSTOMBS(mbs_buffer, command);
504 490 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 95, "Command `%s' has more than %d arguments"),
505 491 mbs_buffer,
506 492 arg_count);
507 493 }
508 494 q = t;
509 495 while (!iswspace(*t) && (*t != (int) nul_char)) {
510 496 t++;
511 497 }
512 498 if (*t) {
513 499 for (*t++ = (int) nul_char; iswspace(*t); t++);
514 500 }
515 501 if ((length = wslen(q)) >= MAXPATHLEN) {
516 502 tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
517 503 (void) wcstombs(tmp_mbs_buffer, q, (length * MB_LEN_MAX) + 1);
518 504 *p++ = strdup(tmp_mbs_buffer);
519 505 retmem_mb(tmp_mbs_buffer);
520 506 } else {
521 507 WCSTOMBS(mbs_buffer, q);
522 508 *p++ = strdup(mbs_buffer);
523 509 }
524 510 }
525 511 *p = NULL;
526 512
527 513 /* Then exec the command with that argument list. */
528 514 (void) fflush(stdout);
529 515 if ((childPid = fork()) == 0) {
530 516 enable_interrupt((void (*) (int)) SIG_DFL);
531 517 if (redirect_out_err) {
532 518 redirect_io(stdout_file, stderr_file);
533 519 }
534 520 #if 0
535 521 if (filter_stderr) {
536 522 redirect_stderr();
537 523 }
538 524 #endif
539 525 (void) exec_vp(argv[1], argv, environ, ignore_error, vroot_path);
540 526 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 96, "Cannot load command `%s': %s"), argv[1], errmsg(errno));
541 527 }
542 528 if (childPid == -1) {
543 529 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 97, "fork failed: %s"),
544 530 errmsg(errno));
545 531 }
546 532 for (int i = 0; argv[i] != NULL; i++) {
547 533 retmem_mb(argv[i]);
548 534 }
549 535 return childPid;
550 536 }
551 537
552 538 /*
553 539 * await(ignore_error, silent_error, target, command, running_pid)
554 540 *
555 541 * Wait for one child process and analyzes
556 542 * the returned status when the child process terminates.
557 543 *
558 544 * Return value:
559 545 * Returns true if commands ran OK
560 546 *
561 547 * Parameters:
562 548 * ignore_error Should we abort on error?
563 549 * silent_error Should error messages be suppressed for dmake?
564 550 * target The target we are building, for error msgs
↓ open down ↓ |
483 lines elided |
↑ open up ↑ |
565 551 * command The command we ran, for error msgs
566 552 * running_pid The pid of the process we are waiting for
567 553 *
568 554 * Static variables used:
569 555 * filter_file The fd for the filter file
570 556 * filter_file_name The name of the filter file
571 557 *
572 558 * Global variables used:
573 559 * filter_stderr Set if -X is on
574 560 */
575 -#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
576 -Boolean
577 -await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, XDR *xdrs_p, int job_msg_id)
578 -#else
579 561 Boolean
580 562 await(register Boolean ignore_error, register Boolean silent_error, Name target, wchar_t *command, pid_t running_pid, Boolean send_mtool_msgs, void *xdrs_p, int job_msg_id)
581 -#endif
582 563 {
583 564 int status;
584 565 char *buffer;
585 566 int core_dumped;
586 567 int exit_status;
587 -#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
588 - Avo_CmdOutput *make_output_msg;
589 -#endif
590 568 FILE *outfp;
591 569 register pid_t pid;
592 570 struct stat stat_buff;
593 571 int termination_signal;
594 572 char tmp_buf[MAXPATHLEN];
595 -#if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
596 - RWCollectable *xdr_msg;
597 -#endif
598 573
599 574 while ((pid = wait(&status)) != running_pid) {
600 575 if (pid == -1) {
601 576 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 98, "wait() failed: %s"), errmsg(errno));
602 577 }
603 578 }
604 579 (void) fflush(stdout);
605 580 (void) fflush(stderr);
606 581
607 582 if (status == 0) {
608 583
609 584 #ifdef PRINT_EXIT_STATUS
610 585 warning_mksh(NOCATGETS("I'm in await(), and status is 0."));
611 586 #endif
612 587
613 588 return succeeded;
614 589 }
615 590
616 591 #ifdef PRINT_EXIT_STATUS
617 592 warning_mksh(NOCATGETS("I'm in await(), and status is *NOT* 0."));
618 593 #endif
619 594
620 595
621 596 exit_status = WEXITSTATUS(status);
622 597
623 598 #ifdef PRINT_EXIT_STATUS
624 599 warning_mksh(NOCATGETS("I'm in await(), and exit_status is %d."), exit_status);
625 600 #endif
626 601
627 602 termination_signal = WTERMSIG(status);
628 603 core_dumped = WCOREDUMP(status);
629 604
630 605 /*
631 606 * If the child returned an error, we now try to print a
632 607 * nice message about it.
633 608 */
634 609 SEND_MTOOL_MSG(
635 610 make_output_msg = new Avo_CmdOutput();
636 611 (void) sprintf(tmp_buf, "%d", job_msg_id);
637 612 make_output_msg->appendOutput(strdup(tmp_buf));
638 613 );
639 614
640 615 tmp_buf[0] = (int) nul_char;
641 616 if (!silent_error) {
642 617 if (exit_status != 0) {
643 618 (void) fprintf(stdout,
644 619 catgets(libmksdmsi18n_catd, 1, 103, "*** Error code %d"),
645 620 exit_status);
646 621 SEND_MTOOL_MSG(
647 622 (void) sprintf(&tmp_buf[strlen(tmp_buf)],
648 623 catgets(libmksdmsi18n_catd, 1, 104, "*** Error code %d"),
649 624 exit_status);
650 625 );
651 626 } else {
652 627 (void) fprintf(stdout,
653 628 catgets(libmksdmsi18n_catd, 1, 105, "*** Signal %d"),
654 629 termination_signal);
655 630 SEND_MTOOL_MSG(
656 631 (void) sprintf(&tmp_buf[strlen(tmp_buf)],
657 632 catgets(libmksdmsi18n_catd, 1, 106, "*** Signal %d"),
658 633 termination_signal);
659 634 );
660 635 if (core_dumped) {
661 636 (void) fprintf(stdout,
662 637 catgets(libmksdmsi18n_catd, 1, 107, " - core dumped"));
663 638 SEND_MTOOL_MSG(
664 639 (void) sprintf(&tmp_buf[strlen(tmp_buf)],
665 640 catgets(libmksdmsi18n_catd, 1, 108, " - core dumped"));
666 641 );
667 642 }
668 643 }
669 644 if (ignore_error) {
670 645 (void) fprintf(stdout,
671 646 catgets(libmksdmsi18n_catd, 1, 109, " (ignored)"));
672 647 SEND_MTOOL_MSG(
673 648 (void) sprintf(&tmp_buf[strlen(tmp_buf)],
674 649 catgets(libmksdmsi18n_catd, 1, 110, " (ignored)"));
675 650 );
676 651 }
677 652 (void) fprintf(stdout, "\n");
678 653 (void) fflush(stdout);
679 654 SEND_MTOOL_MSG(
680 655 make_output_msg->appendOutput(strdup(tmp_buf));
681 656 );
682 657 }
683 658 SEND_MTOOL_MSG(
684 659 xdr_msg = (RWCollectable*) make_output_msg;
685 660 xdr(xdrs_p, xdr_msg);
686 661 delete make_output_msg;
687 662 );
688 663
689 664 #ifdef PRINT_EXIT_STATUS
690 665 warning_mksh(NOCATGETS("I'm in await(), returning failed."));
691 666 #endif
692 667
693 668 return failed;
694 669 }
695 670
696 671 /*
697 672 * sh_command2string(command, destination)
698 673 *
699 674 * Run one sh command and capture the output from it.
700 675 *
701 676 * Return value:
702 677 *
703 678 * Parameters:
704 679 * command The command to run
705 680 * destination Where to deposit the output from the command
706 681 *
707 682 * Static variables used:
708 683 *
709 684 * Global variables used:
710 685 */
711 686 void
712 687 sh_command2string(register String command, register String destination)
713 688 {
714 689 register FILE *fd;
715 690 register int chr;
716 691 int status;
717 692 Boolean command_generated_output = false;
718 693
719 694 command->text.p = (int) nul_char;
720 695 WCSTOMBS(mbs_buffer, command->buffer.start);
721 696 if ((fd = popen(mbs_buffer, "r")) == NULL) {
722 697 WCSTOMBS(mbs_buffer, command->buffer.start);
723 698 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 111, "Could not run command `%s' for :sh transformation"),
724 699 mbs_buffer);
725 700 }
726 701 while ((chr = getc(fd)) != EOF) {
727 702 if (chr == (int) newline_char) {
728 703 chr = (int) space_char;
729 704 }
730 705 command_generated_output = true;
731 706 append_char(chr, destination);
732 707 }
733 708
734 709 /*
735 710 * We don't want to keep the last LINE_FEED since usually
736 711 * the output of the 'sh:' command is used to evaluate
737 712 * some MACRO. ( /bin/sh and other shell add a line feed
738 713 * to the output so that the prompt appear in the right place.
739 714 * We don't need that
740 715 */
741 716 if (command_generated_output){
742 717 if ( *(destination->text.p-1) == (int) space_char) {
743 718 * (-- destination->text.p) = '\0';
744 719 }
745 720 } else {
746 721 /*
747 722 * If the command didn't generate any output,
748 723 * set the buffer to a null string.
749 724 */
750 725 *(destination->text.p) = '\0';
751 726 }
752 727
753 728 status = pclose(fd);
754 729 if (status != 0) {
755 730 WCSTOMBS(mbs_buffer, command->buffer.start);
756 731 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 112, "The command `%s' returned status `%d'"),
757 732 mbs_buffer,
758 733 WEXITSTATUS(status));
759 734 }
760 735 }
761 736
762 737
↓ open down ↓ |
155 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX