client: add -E,--client-environment

When this option is used, the child process in the new terminal
instance will inherit its environment from the footclient process,
instead of the foot server’s.

Implemented by sending (yet another) dynamic string list as part of
the client -> server setup packet. When the new option is *not* used,
the setup packet is now 2 bytes larger than before.

On the server side, the slave process now uses execvpe() instead of
execvp(). There’s plumbing to propagate a new ‘envp’ argument from
term_init() all the way down to slave_exec(). If ‘envp’ is NULL, we
use ‘environ’ instead (thus matching the old behavior of execvp()).

Closes #1004
This commit is contained in:
Daniel Eklöf 2022-04-11 12:19:40 +02:00
parent 856086bbbe
commit d02124902b
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
9 changed files with 100 additions and 39 deletions

13
slave.c
View file

@ -145,8 +145,8 @@ emit_notifications(int fd, const user_notifications_t *notifications)
}
static noreturn void
slave_exec(int ptmx, char *argv[], int err_fd, bool login_shell,
const user_notifications_t *notifications)
slave_exec(int ptmx, char *argv[], char *const envp[], int err_fd,
bool login_shell, const user_notifications_t *notifications)
{
int pts = -1;
const char *pts_name = ptsname(ptmx);
@ -232,7 +232,7 @@ slave_exec(int ptmx, char *argv[], int err_fd, bool login_shell,
} else
file = argv[0];
execvp(file, argv);
execvpe(file, argv, envp);
err:
(void)!write(err_fd, &errno, sizeof(errno));
@ -246,8 +246,8 @@ err:
pid_t
slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv,
const char *term_env, const char *conf_shell, bool login_shell,
const user_notifications_t *notifications)
char *const *envp, const char *term_env, const char *conf_shell,
bool login_shell, const user_notifications_t *notifications)
{
int fork_pipe[2];
if (pipe2(fork_pipe, O_CLOEXEC) < 0) {
@ -319,7 +319,8 @@ slave_spawn(int ptmx, int argc, const char *cwd, char *const *argv,
if (is_valid_shell(shell_argv[0]))
setenv("SHELL", shell_argv[0], 1);
slave_exec(ptmx, shell_argv, fork_pipe[1], login_shell, notifications);
slave_exec(ptmx, shell_argv, envp != NULL ? envp : environ,
fork_pipe[1], login_shell, notifications);
BUG("Unexpected return from slave_exec()");
break;