From 1a5dfe8ae08e00200a081f1f1a368f1201543761 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 24 May 2013 13:32:10 +0000 Subject: [PATCH] * environ.cc (win_env::add_cache): Set the Windows environment variable using wide chars to make sure native chars don't get scrambled. * environ.h (build_env): Fix formatting in declaration. * pinfo.cc (pinfo::status_exit): Handle STATUS_NO_MEMORY. Explain why. --- winsup/cygwin/ChangeLog | 7 +++++++ winsup/cygwin/environ.cc | 10 +++++----- winsup/cygwin/environ.h | 2 +- winsup/cygwin/pinfo.cc | 13 +++++++++++++ 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c69159de6..1fce36c35 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2013-05-24 Corinna Vinschen + + * environ.cc (win_env::add_cache): Set the Windows environment variable + using wide chars to make sure native chars don't get scrambled. + * environ.h (build_env): Fix formatting in declaration. + * pinfo.cc (pinfo::status_exit): Handle STATUS_NO_MEMORY. Explain why. + 2013-05-24 Corinna Vinschen * fork.cc (frok::parent): Always set CREATE_UNICODE_ENVIRONMENT flag. diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index f73c232c9..5e522b91f 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -386,11 +386,11 @@ win_env::add_cache (const char *in_posix, const char *in_native) MALLOC_CHECK; if (immediate && cygwin_finished_initializing) { - char s[namelen]; - size_t n = namelen - 1; - memcpy (s, name, n); - s[n] = '\0'; - SetEnvironmentVariable (s, native + namelen); + wchar_t s[sys_mbstowcs (NULL, 0, native) + 1]; + sys_mbstowcs (s, sizeof s, native); + /* Hack. Relies on affected variables only having ASCII names. */ + s[namelen - 1] = L'\0'; + SetEnvironmentVariableW (s, s + namelen); } debug_printf ("posix %s", posix); debug_printf ("native %s", native); diff --git a/winsup/cygwin/environ.h b/winsup/cygwin/environ.h index d6a7d8a38..b2d65c8bd 100644 --- a/winsup/cygwin/environ.h +++ b/winsup/cygwin/environ.h @@ -45,6 +45,6 @@ extern "C" char **__cygwin_environ, ***main_environ; extern "C" char __stdcall **cur_environ (); #endif char ** __reg3 build_env (const char * const *envp, PWCHAR &envblock, - int &envc, bool need_envblock); + int &envc, bool need_envblock); #define ENV_CVT -1 diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index c92cfc10a..c51902cbd 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -144,6 +144,19 @@ pinfo::status_exit (DWORD x) case STATUS_ILLEGAL_INSTRUCTION: x = SIGILL; break; + case STATUS_NO_MEMORY: + /* If the PATH environment variable is longer than about 30K and the full + Windows environment is > 32K, startup of an exec'ed process fails with + STATUS_NO_MEMORY. This happens with all Cygwin executables, as well + as, for instance, notepad, but it does not happen with CMD for some + reason. This occurs at a point where there's no return to the exec'ing + parent process, so we have to find some way to inform the user what + happened. + + FIXME: For now, just return with SIGBUS set. Maybe it's better to add + a lengthy small_printf instead. */ + x = SIGBUS; + break; default: debug_printf ("*** STATUS_%y\n", x); x = 127 << 8;