Skip to content

Commit 48340b6

Browse files
committed
patch 8.0.1012: MS-Windows: problem with $HOME when is was set internally
Problem: MS-Windows: Problem with $HOME when is was set internally. Solution: Only use the $HOME default internally. (Yasuhiro Matsumoto, closes #2013)
1 parent 97f65fa commit 48340b6

5 files changed

Lines changed: 163 additions & 35 deletions

File tree

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,6 +2278,7 @@ test_arglist \
22782278
test_visual \
22792279
test_window_cmd \
22802280
test_window_id \
2281+
test_windows_home \
22812282
test_writefile \
22822283
test_alot_latin \
22832284
test_alot_utf8 \

src/misc1.c

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3750,10 +3750,33 @@ init_homedir(void)
37503750
var = mch_getenv((char_u *)"HOME");
37513751
#endif
37523752

3753-
if (var != NULL && *var == NUL) /* empty is same as not set */
3754-
var = NULL;
3755-
37563753
#ifdef WIN3264
3754+
/*
3755+
* Typically, $HOME is not defined on Windows, unless the user has
3756+
* specifically defined it for Vim's sake. However, on Windows NT
3757+
* platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
3758+
* each user. Try constructing $HOME from these.
3759+
*/
3760+
if (var == NULL || *var == NULL)
3761+
{
3762+
char_u *homedrive, *homepath;
3763+
3764+
homedrive = mch_getenv((char_u *)"HOMEDRIVE");
3765+
homepath = mch_getenv((char_u *)"HOMEPATH");
3766+
if (homepath == NULL || *homepath == NUL)
3767+
homepath = (char_u *)"\\";
3768+
if (homedrive != NULL
3769+
&& STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
3770+
{
3771+
sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
3772+
if (NameBuff[0] != NUL)
3773+
var = NameBuff;
3774+
}
3775+
}
3776+
3777+
if (var == NULL)
3778+
var = mch_getenv((char_u *)"USERPROFILE");
3779+
37573780
/*
37583781
* Weird but true: $HOME may contain an indirect reference to another
37593782
* variable, esp. "%USERPROFILE%". Happens when $USERPROFILE isn't set
@@ -3774,40 +3797,14 @@ init_homedir(void)
37743797
{
37753798
vim_snprintf((char *)NameBuff, MAXPATHL, "%s%s", exp, p + 1);
37763799
var = NameBuff;
3777-
/* Also set $HOME, it's needed for _viminfo. */
3778-
vim_setenv((char_u *)"HOME", NameBuff);
37793800
}
37803801
}
37813802
}
37823803

3783-
/*
3784-
* Typically, $HOME is not defined on Windows, unless the user has
3785-
* specifically defined it for Vim's sake. However, on Windows NT
3786-
* platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
3787-
* each user. Try constructing $HOME from these.
3788-
*/
3789-
if (var == NULL)
3790-
{
3791-
char_u *homedrive, *homepath;
3792-
3793-
homedrive = mch_getenv((char_u *)"HOMEDRIVE");
3794-
homepath = mch_getenv((char_u *)"HOMEPATH");
3795-
if (homepath == NULL || *homepath == NUL)
3796-
homepath = (char_u *)"\\";
3797-
if (homedrive != NULL
3798-
&& STRLEN(homedrive) + STRLEN(homepath) < MAXPATHL)
3799-
{
3800-
sprintf((char *)NameBuff, "%s%s", homedrive, homepath);
3801-
if (NameBuff[0] != NUL)
3802-
{
3803-
var = NameBuff;
3804-
/* Also set $HOME, it's needed for _viminfo. */
3805-
vim_setenv((char_u *)"HOME", NameBuff);
3806-
}
3807-
}
3808-
}
3804+
if (var != NULL && *var == NUL) /* empty is same as not set */
3805+
var = NULL;
38093806

3810-
# if defined(FEAT_MBYTE)
3807+
# ifdef FEAT_MBYTE
38113808
if (enc_utf8 && var != NULL)
38123809
{
38133810
int len;
@@ -3823,16 +3820,15 @@ init_homedir(void)
38233820
}
38243821
}
38253822
# endif
3826-
#endif
38273823

