https://bugs.winehq.org/show_bug.cgi?id=50553
Bug ID: 50553 Summary: SetEnvironmentVariableW function sets last error on deleting non-existent variable Product: Wine Version: 6.0 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: kernel32 Assignee: wine-bugs@winehq.org Reporter: topin89@mail.ru Distribution: ---
This code
``` //gcc test.c -o test.exe && ./test.exe #include <windows.h> #include <stdio.h>
int main(int argc, char *argv[]){ BOOL result;
result = SetEnvironmentVariableW(L"PERL5LIB", NULL); printf("result: %u, last error: %d\n", result, GetLastError()); SetLastError(0);
result = SetEnvironmentVariableW(L"PERL5LIB", "SomeValue"); printf("result: %u, last error: %d\n", result, GetLastError()); SetLastError(0);
result = SetEnvironmentVariableW(L"PERL5LIB", NULL); printf("result: %u, last error: %d\n", result, GetLastError()); SetLastError(0);
result = SetEnvironmentVariableW(L"PERL5LIB", NULL); printf("result: %u, last error: %d\n", result, GetLastError()); SetLastError(0);
return 0; } ```
compiled with Mingw-w64 gcc and running from command line and MSYS console gives this in Windows 10:
``` result: 1, last error: 0 result: 1, last error: 0 result: 1, last error: 0 result: 1, last error: 0 ```
and this in Kubuntu 20.04.1 with winehq-staging 6.0:
``` <snip fixmes> result: 0, last error: 203 result: 1, last error: 0 result: 1, last error: 0 result: 0, last error: 203 ```
Error 203 is ERROR_ENVVAR_NOT_FOUND, btw. So, in Win 10 deleting already deleted environmental variable doesn't lead to error, in Wine it is.
This alone prevents git.exe (and probably many more apps) to work correctly. In file git-for-windows-repo/compat/mingw.c
there is this function,
``` int mingw_putenv(const char *namevalue) { int size; wchar_t *wide, *equal; BOOL result;
if (!namevalue || !*namevalue) return 0;
size = strlen(namevalue) * 2 + 1; wide = calloc(size, sizeof(wchar_t)); if (!wide) die("Out of memory, (tried to allocate %u wchar_t's)", size); xutftowcs(wide, namevalue, size); equal = wcschr(wide, L'='); if (!equal) result = SetEnvironmentVariableW(wide, NULL); else { *equal = L'\0'; result = SetEnvironmentVariableW(wide, equal + 1); } free(wide);
if (!result) errno = err_win_to_posix(GetLastError());
return result ? 0 : -1; } ```
This line :
``` result = SetEnvironmentVariableW(wide, NULL); ```
sets error on removing non-existent `PERL5LIB` and that leads to result == 0 which in turn leads to premature exit in `err_win_to_posix(GetLastError())`.
In this particular case, for some reason last error sets to 0 instead of 203. Another bug probably, I'll report it later.