* cygheap.cc (cygheap_user::set_name): Set homedrive and homepath to NULL on
user name change. (cygheap_user::set_logsrv): Allocate enough space for leading \\ so that we can put this in the environment, if needed. * cygheap.h (homebodies): New enum. (cygheap_user::homedrive): New field. (cygheap_user::homepath): Ditto. (cygheap_user::env_logsrv): New method. (cygheap_user::env_homepath): New method. (cygheap_user::env_homedrive): New method. (cygheap_user::env_userprofile): New method. (cygheap_user::ontherange): New method. * environ.cc (envsize): Eliminate debugging argument. (environ_init): Assume that envc counts number of elments not total size. (spenv): New class. (spenvs): New array, renamed from forced_winenv_vars, using spenv. (spenv::retrieve): New method. (build_env): Rename from 'winenv' -- one stop shopping for building new environment blocks for both windows and "unix". * environ.h (build_env: Declare. (winenv): Delete declaration. (envsize): Ditto. * spawn.cc (spawn_guts): Use build_env to build windows and cygwin environment blocks. * uinfo.cc (internal_getlogin): Eliminate environment manipulation. Default to info from GetUserName if it exists. Move HOMEPATH and HOMEDRIVE stuff elsewhere. Move HOME setting elsewhere. Only set HOME environment variable in processes that are not parented by a cygwin process. (cygheap_user::ontherange): Define new method. (cygheap_user::env_logsrv): Ditto. (cygheap_user::env_homepath): Ditto. (cygheap_user::env_homedrive): Ditto. (cygheap_user::env_userprofile): Ditto.
This commit is contained in:
@@ -195,13 +195,12 @@ getenv (const char *name)
|
||||
return my_findenv (name, &offset);
|
||||
}
|
||||
|
||||
extern int __stdcall
|
||||
envsize (const char * const *in_envp, int debug_print)
|
||||
static int __stdcall
|
||||
envsize (const char * const *in_envp)
|
||||
{
|
||||
const char * const *envp;
|
||||
for (envp = in_envp; *envp; envp++)
|
||||
if (debug_print)
|
||||
debug_printf ("%s", *envp);
|
||||
continue;
|
||||
return (1 + envp - in_envp) * sizeof (const char *);
|
||||
}
|
||||
|
||||
@@ -673,6 +672,8 @@ environ_init (char **envp, int envc)
|
||||
envp_passed_in = 0;
|
||||
else
|
||||
{
|
||||
envc++;
|
||||
envc *= sizeof (char *);
|
||||
char **newenv = (char **) malloc (envc);
|
||||
memcpy (newenv, envp, envc);
|
||||
cfree (envp);
|
||||
@@ -749,107 +750,154 @@ env_sort (const void *a, const void *b)
|
||||
return strcmp (*p, *q);
|
||||
}
|
||||
|
||||
/* Keep this list in upper case and sorted */
|
||||
static const NO_COPY char* forced_winenv_vars [] =
|
||||
{
|
||||
"SYSTEMDRIVE",
|
||||
"SYSTEMROOT",
|
||||
NULL
|
||||
};
|
||||
struct spenv
|
||||
{
|
||||
const char *name;
|
||||
const char * (cygheap_user::*from_cygheap) ();
|
||||
char *retrieve (bool, const char * const = NULL, int = 0);
|
||||
};
|
||||
|
||||
#define FORCED_WINENV_SIZE (sizeof (forced_winenv_vars) / sizeof (forced_winenv_vars[0]))
|
||||
/* Keep this list in upper case and sorted */
|
||||
static NO_COPY spenv spenvs[] =
|
||||
{
|
||||
{"HOMEPATH=", &cygheap_user::env_homepath},
|
||||
{"HOMEDRIVE=", &cygheap_user::env_homedrive},
|
||||
{"LOGONSERVER=", &cygheap_user::env_logsrv},
|
||||
{"SYSTEMDRIVE=", NULL},
|
||||
{"SYSTEMROOT=", NULL},
|
||||
{"USERPROFILE=", &cygheap_user::env_userprofile},
|
||||
};
|
||||
|
||||
char *
|
||||
spenv::retrieve (bool no_envblock, const char *const envname, int len)
|
||||
{
|
||||
if (len && !strncasematch (envname, name, len))
|
||||
return NULL;
|
||||
if (from_cygheap)
|
||||
{
|
||||
const char *p;
|
||||
if (!len)
|
||||
return NULL; /* No need to force these into the
|
||||
environment */
|
||||
|
||||
if (no_envblock)
|
||||
return cstrdup1 (envname); /* Don't really care what it's set to
|
||||
if we're calling a cygwin program */
|
||||
|
||||
/* Make a FOO=BAR entry from the value returned by the cygheap_user
|
||||
method. */
|
||||
p = (cygheap->user.*from_cygheap) ();
|
||||
int namelen = strlen (name);
|
||||
char *s = (char *) cmalloc (HEAP_1_STR, namelen + strlen (p) + 1);
|
||||
strcpy (s, name);
|
||||
(void) strcpy (s + namelen, p);
|
||||
return s;
|
||||
}
|
||||
|
||||
if (len)
|
||||
return cstrdup1 (envname);
|
||||
|
||||
char dum[1];
|
||||
int vallen = GetEnvironmentVariable (name, dum, 0);
|
||||
if (vallen > 0)
|
||||
{
|
||||
int namelen = strlen (name);
|
||||
char *p = (char *) cmalloc (HEAP_1_STR, namelen + ++vallen);
|
||||
strcpy (p, name);
|
||||
if (GetEnvironmentVariable (name, p + namelen, vallen))
|
||||
return p;
|
||||
else
|
||||
cfree (p);
|
||||
}
|
||||
|
||||
debug_printf ("warning: %s not present in environment", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define SPENVS_SIZE (sizeof (spenvs) / sizeof (spenvs[0]))
|
||||
|
||||
/* Create a Windows-style environment block, i.e. a typical character buffer
|
||||
filled with null terminated strings, terminated by double null characters.
|
||||
Converts environment variables noted in conv_envvars into win32 form
|
||||
prior to placing them in the string. */
|
||||
char * __stdcall
|
||||
winenv (const char * const *envp, int keep_posix)
|
||||
char ** __stdcall
|
||||
build_env (const char * const *envp, char *&envblock, int &envc,
|
||||
bool no_envblock)
|
||||
{
|
||||
int len, n, tl;
|
||||
const char * const *srcp;
|
||||
const char **dstp;
|
||||
bool saw_forced_winenv[FORCED_WINENV_SIZE] = {0};
|
||||
char *p;
|
||||
char **dstp;
|
||||
bool saw_spenv[SPENVS_SIZE] = {0};
|
||||
|
||||
debug_printf ("envp %p, keep_posix %d", envp, keep_posix);
|
||||
debug_printf ("envp %p", envp);
|
||||
|
||||
tl = 0;
|
||||
|
||||
for (n = 0; envp[n]; n++)
|
||||
continue;
|
||||
|
||||
const char *newenvp[n + 1 + FORCED_WINENV_SIZE];
|
||||
char **newenv = (char **) cmalloc (HEAP_1_ARGV, sizeof (char *) * (n + SPENVS_SIZE + 1));
|
||||
|
||||
for (srcp = envp, dstp = newenvp; *srcp; srcp++, dstp++)
|
||||
for (srcp = envp, dstp = newenv; *srcp; srcp++, dstp++)
|
||||
{
|
||||
len = strcspn (*srcp, "=");
|
||||
len = strcspn (*srcp, "=") + 1;
|
||||
|
||||
for (unsigned i = 0; i < SPENVS_SIZE; i++)
|
||||
if (!saw_spenv[i] && (*dstp = spenvs[i].retrieve (no_envblock,*srcp, len)))
|
||||
{
|
||||
saw_spenv[i] = 1;
|
||||
goto last;
|
||||
}
|
||||
|
||||
win_env *conv;
|
||||
|
||||
if (keep_posix || !(conv = getwinenv (*srcp, *srcp + len + 1)))
|
||||
*dstp = *srcp;
|
||||
if (!(conv = getwinenv (*srcp, *srcp + len)))
|
||||
*dstp = cstrdup1 (*srcp);
|
||||
else
|
||||
{
|
||||
p = (char *) alloca (strlen (conv->native) + 1);
|
||||
strcpy (p, conv->native);
|
||||
*dstp = p;
|
||||
}
|
||||
tl += strlen (*dstp) + 1;
|
||||
if ((*dstp)[0] == '!' && isdrive ((*dstp) + 1) && (*dstp)[3] == '=')
|
||||
{
|
||||
p = (char *) alloca (strlen (*dstp) + 1);
|
||||
strcpy (p, *dstp);
|
||||
*p = '=';
|
||||
*dstp = p;
|
||||
}
|
||||
*dstp = cstrdup1 (conv->native);
|
||||
|
||||
for (int i = 0; forced_winenv_vars[i]; i++)
|
||||
if (!saw_forced_winenv[i])
|
||||
saw_forced_winenv[i] = strncasematch (forced_winenv_vars[i], *srcp, len);
|
||||
if ((*dstp)[0] == '!' && isdrive ((*dstp) + 1) && (*dstp)[3] == '=')
|
||||
**dstp = '=';
|
||||
|
||||
last:
|
||||
tl += strlen (*dstp) + 1;
|
||||
}
|
||||
|
||||
char dum[1];
|
||||
for (int i = 0; forced_winenv_vars[i]; i++)
|
||||
if (!saw_forced_winenv[i])
|
||||
for (unsigned i = 0; i < SPENVS_SIZE; i++)
|
||||
if (!saw_spenv[i])
|
||||
{
|
||||
int vallen = GetEnvironmentVariable (forced_winenv_vars[i], dum, 0);
|
||||
if (vallen > 0)
|
||||
*dstp = spenvs[i].retrieve (no_envblock);
|
||||
if (*dstp)
|
||||
{
|
||||
int namelen = strlen (forced_winenv_vars[i]) + 1;
|
||||
p = (char *) alloca (namelen + ++vallen);
|
||||
strcpy (p, forced_winenv_vars[i]);
|
||||
strcat (p, "=");
|
||||
if (!GetEnvironmentVariable (forced_winenv_vars[i], p + namelen,
|
||||
vallen))
|
||||
debug_printf ("warning: %s not present in environment", *srcp);
|
||||
else
|
||||
{
|
||||
*dstp++ = p;
|
||||
tl += strlen (p) + 1;
|
||||
}
|
||||
tl += strlen (*dstp) + 1;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
|
||||
*dstp = NULL; /* Terminate */
|
||||
envc = dstp - newenv;
|
||||
*dstp = NULL; /* Terminate */
|
||||
|
||||
int envlen = dstp - newenvp;
|
||||
debug_printf ("env count %d, bytes %d", envlen, tl);
|
||||
|
||||
/* Windows programs expect the environment block to be sorted. */
|
||||
qsort (newenvp, envlen, sizeof (char *), env_sort);
|
||||
|
||||
/* Create an environment block suitable for passing to CreateProcess. */
|
||||
char *ptr, *envblock;
|
||||
envblock = (char *) malloc (tl + 2);
|
||||
for (srcp = newenvp, ptr = envblock; *srcp; srcp++)
|
||||
if (no_envblock)
|
||||
envblock = NULL;
|
||||
else
|
||||
{
|
||||
len = strlen (*srcp);
|
||||
memcpy (ptr, *srcp, len + 1);
|
||||
ptr += len + 1;
|
||||
}
|
||||
*ptr = '\0'; /* Two null bytes at the end */
|
||||
debug_printf ("env count %d, bytes %d", envc, tl);
|
||||
|
||||
return envblock;
|
||||
/* Windows programs expect the environment block to be sorted. */
|
||||
qsort (newenv, envc, sizeof (char *), env_sort);
|
||||
|
||||
/* Create an environment block suitable for passing to CreateProcess. */
|
||||
char *ptr;
|
||||
envblock = (char *) malloc (tl + 2);
|
||||
for (srcp = newenv, ptr = envblock; *srcp; srcp++)
|
||||
{
|
||||
len = strlen (*srcp);
|
||||
memcpy (ptr, *srcp, len + 1);
|
||||
ptr += len + 1;
|
||||
}
|
||||
*ptr = '\0'; /* Two null bytes at the end */
|
||||
}
|
||||
|
||||
return newenv;
|
||||
}
|
||||
|
||||
/* This idiocy is necessary because the early implementers of cygwin
|
||||
|
Reference in New Issue
Block a user