From 7f50c692685c92d47e6ba6c3ee5f6fdccb78fec5 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Fri, 31 Jul 2020 01:17:24 -0400 Subject: Use dict_T to pass env vars to process spawning code Co-authored-by: Matthieu Coudron --- src/nvim/os/pty_process_unix.c | 79 +++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 21 deletions(-) (limited to 'src/nvim/os/pty_process_unix.c') diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index 4d7d9a45df..a3c9e726c5 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -20,6 +20,10 @@ # include #endif +#ifdef __APPLE__ +# include +#endif + #include #include "nvim/lib/klist.h" @@ -151,31 +155,24 @@ void pty_process_teardown(Loop *loop) uv_signal_stop(&loop->children_watcher); } +static const char *ignored_env_vars[] = { + "COLUMNS", + "LINES", + "TERMCAP", + "COLORFGBG" +}; + static void init_child(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL { +#if defined(HAVE__NSGETENVIRON) + char **environ = *_NSGetEnviron(); +#else + extern char **environ; +#endif // New session/process-group. #6530 setsid(); - os_unsetenv("COLUMNS"); - os_unsetenv("LINES"); - os_unsetenv("TERMCAP"); - os_unsetenv("COLORFGBG"); - // setting COLORTERM to "truecolor" if termguicolors is set and 256 - // otherwise, but only if it was set in the parent terminal at all - if (os_env_exists("COLORTERM")) { - const char *colorterm = os_getenv("COLORTERM"); - if (colorterm != NULL) { - if (p_tgc) { - os_setenv("COLORTERM", "truecolor", 1); - } else { - os_setenv("COLORTERM", "256", 1); - } - } else { - os_unsetenv("COLORTERM"); - } - } - signal(SIGCHLD, SIG_DFL); signal(SIGHUP, SIG_DFL); signal(SIGINT, SIG_DFL); @@ -190,9 +187,49 @@ static void init_child(PtyProcess *ptyproc) } char *prog = ptyproc->process.argv[0]; - os_setenv("TERM", ptyproc->term_name ? ptyproc->term_name : "ansi", 1); - execvp(prog, ptyproc->process.argv); + if (proc->env) { + for (size_t i = 0; i < ARRAY_SIZE(ignored_env_vars); i++) { + dictitem_T *dv = tv_dict_find(proc->env, ignored_env_vars[i], -1); + if (dv) { + tv_dict_item_remove(proc->env, dv); + } + } + tv_dict_add_str(proc->env, S_LEN("TERM"), ptyproc->term_name ? ptyproc->term_name : "ansi"); + + // setting COLORTERM to "truecolor" if termguicolors is set and 256 + // otherwise, but only if it was set in the parent terminal at all + dictitem_T *dv = tv_dict_find(proc->env, S_LEN("COLORTERM")); + if (dv) { + tv_dict_item_remove(proc->env, dv); + tv_dict_add_str(proc->env, S_LEN("COLORTERM"), p_tgc ? "truecolor" : "256"); + } + + environ = tv_dict_to_env(proc->env); + } else { + for (size_t i = 0; i < ARRAY_SIZE(ignored_env_vars); i++) { + os_unsetenv(ignored_env_vars[i]); + } + + // setting COLORTERM to "truecolor" if termguicolors is set and 256 + // otherwise, but only if it was set in the parent terminal at all + if (os_env_exists("COLORTERM")) { + const char *colorterm = os_getenv("COLORTERM"); + if (colorterm != NULL) { + if (p_tgc) { + os_setenv("COLORTERM", "truecolor", 1); + } else { + os_setenv("COLORTERM", "256", 1); + } + } else { + os_unsetenv("COLORTERM"); + } + } + + os_setenv("TERM", ptyproc->term_name ? ptyproc->term_name : "ansi", 1); + } + execvp(prog, proc->argv); ELOG("execvp failed: %s: %s", strerror(errno), prog); + _exit(122); // 122 is EXEC_FAILED in the Vim source. } -- cgit From 8eec9c7d5b398918609d8edfed3928e873fa646f Mon Sep 17 00:00:00 2001 From: James McCoy Date: Thu, 10 Sep 2020 07:15:32 -0400 Subject: Common handling of required/ignored env vars When starting a pty job, there are certain env vars that we need to either add or remove. Currently, there are two relevant scenarios. * Removing irrelevant env vars on Unix, mostly related to the terminal hosting nvim since they do not apply to a libvterm-hosted terminal. * Adding required env vars for Windows jobs. --- src/nvim/os/pty_process_unix.c | 50 ++++-------------------------------------- 1 file changed, 4 insertions(+), 46 deletions(-) (limited to 'src/nvim/os/pty_process_unix.c') diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index a3c9e726c5..0733589870 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -155,13 +155,6 @@ void pty_process_teardown(Loop *loop) uv_signal_stop(&loop->children_watcher); } -static const char *ignored_env_vars[] = { - "COLUMNS", - "LINES", - "TERMCAP", - "COLORFGBG" -}; - static void init_child(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL { @@ -187,46 +180,11 @@ static void init_child(PtyProcess *ptyproc) } char *prog = ptyproc->process.argv[0]; - if (proc->env) { - for (size_t i = 0; i < ARRAY_SIZE(ignored_env_vars); i++) { - dictitem_T *dv = tv_dict_find(proc->env, ignored_env_vars[i], -1); - if (dv) { - tv_dict_item_remove(proc->env, dv); - } - } - tv_dict_add_str(proc->env, S_LEN("TERM"), ptyproc->term_name ? ptyproc->term_name : "ansi"); - - // setting COLORTERM to "truecolor" if termguicolors is set and 256 - // otherwise, but only if it was set in the parent terminal at all - dictitem_T *dv = tv_dict_find(proc->env, S_LEN("COLORTERM")); - if (dv) { - tv_dict_item_remove(proc->env, dv); - tv_dict_add_str(proc->env, S_LEN("COLORTERM"), p_tgc ? "truecolor" : "256"); - } - - environ = tv_dict_to_env(proc->env); - } else { - for (size_t i = 0; i < ARRAY_SIZE(ignored_env_vars); i++) { - os_unsetenv(ignored_env_vars[i]); - } - - // setting COLORTERM to "truecolor" if termguicolors is set and 256 - // otherwise, but only if it was set in the parent terminal at all - if (os_env_exists("COLORTERM")) { - const char *colorterm = os_getenv("COLORTERM"); - if (colorterm != NULL) { - if (p_tgc) { - os_setenv("COLORTERM", "truecolor", 1); - } else { - os_setenv("COLORTERM", "256", 1); - } - } else { - os_unsetenv("COLORTERM"); - } - } - os_setenv("TERM", ptyproc->term_name ? ptyproc->term_name : "ansi", 1); - } + assert(proc->env); + tv_dict_add_str(proc->env, S_LEN("TERM"), + ptyproc->term_name ? ptyproc->term_name : "ansi"); + environ = tv_dict_to_env(proc->env); execvp(prog, proc->argv); ELOG("execvp failed: %s: %s", strerror(errno), prog); -- cgit From 035ee868ae2d9cbbf2a290ca3412946fade20833 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sun, 31 Jan 2021 07:49:31 -0500 Subject: fix(pty_proc/macOS): Properly set the environment for the child Binding _NSGetEnviron()'s return value to a local variable and then re-binding that is incorrect. We need to directly update what _NSGetEnviron() refers to. --- src/nvim/os/pty_process_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/os/pty_process_unix.c') diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index 0733589870..348a139e79 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -159,7 +159,7 @@ static void init_child(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL { #if defined(HAVE__NSGETENVIRON) - char **environ = *_NSGetEnviron(); +#define environ (*_NSGetEnviron()) #else extern char **environ; #endif -- cgit