summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-08-29 22:08:53 +0200
committerBram Moolenaar <Bram@vim.org>2017-08-29 22:08:53 +0200
commit48340b62e812dc9280f621a2eb6db76d43555c66 (patch)
treecdafeefc8f1ac57190fcd2b97f717c84fdd6b658
parent97f65fafdbf3530fa42d6e43618e66e14c866b50 (diff)
downloadvim-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/Makefile1
-rw-r--r--src/misc1.c68
-rw-r--r--src/testdir/Make_all.mak3
-rw-r--r--src/testdir/test_windows_home.vim124
-rw-r--r--src/version.c2
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,