Move the core environment parsing of environ_init into a new win32env_to_cygenv function.

win32env_to_cygwenv handles converting wchar to char and some other
minor taks.  Optionally it handles converting any paths in variables to
posix paths.

This will be useful for implementing /proc/<pid>/environ
This commit is contained in:
Erik M. Bray 2017-01-10 16:03:08 +01:00 committed by Corinna Vinschen
parent 387521976d
commit 7fd70a9706
2 changed files with 51 additions and 35 deletions

View File

@ -758,18 +758,12 @@ ucenv (char *p, const char *eq)
void
environ_init (char **envp, int envc)
{
PWCHAR rawenv, w;
int i;
PWCHAR rawenv;
char *p;
char *newp;
int sawTERM = 0;
bool envp_passed_in;
static char NO_COPY cygterm[] = "TERM=cygwin";
tmp_pathbuf tp;
__try
{
char *tmpbuf = tp.t_get ();
if (!envp)
envp_passed_in = 0;
else
@ -794,9 +788,6 @@ environ_init (char **envp, int envc)
goto out;
}
/* Allocate space for environment + trailing NULL + CYGWIN env. */
lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
rawenv = GetEnvironmentStringsW ();
if (!rawenv)
{
@ -805,32 +796,8 @@ environ_init (char **envp, int envc)
}
debug_printf ("GetEnvironmentStrings returned %p", rawenv);
/* Current directory information is recorded as variables of the
form "=X:=X:\foo\bar; these must be changed into something legal
(we could just ignore them but maybe an application will
eventually want to use them). */
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
{
sys_wcstombs_alloc_no_path (&newp, HEAP_NOTHEAP, w);
if (i >= envc)
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
envp[i] = newp;
if (*newp == '=')
*newp = '!';
char *eq = strchrnul (newp, '=');
ucenv (newp, eq); /* uppercase env vars which need it */
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
sawTERM = 1;
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
parse_options (newp + 7);
if (*eq)
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
debug_printf ("%p: %s", envp[i], envp[i]);
}
lastenviron = envp = win32env_to_cygenv (rawenv, true);
if (!sawTERM)
envp[i++] = strdup (cygterm);
envp[i] = NULL;
FreeEnvironmentStringsW (rawenv);
out:
@ -852,6 +819,53 @@ environ_init (char **envp, int envc)
__endtry
}
char ** __reg2
win32env_to_cygenv (PWCHAR rawenv, bool posify)
{
tmp_pathbuf tp;
char **envp;
int envc;
char *newp;
int i;
int sawTERM = 0;
static char NO_COPY cygterm[] = "TERM=cygwin";
char *tmpbuf = tp.t_get ();
PWCHAR w;
/* Allocate space for environment + trailing NULL + CYGWIN env. */
envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
/* Current directory information is recorded as variables of the
form "=X:=X:\foo\bar; these must be changed into something legal
(we could just ignore them but maybe an application will
eventually want to use them). */
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
{
sys_wcstombs_alloc_no_path (&newp, HEAP_NOTHEAP, w);
if (i >= envc)
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
envp[i] = newp;
if (*newp == '=')
*newp = '!';
char *eq = strchrnul (newp, '=');
ucenv (newp, eq); /* uppercase env vars which need it */
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
sawTERM = 1;
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
parse_options (newp + 7);
if (*eq && posify)
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
debug_printf ("%p: %s", envp[i], envp[i]);
}
if (!sawTERM)
envp[i++] = strdup (cygterm);
envp[i] = NULL;
return envp;
}
/* Function called by qsort to sort environment strings. */
static int
env_sort (const void *a, const void *b)

View File

@ -45,4 +45,6 @@ extern "C" char __stdcall **cur_environ ();
char ** __reg3 build_env (const char * const *envp, PWCHAR &envblock,
int &envc, bool need_envblock, HANDLE new_token);
char ** __reg2 win32env_to_cygenv (PWCHAR rawenv, bool posify);
#define ENV_CVT -1