diff options
author | devans <devans@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-12-08 07:05:35 +0000 |
---|---|---|
committer | devans <devans@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-12-08 07:05:35 +0000 |
commit | cfe9fd45f7f8ffa2b6c624f48a22de29160fe0af (patch) | |
tree | 818366a7b979a3e001dd55453648c8702ad52408 /libiberty | |
parent | 070457e75c48625d012edc6a93924770b997dd97 (diff) | |
download | gcc-cfe9fd45f7f8ffa2b6c624f48a22de29160fe0af.tar.gz |
* pex-unix.c (pex_unix_exec_child): Save/restore environ.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155079 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libiberty')
-rw-r--r-- | libiberty/ChangeLog | 4 | ||||
-rw-r--r-- | libiberty/pex-unix.c | 21 |
2 files changed, 24 insertions, 1 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index ddabcd38d22..f8ba8f7909d 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,7 @@ +2009-12-07 Doug Evans <dje@google.com> + + * pex-unix.c (pex_unix_exec_child): Save/restore environ. + 2009-11-26 Ben Elliston <bje@au.ibm.com> * configure.ac (AC_CHECK_FUNCS): Sort into alphabetic order. diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c index 4428f60863f..85733a66923 100644 --- a/libiberty/pex-unix.c +++ b/libiberty/pex-unix.c @@ -400,6 +400,12 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, volatile int sleep_interval; volatile int retries; + /* We vfork and then set environ in the child before calling execvp. + This clobbers the parent's environ so we need to restore it. + It would be nice to use one of the exec* functions that takes an + environment as a parameter, but that may have portability issues. */ + char **save_environ = environ; + sleep_interval = 1; pid = -1; for (retries = 0; retries < 4; ++retries) @@ -453,7 +459,12 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, } if (env) - environ = (char**) env; + { + /* NOTE: In a standard vfork implementation this clobbers the + parent's copy of environ "too" (in reality there's only one copy). + This is ok as we restore it below. */ + environ = (char**) env; + } if ((flags & PEX_SEARCH) != 0) { @@ -471,6 +482,14 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, default: /* Parent process. */ + + /* Restore environ. + Note that the parent either doesn't run until the child execs/exits + (standard vfork behaviour), or if it does run then vfork is behaving + more like fork. In either case we needn't worry about clobbering + the child's copy of environ. */ + environ = save_environ; + if (in != STDIN_FILE_NO) { if (close (in) < 0) |