aboutsummaryrefslogtreecommitdiffstats
path: root/src/spawn-posix.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2024-10-11 07:17:53 +0000
committerNIIBE Yutaka <[email protected]>2024-10-11 07:29:02 +0000
commit1860f6407f834b681c21f67db7236eaad161524c (patch)
tree81e1fee4007e1b70fad278f9716fd65fcc28a7e4 /src/spawn-posix.c
parentw32: Fix releasing memory for UTF-8 text. (diff)
downloadlibgpg-error-1860f6407f834b681c21f67db7236eaad161524c.tar.gz
libgpg-error-1860f6407f834b681c21f67db7236eaad161524c.zip
spawn: Add new function to modify environment.
* src/gpg-error.def.in (gpgrt_spawn_actions_set_envchange): New. * src/gpg-error.vers (gpgrt_spawn_actions_set_envchange): New. * src/gpg-error.h.in (gpgrt_spawn_actions_set_envchange): New. * src/gpgrt-int.h (_gpgrt_spawn_actions_set_envchange): New. * src/spawn-posix.c (struct gpgrt_spawn_actions): New field ENVCHANGE. (prepare_environ): New. (my_exec): Take care of ENVCHANGE. (_gpgrt_spawn_actions_set_envchange): New. * src/spawn-w32.c (struct gpgrt_spawn_actions): New field ENVCHANGE. (prepare_env_block): New. (_gpgrt_spawn_actions_set_envchange): New. (spawn_detached, _gpgrt_process_spawn): Take care of ENVCHANGE. * src/visibility.c (gpgrt_spawn_actions_set_envchange): New. * src/visibility.h (gpgrt_spawn_actions_set_envchange): New. * tests/Makefile.am (TESTS): Add t-spawn. * tests/t-spawn.c: New. -- GnuPG-bug-id: 7307 Signed-off-by: NIIBE Yutaka <[email protected]>
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)
{