diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-08-29 22:08:53 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-08-29 22:08:53 +0200 |
commit | 48340b62e812dc9280f621a2eb6db76d43555c66 (patch) | |
tree | cdafeefc8f1ac57190fcd2b97f717c84fdd6b658 | |
parent | 97f65fafdbf3530fa42d6e43618e66e14c866b50 (diff) | |
download | vim-git-48340b62e812dc9280f621a2eb6db76d43555c66.tar.gz |
patch 8.0.1012: MS-Windows: problem with $HOME when is was set internallyv8.0.1012
Problem: MS-Windows: Problem with $HOME when is was set internally.
Solution: Only use the $HOME default internally. (Yasuhiro Matsumoto, closes
#2013)
-rw-r--r-- | src/Makefile | 1 | ||||
-rw-r--r-- | src/misc1.c | 68 | ||||
-rw-r--r-- | src/testdir/Make_all.mak | 3 | ||||
-rw-r--r-- | src/testdir/test_windows_home.vim | 124 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 163 insertions, 35 deletions
diff --git a/src/Makefile b/src/Makefile index e4da3b4b6..ecf14bc49 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2278,6 +2278,7 @@ test_arglist \ test_visual \ test_window_cmd \ test_window_id \ + test_windows_home \ test_writefile \ test_alot_latin \ test_alot_utf8 \ diff --git a/src/misc1.c b/src/misc1.c index bd7dcefbe..632571dbe 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -3750,11 +3750,34 @@ init_homedir(void) var = mch_getenv((char_u *)"HOME"); #endif - if (var != NULL && *var == NUL) /* empty is same as not set */ - var = NULL; - #ifdef WIN3264 /* + * Typically, $HOME is not defined on Windows, unless the user has + * specifically defined it for Vim's sake. However, on Windows NT + * platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for + * each user. Try constructing $HOME from these. + */ + if (var == NULL || *var == NULL) + { + char_u *homedrive, *homepath; + + homedrive = mch_getenv((char_u *)"HOMEDRIVE"); + homepath = mch_getenv((char_u *)"HOMEPATH"); + if (homepath == NULL || *homepath == NUL) + homepath = (char_u *)"\\"; + if (homedrive != NULL + && STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL) + { + sprintf((char *)NameBuff, "%s%s", homedrive, homepath); + if (NameBuff[0] != NUL) + var = NameBuff; + } + } + + if (var == NULL) + var = mch_getenv((char_u *)"USERPROFILE"); + + /* * Weird but true: $HOME may contain an indirect reference to another * variable, esp. "%USERPROFILE%". Happens when $USERPROFILE isn't set * when $HOME is being set. @@ -3774,40 +3797,14 @@ init_homedir(void) { vim_snprintf((char *)NameBuff, MAXPATHL, "%s%s", exp, p + 1); var = NameBuff; - /* Also set $HOME, it's needed for _viminfo. */ - vim_setenv((char_u *)"HOME", NameBuff); } } } - /* - * Typically, $HOME is not defined on Windows, unless the user has - * specifically defined it for Vim's sake. However, on Windows NT - * platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for - * each user. Try constructing $HOME from these. - */ - if (var == NULL) - { - char_u *homedrive, *homepath; - - homedrive = mch_getenv((char_u *)"HOMEDRIVE"); - homepath = mch_getenv((char_u *)"HOMEPATH"); - if (homepath == NULL || *homepath == NUL) - homepath = (char_u *)"\\"; - if (homedrive != NULL - && STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL) - { - sprintf((char *)NameBuff, "%s%s", homedrive, homepath); - if (NameBuff[0] != NUL) - { - var = NameBuff; - /* Also set $HOME, it's needed for _viminfo. */ - vim_setenv((char_u *)"HOME", NameBuff); - } - } - } + if (var != NULL && *var == NUL) /* empty is same as not set */ + var = NULL; -# if defined(FEAT_MBYTE) +# ifdef FEAT_MBYTE if (enc_utf8 && var != NULL) { int len; @@ -3823,9 +3820,7 @@ init_homedir(void) } } # endif -#endif -#if defined(MSWIN) /* * Default home dir is C:/ * Best assumption we can make in such a situation. @@ -3833,6 +3828,7 @@ init_homedir(void) if (var == NULL) var = (char_u *)"C:/"; #endif + if (var != NULL) { #ifdef UNIX @@ -4662,6 +4658,10 @@ home_replace( #else homedir_env_orig = homedir_env = mch_getenv((char_u *)"HOME"); #endif +#ifdef WIN3264 + if (homedir_env == NULL) + homedir_env_orig = homedir_env = mch_getenv((char_u *)"USERPROFILE"); +#endif /* Empty is the same as not set. */ if (homedir_env != NULL && *homedir_env == NUL) homedir_env = NULL; diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index 678fc8000..2a267d653 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -205,7 +205,8 @@ NEW_TESTS = test_arabic.res \ test_writefile.res \ test_alot_latin.res \ test_alot_utf8.res \ - test_alot.res + test_alot.res \ + test_windows_home.res # Explicit dependencies. diff --git a/src/testdir/test_windows_home.vim b/src/testdir/test_windows_home.vim new file mode 100644 index 000000000..082f217e1 --- /dev/null +++ b/src/testdir/test_windows_home.vim @@ -0,0 +1,124 @@ +" Test for $HOME on Windows. + +if !has('win32') + finish +endif + +let s:env = {} + +func s:restore_env() + for i in keys(s:env) + exe 'let ' . i . '=s:env["' . i . '"]' + endfor +endfunc + +func s:save_env(...) + for i in a:000 + exe 'let s:env["' . i . '"]=' . i + endfor +endfunc + +func s:unlet_env(...) + for i in a:000 + exe 'let ' . i . '=""' + endfor +endfunc + +func CheckHomeIsMissingFromSubprocessEnvironment() + silent! let out = system('set') + let env = filter(split(out, "\n"), 'v:val=~"^HOME="') + call assert_equal(0, len(env)) +endfunc + +func CheckHomeIsInSubprocessEnvironment(exp) + silent! let out = system('set') + let env = filter(split(out, "\n"), 'v:val=~"^HOME="') + let home = len(env) == 0 ? "" : substitute(env[0], '[^=]\+=', '', '') + call assert_equal(a:exp, home) +endfunc + +func CheckHome(exp, ...) + "call assert_equal(a:exp, $HOME) + "call assert_equal(a:exp, expand('~', ':p')) + if !a:0 + call CheckHomeIsMissingFromSubprocessEnvironment() + else + call CheckHomeIsInSubprocessEnvironment(a:exp) + endif +endfunc + +func TestWindowsHome() + command! -nargs=* SaveEnv call <SID>save_env(<f-args>) + command! -nargs=* RestoreEnv call <SID>restore_env() + command! -nargs=* UnletEnv call <SID>unlet_env(<f-args>) + + SaveEnv $HOME $USERPROFILE $HOMEDRIVE $HOMEPATH + try + RestoreEnv + UnletEnv $HOME $USERPROFILE $HOMEPATH + let $HOMEDRIVE = 'C:' + call CheckHome('C:\') + + RestoreEnv + UnletEnv $HOME $USERPROFILE + let $HOMEDRIVE = 'C:' + let $HOMEPATH = '\foobar' + call CheckHome('C:\foobar') + + RestoreEnv + UnletEnv $HOME $HOMEDRIVE $HOMEPATH + let $USERPROFILE = 'C:\foo' + call CheckHome('C:\foo') + + RestoreEnv + UnletEnv $HOME + let $USERPROFILE = 'C:\foo' + let $HOMEDRIVE = 'C:' + let $HOMEPATH = '\baz' + call CheckHome('C:\foo') + + RestoreEnv + let $HOME = 'C:\bar' + let $USERPROFILE = 'C:\foo' + let $HOMEDRIVE = 'C:' + let $HOMEPATH = '\baz' + call CheckHome('C:\bar', 1) + + RestoreEnv + let $HOME = '%USERPROFILE%\bar' + let $USERPROFILE = 'C:\foo' + let $HOMEDRIVE = 'C:' + let $HOMEPATH = '\baz' + call CheckHome('%USERPROFILE%\bar', 1) + + RestoreEnv + let $HOME = '%USERPROFILE' + let $USERPROFILE = 'C:\foo' + let $HOMEDRIVE = 'C:' + let $HOMEPATH = '\baz' + call CheckHome('%USERPROFILE', 1) + + RestoreEnv + let $HOME = 'C:\%USERPROFILE%' + let $USERPROFILE = 'C:\foo' + let $HOMEDRIVE = 'C:' + let $HOMEPATH = '\baz' + call CheckHome('C:\%USERPROFILE%', 1) + + if has('channel') + RestoreEnv + UnletEnv $HOME + let env = '' + let job = job_start('cmd /c set', {'out_cb': {ch,x->[env,execute('let env=x')]}}) + sleep 1 + let env = filter(split(env, "\n"), 'v:val=="HOME"') + let home = len(env) == 0 ? "" : env[0] + call assert_equal('', home) + endif + finally + RestoreEnv + delcommand SaveEnv + delcommand RestoreEnv + delcommand UnletEnv + endtry +endfunc diff --git a/src/version.c b/src/version.c index 0ef208437..3be91c249 100644 --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1012, +/**/ 1011, /**/ 1010, |