comparison libiberty/pex-unix.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children f6334be47118
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
1 /* Utilities to execute a program in a subprocess (possibly linked by pipes 1 /* Utilities to execute a program in a subprocess (possibly linked by pipes
2 with other subprocesses), and wait for it. Generic Unix version 2 with other subprocesses), and wait for it. Generic Unix version
3 (also used for UWIN and VMS). 3 (also used for UWIN and VMS).
4 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 4 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2009
5 Free Software Foundation, Inc. 5 Free Software Foundation, Inc.
6 6
7 This file is part of the libiberty library. 7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or 8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public 9 modify it under the terms of the GNU Library General Public
63 # define VFORK_STRING "vfork" 63 # define VFORK_STRING "vfork"
64 #endif 64 #endif
65 #ifdef HAVE_VFORK_H 65 #ifdef HAVE_VFORK_H
66 #include <vfork.h> 66 #include <vfork.h>
67 #endif 67 #endif
68 #ifdef VMS 68 #if defined(VMS) && defined (__LONG_POINTERS)
69 #define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ 69 #ifndef __CHAR_PTR32
70 lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) 70 typedef char * __char_ptr32
71 #endif /* VMS */ 71 __attribute__ ((mode (SI)));
72 72 #endif
73
74 typedef __char_ptr32 *__char_ptr_char_ptr32
75 __attribute__ ((mode (SI)));
76
77 /* Return a 32 bit pointer to an array of 32 bit pointers
78 given a 64 bit pointer to an array of 64 bit pointers. */
79
80 static __char_ptr_char_ptr32
81 to_ptr32 (char **ptr64)
82 {
83 int argc;
84 __char_ptr_char_ptr32 short_argv;
85
86 for (argc=0; ptr64[argc]; argc++);
87
88 /* Reallocate argv with 32 bit pointers. */
89 short_argv = (__char_ptr_char_ptr32) decc$malloc
90 (sizeof (__char_ptr32) * (argc + 1));
91
92 for (argc=0; ptr64[argc]; argc++)
93 short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]);
94
95 short_argv[argc] = (__char_ptr32) 0;
96 return short_argv;
97
98 }
99 #else
100 #define to_ptr32(argv) argv
101 #endif
73 102
74 /* File mode to use for private and world-readable files. */ 103 /* File mode to use for private and world-readable files. */
75 104
76 #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH) 105 #if defined (S_IRUSR) && defined (S_IWUSR) && defined (S_IRGRP) && defined (S_IWGRP) && defined (S_IROTH) && defined (S_IWOTH)
77 #define PUBLIC_MODE \ 106 #define PUBLIC_MODE \
337 366
338 static void 367 static void
339 pex_child_error (struct pex_obj *obj, const char *executable, 368 pex_child_error (struct pex_obj *obj, const char *executable,
340 const char *errmsg, int err) 369 const char *errmsg, int err)
341 { 370 {
342 #define writeerr(s) (void) write (STDERR_FILE_NO, s, strlen (s)) 371 int retval = 0;
372 #define writeerr(s) retval |= (write (STDERR_FILE_NO, s, strlen (s)) < 0)
343 writeerr (obj->pname); 373 writeerr (obj->pname);
344 writeerr (": error trying to exec '"); 374 writeerr (": error trying to exec '");
345 writeerr (executable); 375 writeerr (executable);
346 writeerr ("': "); 376 writeerr ("': ");
347 writeerr (errmsg); 377 writeerr (errmsg);
348 writeerr (": "); 378 writeerr (": ");
349 writeerr (xstrerror (err)); 379 writeerr (xstrerror (err));
350 writeerr ("\n"); 380 writeerr ("\n");
351 _exit (-1); 381 #undef writeerr
382 /* Exit with -2 if the error output failed, too. */
383 _exit (retval == 0 ? -1 : -2);
352 } 384 }
353 385
354 /* Execute a child. */ 386 /* Execute a child. */
355 387
356 extern char **environ; 388 extern char **environ;
366 /* We declare these to be volatile to avoid warnings from gcc about 398 /* We declare these to be volatile to avoid warnings from gcc about
367 them being clobbered by vfork. */ 399 them being clobbered by vfork. */
368 volatile int sleep_interval; 400 volatile int sleep_interval;
369 volatile int retries; 401 volatile int retries;
370 402
403 /* We vfork and then set environ in the child before calling execvp.
404 This clobbers the parent's environ so we need to restore it.
405 It would be nice to use one of the exec* functions that takes an
406 environment as a parameter, but that may have portability issues. */
407 char **save_environ = environ;
408
371 sleep_interval = 1; 409 sleep_interval = 1;
372 pid = -1; 410 pid = -1;
373 for (retries = 0; retries < 4; ++retries) 411 for (retries = 0; retries < 4; ++retries)
374 { 412 {
375 pid = vfork (); 413 pid = vfork ();
419 if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0) 457 if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
420 pex_child_error (obj, executable, "dup2", errno); 458 pex_child_error (obj, executable, "dup2", errno);
421 } 459 }
422 460
423 if (env) 461 if (env)
424 environ = (char**) env; 462 {
463 /* NOTE: In a standard vfork implementation this clobbers the
464 parent's copy of environ "too" (in reality there's only one copy).
465 This is ok as we restore it below. */
466 environ = (char**) env;
467 }
425 468
426 if ((flags & PEX_SEARCH) != 0) 469 if ((flags & PEX_SEARCH) != 0)
427 { 470 {
428 execvp (executable, argv); 471 execvp (executable, to_ptr32 (argv));
429 pex_child_error (obj, executable, "execvp", errno); 472 pex_child_error (obj, executable, "execvp", errno);
430 } 473 }
431 else 474 else
432 { 475 {
433 execv (executable, argv); 476 execv (executable, to_ptr32 (argv));
434 pex_child_error (obj, executable, "execv", errno); 477 pex_child_error (obj, executable, "execv", errno);
435 } 478 }
436 479
437 /* NOTREACHED */ 480 /* NOTREACHED */
438 return (pid_t) -1; 481 return (pid_t) -1;
439 482
440 default: 483 default:
441 /* Parent process. */ 484 /* Parent process. */
485
486 /* Restore environ.
487 Note that the parent either doesn't run until the child execs/exits
488 (standard vfork behaviour), or if it does run then vfork is behaving
489 more like fork. In either case we needn't worry about clobbering
490 the child's copy of environ. */
491 environ = save_environ;
492
442 if (in != STDIN_FILE_NO) 493 if (in != STDIN_FILE_NO)
443 { 494 {
444 if (close (in) < 0) 495 if (close (in) < 0)
445 { 496 {
446 *err = errno; 497 *err = errno;