From: Doug Evans Date: Tue, 8 Dec 2009 07:15:36 +0000 (+0000) Subject: * pex-unix.c (pex_unix_exec_child): Save/restore environ. X-Git-Tag: cgen-snapshot-20100101~99 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=16b8170d502e4d6339d466b51ee0d64ee35a1d2b;p=external%2Fbinutils.git * pex-unix.c (pex_unix_exec_child): Save/restore environ. --- 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)