aboutsummaryrefslogtreecommitdiff
path: root/libiberty
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2009-12-08 07:15:36 +0000
committerDoug Evans <dje@google.com>2009-12-08 07:15:36 +0000
commit16b8170d502e4d6339d466b51ee0d64ee35a1d2b (patch)
tree61e92cafa98713f44a7c56d8b2e47bd095e8f941 /libiberty
parent3281215912fb595a0530d0abe2bffe4513fc8d6b (diff)
downloadfsf-binutils-gdb-16b8170d502e4d6339d466b51ee0d64ee35a1d2b.zip
fsf-binutils-gdb-16b8170d502e4d6339d466b51ee0d64ee35a1d2b.tar.gz
fsf-binutils-gdb-16b8170d502e4d6339d466b51ee0d64ee35a1d2b.tar.bz2
* pex-unix.c (pex_unix_exec_child): Save/restore environ.
Diffstat (limited to 'libiberty')
-rw-r--r--libiberty/ChangeLog4
-rw-r--r--libiberty/pex-unix.c21
2 files changed, 24 insertions, 1 deletions
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 <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 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)