Skip to content

Commit fe46171

Browse files
committed
POSIX-ify the SHELL variable
When calling a non-MSys2 binary, all of the environment is converted from POSIX to Win32, including the SHELL environment variable. In Git for Windows, for example, `SHELL=/usr/bin/bash` is converted to `SHELL=C:\Program Files\Git\usr\bin\bash.exe` when calling the `git.exe` binary. This is appropriate because non-MSys2 binaries would not handle POSIX paths correctly. Under certain circumstances, however, `git.exe` calls an *MSys2* binary in turn, such as `git config --edit` calling `vim.exe` unless Git is configured to use another editor specifically. Now, when this "improved vi" calls shell commands, it uses that $SHELL variable *without quoting*, resulting in a nasty error: C:\Program: No such file or directory Many other programs behave in the same manner, assuming that $SHELL does not contain spaces and hence needs no quoting, unfortunately including some of Git's own scripts. Therefore let's make sure that $SHELL gets "posified" again when entering MSys2 programs. Earlier attempts by Git for Windows contributors claimed that adding `SHELL` to the `conv_envvars` array does not have the intended effect. These reports just missed that the `conv_start_chars` array (which makes the code more performant) needs to be adjusted, too. Note that we set the `immediate` flag to `true` so that the environment variable is set immediately by the MSys2 runtime, i.e. not only spawned processes will see the POSIX-ified `SHELL` variable, but the MSys2 runtime *itself*, too. This fixes git-for-windows/git#542, git-for-windows/git#498, and git-for-windows/git#468. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent f6b74e2 commit fe46171

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

winsup/cygwin/environ.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ static win_env conv_envvars[] =
323323
{NL ("HOME="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
324324
{NL ("LD_LIBRARY_PATH="), NULL, NULL,
325325
env_plist_to_posix, env_plist_to_win32, true},
326+
{NL ("SHELL="), NULL, NULL, env_path_to_posix, env_path_to_win32, true, true},
326327
{NL ("TMPDIR="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
327328
{NL ("TMP="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
328329
{NL ("TEMP="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
@@ -351,7 +352,7 @@ static const unsigned char conv_start_chars[256] =
351352
WC, 0, 0, 0, WC, 0, 0, 0,
352353
/* 80 */
353354
/* P Q R S T U V W */
354-
WC, 0, 0, 0, WC, 0, 0, 0,
355+
WC, 0, 0, WC, WC, 0, 0, 0,
355356
/* 88 */
356357
/* x Y Z */
357358
0, 0, 0, 0, 0, 0, 0, 0,
@@ -380,6 +381,7 @@ win_env::operator = (struct win_env& x)
380381
toposix = x.toposix;
381382
towin32 = x.towin32;
382383
immediate = false;
384+
skip_if_empty = x.skip_if_empty;
383385
return *this;
384386
}
385387

@@ -401,6 +403,8 @@ win_env::add_cache (const char *in_posix, const char *in_native)
401403
native = (char *) realloc (native, namelen + 1 + strlen (in_native));
402404
stpcpy (stpcpy (native, name), in_native);
403405
}
406+
else if (skip_if_empty && !*in_posix)
407+
native = (char *) calloc(1, 1);
404408
else
405409
{
406410
tmp_pathbuf tp;
@@ -466,6 +470,8 @@ posify_maybe (char **here, const char *value, char *outenv)
466470
return;
467471

468472
int len = strcspn (src, "=") + 1;
473+
if (conv->skip_if_empty && !src[len])
474+
return;
469475

470476
/* Turn all the items from c:<foo>;<bar> into their
471477
mounted equivalents - if there is one. */

winsup/cygwin/local_includes/environ.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct win_env
2121
char *native;
2222
ssize_t (*toposix) (const void *, void *, size_t);
2323
ssize_t (*towin32) (const void *, void *, size_t);
24-
bool immediate;
24+
bool immediate, skip_if_empty;
2525
void add_cache (const char *in_posix, const char *in_native = NULL);
2626
const char * get_native () const {return native ? native + namelen : NULL;}
2727
const char * get_posix () const {return posix ? posix : NULL;}

0 commit comments

Comments
 (0)