aboutsummaryrefslogtreecommitdiffstats
path: root/src/spawn-posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/spawn-posix.c')
-rw-r--r--src/spawn-posix.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/src/spawn-posix.c b/src/spawn-posix.c
index 9787ec1..4bb90ca 100644
--- a/src/spawn-posix.c
+++ b/src/spawn-posix.c
@@ -57,9 +57,6 @@
#include "gpgrt-int.h"
-/* (Only glibc's unistd.h declares this iff _GNU_SOURCE is used.) */
-extern char **environ;
-
/* Definition for the gpgrt_spawn_actions_t. Note that there is a
* different one for Windows. */
@@ -67,6 +64,7 @@ struct gpgrt_spawn_actions {
int fd[3];
const int *except_fds;
char **environ;
+ const char *const *envchange;
void (*atfork) (void *);
void *atfork_arg;
};
@@ -318,6 +316,31 @@ posix_open_null (int for_write)
}
+static gpg_err_code_t
+prepare_environ (const char *const *envchange)
+{
+ const char *const *envp;
+ const char *e;
+
+ for (envp = envchange; (e = *envp); envp++)
+ {
+ char *name = xtrystrdup (e);
+ char *p;
+
+ if (!name)
+ return _gpg_err_code_from_syserror ();
+
+ p = strchr (name, '=');
+ if (p)
+ *p++ = 0;
+
+ _gpgrt_setenv (name, p, 1);
+ xfree (name);
+ }
+
+ return 0;
+}
+
static int
my_exec (const char *pgmname, const char *argv[], gpgrt_spawn_actions_t act)
{
@@ -345,8 +368,8 @@ my_exec (const char *pgmname, const char *argv[], gpgrt_spawn_actions_t act)
/* Close all other files. */
_gpgrt_close_all_fds (3, act->except_fds);
- if (act->environ)
- environ = act->environ;
+ if (act->envchange && prepare_environ (act->envchange))
+ goto leave;
if (act->atfork)
act->atfork (act->atfork_arg);
@@ -355,8 +378,13 @@ my_exec (const char *pgmname, const char *argv[], gpgrt_spawn_actions_t act)
if (pgmname == NULL)
return 0;
- execv (pgmname, (char *const *)argv);
+ if (act->environ)
+ execve (pgmname, (char *const *)argv, act->environ);
+ else
+ execv (pgmname, (char *const *)argv);
+
/* No way to print anything, as we have may have closed all streams. */
+ leave:
_exit (127);
return -1;
}
@@ -456,6 +484,13 @@ _gpgrt_spawn_actions_set_environ (gpgrt_spawn_actions_t act,
}
void
+_gpgrt_spawn_actions_set_envchange (gpgrt_spawn_actions_t act,
+ const char *const *envchange)
+{
+ act->envchange = envchange;
+}
+
+void
_gpgrt_spawn_actions_set_atfork (gpgrt_spawn_actions_t act,
void (*atfork)(void *), void *arg)
{