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