3828-
#if defined(MSWIN)
38293824
/*
38303825
* Default home dir is C:/
38313826
* Best assumption we can make in such a situation.
38323827
*/
38333828
if (var == NULL)
38343829
var = (char_u *)"C:/";
38353830
#endif
3831+
38363832
if (var != NULL)
38373833
{
38383834
#ifdef UNIX
@@ -4661,6 +4657,10 @@ home_replace(
46614657
homedir_env_orig = homedir_env = mch_getenv((char_u *)"SYS$LOGIN");
46624658
#else
46634659
homedir_env_orig = homedir_env = mch_getenv((char_u *)"HOME");
4660+
#endif
4661+
#ifdef WIN3264
4662+
if (homedir_env == NULL)
4663+
homedir_env_orig = homedir_env = mch_getenv((char_u *)"USERPROFILE");
46644664
#endif
46654665
/* Empty is the same as not set. */
46664666
if (homedir_env != NULL && *homedir_env == NUL)

src/testdir/Make_all.mak

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ NEW_TESTS = test_arabic.res \
205205
test_writefile.res \
206206
test_alot_latin.res \
207207
test_alot_utf8.res \
208-
test_alot.res
208+
test_alot.res \
209+
test_windows_home.res
209210

210211

211212
# Explicit dependencies.

src/testdir/test_windows_home.vim

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
" Test for $HOME on Windows.
2+
3+
if !has('win32')
4+
finish
5+
endif
6+
7+
let s:env = {}
8+
9+
func s:restore_env()
10+
for i in keys(s:env)
11+
exe 'let ' . i . '=s:env["' . i . '"]'
12+
endfor
13+
endfunc
14+
15+
func s:save_env(...)
16+
for i in a:000
17+
exe 'let s:env["' . i . '"]=' . i
18+
endfor
19+
endfunc
20+
21+
func s:unlet_env(...)
22+
for i in a:000
23+
exe 'let ' . i . '=""'
24+
endfor
25+
endfunc
26+
27+
func CheckHomeIsMissingFromSubprocessEnvironment()
28+
silent! let out = system('set')
29+
let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
30+
call assert_equal(0, len(env))
31+
endfunc
32+
33+
func CheckHomeIsInSubprocessEnvironment(exp)
34+
silent! let out = system('set')
35+
let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
36+
let home = len(env) == 0 ? "" : substitute(env[0], '[^=]\+=', '', '')
37+
call assert_equal(a:exp, home)
38+
endfunc
39+
40+
func CheckHome(exp, ...)
41+
"call assert_equal(a:exp, $HOME)
42+
"call assert_equal(a:exp, expand('~', ':p'))
43+
if !a:0
44+
call CheckHomeIsMissingFromSubprocessEnvironment()
45+
else
46+
call CheckHomeIsInSubprocessEnvironment(a:exp)
47+
endif
48+
endfunc
49+
50+
func TestWindowsHome()
51+
command! -nargs=* SaveEnv call <SID>save_env(<f-args>)
52+
command! -nargs=* RestoreEnv call <SID>restore_env()
53+
command! -nargs=* UnletEnv call <SID>unlet_env(<f-args>)
54+
55+
SaveEnv $HOME $USERPROFILE $HOMEDRIVE $HOMEPATH
56+
try
57+
RestoreEnv
58+
UnletEnv $HOME $USERPROFILE $HOMEPATH
59+
let $HOMEDRIVE = 'C:'
60+
call CheckHome('C:\')
61+
62+
RestoreEnv
63+
UnletEnv $HOME $USERPROFILE
64+
let $HOMEDRIVE = 'C:'
65+
let $HOMEPATH = '\foobar'
66+
call CheckHome('C:\foobar')
67+
68+
RestoreEnv
69+
UnletEnv $HOME $HOMEDRIVE $HOMEPATH
70+
let $USERPROFILE = 'C:\foo'
71+
call CheckHome('C:\foo')
72+
73+
RestoreEnv
74+
UnletEnv $HOME
75+
let $USERPROFILE = 'C:\foo'
76+
let $HOMEDRIVE = 'C:'
77+
let $HOMEPATH = '\baz'
78+
call CheckHome('C:\foo')
79+
80+
RestoreEnv
81+
let $HOME = 'C:\bar'
82+
let $USERPROFILE = 'C:\foo'
83+
let $HOMEDRIVE = 'C:'
84+
let $HOMEPATH = '\baz'
85+
call CheckHome('C:\bar', 1)
86+
87+
RestoreEnv
88+
let $HOME = '%USERPROFILE%\bar'
89+
let $USERPROFILE = 'C:\foo'
90+
let $HOMEDRIVE = 'C:'
91+
let $HOMEPATH = '\baz'
92+
call CheckHome('%USERPROFILE%\bar', 1)
93+
94+
RestoreEnv
95+
let $HOME = '%USERPROFILE'
96+
let $USERPROFILE = 'C:\foo'
97+
let $HOMEDRIVE = 'C:'
98+
let $HOMEPATH = '\baz'
99+
call CheckHome('%USERPROFILE', 1)
100+
101+
RestoreEnv
102+
let $HOME = 'C:\%USERPROFILE%'
103+
let $USERPROFILE = 'C:\foo'
104+
let $HOMEDRIVE = 'C:'
105+
let $HOMEPATH = '\baz'
106+
call CheckHome('C:\%USERPROFILE%', 1)
107+
108+
if has('channel')
109+
RestoreEnv
110+
UnletEnv $HOME
111+
let env = ''
112+
let job = job_start('cmd /c set', {'out_cb': {ch,x->[env,execute('let env=x')]}})
113+
sleep 1
114+
let env = filter(split(env, "\n"), 'v:val=="HOME"')
115+
let home = len(env) == 0 ? "" : env[0]
116+
call assert_equal('', home)
117+
endif
118+
finally
119+
RestoreEnv
120+
delcommand SaveEnv
121+
delcommand RestoreEnv
122+
delcommand UnletEnv
123+
endtry
124+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
1012,
772774
/**/
773775
1011,
774776
/**/

0 commit comments

Comments
 (0)