From cfe9fd45f7f8ffa2b6c624f48a22de29160fe0af Mon Sep 17 00:00:00 2001 From: devans Date: Tue, 8 Dec 2009 07:05:35 +0000 Subject: [PATCH] * 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 --- libiberty/ChangeLog | 4 ++++ libiberty/pex-unix.c | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index ddabcd3..f8ba8f7 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,7 @@ +2009-12-07 Doug Evans + + * pex-unix.c (pex_unix_exec_child): Save/restore environ. + 2009-11-26 Ben Elliston * configure.ac (AC_CHECK_FUNCS): Sort into alphabetic order. diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c index 4428f60..85733a6 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) -- 2.7.4