Windows: Remove compatibility to ancient MSVCRT API

Using _wputenv_s simplifies the code and we can avoid code duplication by using rb_w32_home_dir() to initialize ENV['HOME'].
This commit is contained in:
Lars Kanis 2023-10-27 12:30:51 +02:00 committed by Hiroshi SHIBATA
parent 79e79afee4
commit 0641845a4b
Notes: git 2024-09-24 05:07:10 +00:00
2 changed files with 17 additions and 49 deletions

View File

@ -332,7 +332,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
if (!IS_ABSOLUTE_PATH_P(whome, whome_len)) { if (!IS_ABSOLUTE_PATH_P(whome, whome_len)) {
free(wpath); free(wpath);
xfree(whome); free(whome);
rb_raise(rb_eArgError, "non-absolute home"); rb_raise(rb_eArgError, "non-absolute home");
} }
@ -411,7 +411,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
if (!IS_ABSOLUTE_PATH_P(whome, whome_len)) { if (!IS_ABSOLUTE_PATH_P(whome, whome_len)) {
free(wpath); free(wpath);
free(wdir); free(wdir);
xfree(whome); free(whome);
rb_raise(rb_eArgError, "non-absolute home"); rb_raise(rb_eArgError, "non-absolute home");
} }
@ -572,7 +572,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
xfree(buffer); xfree(buffer);
free(wpath); free(wpath);
free(wdir); free(wdir);
xfree(whome); free(whome);
if (wfullpath != wfullpath_buffer) if (wfullpath != wfullpath_buffer)
xfree(wfullpath); xfree(wfullpath);

View File

@ -559,8 +559,9 @@ rb_w32_home_dir(void)
} }
} }
/* allocate buffer */ /* can't use xmalloc here, since it's called too early from init_env() */
buffer = ALLOC_N(WCHAR, buffer_len); buffer = malloc(sizeof(WCHAR) * buffer_len);
if (buffer == NULL) return NULL;
switch (home_type) { switch (home_type) {
case ENV_HOME: case ENV_HOME:
@ -576,10 +577,10 @@ rb_w32_home_dir(void)
default: default:
if (!get_special_folder(CSIDL_PROFILE, buffer, buffer_len) && if (!get_special_folder(CSIDL_PROFILE, buffer, buffer_len) &&
!get_special_folder(CSIDL_PERSONAL, buffer, buffer_len)) { !get_special_folder(CSIDL_PERSONAL, buffer, buffer_len)) {
xfree(buffer); free(buffer);
return NULL; return NULL;
} }
REALLOC_N(buffer, WCHAR, lstrlenW(buffer) + 1); buffer = realloc(buffer, sizeof(WCHAR) * (lstrlenW(buffer) + 1));
break; break;
} }
@ -593,54 +594,24 @@ rb_w32_home_dir(void)
static void static void
init_env(void) init_env(void)
{ {
static const WCHAR TMPDIR[] = L"TMPDIR"; WCHAR env[ENV_MAX];
struct {WCHAR name[6], eq, val[ENV_MAX];} wk;
DWORD len;
BOOL f;
#define env wk.val
#define set_env_val(vname) do { \
typedef char wk_name_offset[(numberof(wk.name) - (numberof(vname) - 1)) * 2 + 1]; \
WCHAR *const buf = wk.name + sizeof(wk_name_offset) / 2; \
MEMCPY(buf, vname, WCHAR, numberof(vname) - 1); \
_wputenv(buf); \
} while (0)
wk.eq = L'=';
if (!GetEnvironmentVariableW(L"HOME", env, numberof(env))) { if (!GetEnvironmentVariableW(L"HOME", env, numberof(env))) {
f = FALSE; WCHAR *whome = rb_w32_home_dir();
if (GetEnvironmentVariableW(L"USERPROFILE", env, numberof(env))) { if (whome) {
f = TRUE; _wputenv_s(L"HOME", whome);
} free(whome);
else {
if (GetEnvironmentVariableW(L"HOMEDRIVE", env, numberof(env)))
len = lstrlenW(env);
else
len = 0;
if (GetEnvironmentVariableW(L"HOMEPATH", env + len, numberof(env) - len) || len) {
f = TRUE;
}
else if (get_special_folder(CSIDL_PROFILE, env, numberof(env))) {
f = TRUE;
}
else if (get_special_folder(CSIDL_PERSONAL, env, numberof(env))) {
f = TRUE;
}
}
if (f) {
regulate_path(env);
set_env_val(L"HOME");
} }
} }
if (!GetEnvironmentVariableW(L"USER", env, numberof(env))) { if (!GetEnvironmentVariableW(L"USER", env, numberof(env))) {
DWORD len;
if (!GetEnvironmentVariableW(L"USERNAME", env, numberof(env)) && if (!GetEnvironmentVariableW(L"USERNAME", env, numberof(env)) &&
!GetUserNameW(env, (len = numberof(env), &len))) { !GetUserNameW(env, (len = numberof(env), &len))) {
NTLoginName = "<Unknown>"; NTLoginName = "<Unknown>";
} }
else { else {
set_env_val(L"USER"); _wputenv_s(L"USER", env);
NTLoginName = rb_w32_wstr_to_mbstr(CP_UTF8, env, -1, NULL); NTLoginName = rb_w32_wstr_to_mbstr(CP_UTF8, env, -1, NULL);
} }
} }
@ -648,15 +619,12 @@ init_env(void)
NTLoginName = rb_w32_wstr_to_mbstr(CP_UTF8, env, -1, NULL); NTLoginName = rb_w32_wstr_to_mbstr(CP_UTF8, env, -1, NULL);
} }
if (!GetEnvironmentVariableW(TMPDIR, env, numberof(env)) && if (!GetEnvironmentVariableW(L"TMPDIR", env, numberof(env)) &&
!GetEnvironmentVariableW(L"TMP", env, numberof(env)) && !GetEnvironmentVariableW(L"TMP", env, numberof(env)) &&
!GetEnvironmentVariableW(L"TEMP", env, numberof(env)) && !GetEnvironmentVariableW(L"TEMP", env, numberof(env)) &&
rb_w32_system_tmpdir(env, numberof(env))) { rb_w32_system_tmpdir(env, numberof(env))) {
set_env_val(TMPDIR); _wputenv_s(L"TMPDIR", env);
} }
#undef env
#undef set_env_val
} }
static void init_stdhandle(void); static void init_stdhandle(void);