diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/event/libuv_process.c | 20 | ||||
-rw-r--r-- | src/nvim/memory.c | 7 | ||||
-rw-r--r-- | src/nvim/os/env.c | 22 |
3 files changed, 28 insertions, 21 deletions
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index ab69bea04c..f5a41d151b 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -8,7 +8,6 @@ #include "nvim/event/process.h" #include "nvim/event/libuv_process.h" #include "nvim/log.h" -#include "nvim/path.h" #include "nvim/os/os.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -27,22 +26,9 @@ int libuv_process_spawn(LibuvProcess *uvproc) uvproc->uvopts.flags |= UV_PROCESS_DETACHED; } #ifdef WIN32 - // libuv assumes spawned processes follow the convention from - // CommandLineToArgvW(), cmd.exe does not. Disable quoting since it will - // result in unexpected behaviour, the caller is left with the responsibility - // to quote arguments accordingly. system('') has shell* options for this. - // - // Disable quoting for cmd, cmd.exe and $COMSPEC with a cmd.exe filename - bool is_cmd = STRICMP(proc->argv[0], "cmd.exe") == 0 - || STRICMP(proc->argv[0], "cmd") == 0; - if (!is_cmd) { - const char_u *comspec = (char_u *)os_getenv("COMSPEC"); - const char_u *comspecshell = path_tail((char_u *)proc->argv[0]); - is_cmd = comspec != NULL && STRICMP(proc->argv[0], comspec) == 0 - && STRICMP("cmd.exe", (char *)comspecshell) == 0; - } - - if (is_cmd) { + // libuv collapses the argv to a CommandLineToArgvW()-style string. cmd.exe + // expects a different syntax (must be prepared by the caller before now). + if (os_shell_is_cmdexe(proc->argv[0])) { uvproc->uvopts.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; } #endif diff --git a/src/nvim/memory.c b/src/nvim/memory.c index b4fdd86a6d..85ec916ba0 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -495,6 +495,13 @@ bool strequal(const char *a, const char *b) return (a == NULL && b == NULL) || (a && b && strcmp(a, b) == 0); } +/// Case-insensitive `strequal`. +bool striequal(const char *a, const char *b) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + return (a == NULL && b == NULL) || (a && b && STRICMP(a, b) == 0); +} + /* * Avoid repeating the error message many times (they take 1 second each). * Did_outofmem_msg is reset when a character is read. diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 12c2da6152..ad51e598c1 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -1,11 +1,8 @@ -// env.c -- environment variable access +// Environment inspection #include <assert.h> - #include <uv.h> -// vim.h must be included before charset.h (and possibly others) or things -// blow up #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/charset.h" @@ -919,3 +916,20 @@ bool os_term_is_nice(void) || NULL != os_getenv("KONSOLE_DBUS_SESSION"); #endif } + +/// Returns true if `sh` looks like it resolves to "cmd.exe". +bool os_shell_is_cmdexe(const char *sh) + FUNC_ATTR_NONNULL_ALL +{ + if (*sh == NUL) { + return false; + } + if (striequal(sh, "$COMSPEC")) { + const char *comspec = os_getenv("COMSPEC"); + return striequal("cmd.exe", (char *)path_tail((char_u *)comspec)); + } + if (striequal(sh, "cmd.exe") || striequal(sh, "cmd")) { + return true; + } + return striequal("cmd.exe", (char *)path_tail((char_u *)sh)); +} |