Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-03-30 19:54:28 +0400
committerChristopher Faylor <me@cgf.cx>2005-03-30 19:54:28 +0400
commit47dc3dec0ab30187d3502e0c66ed78396aa14672 (patch)
tree427565aef23cdecea2db8f37b794880e34c8c79b
parentf3fd76d41826effa0f94202be1811a52a9547b56 (diff)
* environ.h (win_env::immediate): Declare new field.
(win_env::operator = ): Declare new operator. (win_env::reset): Declare new function. (win_env::~win_env): Declare new destructor. (getwinenv): Add optional third argument to declaration. * environ.cc (conv_envvars): Accommodate immediate field. (win_env::operator =): Define new operator. (win_env::~win_env): Define new destructor. (win_env::add_cache): Add value to environment immediately if "immediate" is set. (getwinenv): Accept optional third argument which will be used to store "cached" values to avoid overwriting real cache. (spenv::force): Declare new field. (spenvs): Accommodate force field. Add "PATH=" with force set to true. (spenv::retrieve): Avoid duping anything if we're not building an envblock. (build_env): Ditto. Use size of potentially constructed new environment block to determine if we need to create an environment block. Pass getwinenv temporary storage to avoid inappropriately overwriting the environment cache.
-rw-r--r--winsup/cygwin/ChangeLog23
-rw-r--r--winsup/cygwin/environ.cc105
-rw-r--r--winsup/cygwin/environ.h6
3 files changed, 103 insertions, 31 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index aa28ca4dc..21331b37c 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,26 @@
+2005-03-30 Christopher Faylor <cgf@timesys.com>
+
+ * environ.h (win_env::immediate): Declare new field.
+ (win_env::operator = ): Declare new operator.
+ (win_env::reset): Declare new function.
+ (win_env::~win_env): Declare new destructor.
+ (getwinenv): Add optional third argument to declaration.
+ * environ.cc (conv_envvars): Accommodate immediate field.
+ (win_env::operator =): Define new operator.
+ (win_env::~win_env): Define new destructor.
+ (win_env::add_cache): Add value to environment immediately if
+ "immediate" is set.
+ (getwinenv): Accept optional third argument which will be used to store
+ "cached" values to avoid overwriting real cache.
+ (spenv::force): Declare new field.
+ (spenvs): Accommodate force field. Add "PATH=" with force set to true.
+ (spenv::retrieve): Avoid duping anything if we're not building an
+ envblock.
+ (build_env): Ditto. Use size of potentially constructed new
+ environment block to determine if we need to create an environment
+ block. Pass getwinenv temporary storage to avoid inappropriately
+ overwriting the environment cache.
+
2005-03-29 Eric Blake <ebb9@byu.net>
* include/limits.h (NAME_MAX): New define.
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 6bb3ae971..db8c6d171 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -59,22 +59,43 @@ static win_env conv_envvars[] =
{NL ("PATH="), NULL, NULL, cygwin_win32_to_posix_path_list,
cygwin_posix_to_win32_path_list,
cygwin_win32_to_posix_path_list_buf_size,
- cygwin_posix_to_win32_path_list_buf_size},
+ cygwin_posix_to_win32_path_list_buf_size, true},
{NL ("HOME="), NULL, NULL, cygwin_conv_to_full_posix_path,
- cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH},
+ cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
{NL ("LD_LIBRARY_PATH="), NULL, NULL, cygwin_conv_to_full_posix_path,
- cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH},
+ cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, true},
{NL ("TMPDIR="), NULL, NULL, cygwin_conv_to_full_posix_path,
- cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH},
+ cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
{NL ("TMP="), NULL, NULL, cygwin_conv_to_full_posix_path,
- cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH},
+ cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
{NL ("TEMP="), NULL, NULL, cygwin_conv_to_full_posix_path,
- cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH},
+ cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
{NULL, 0, NULL, NULL, NULL, NULL, 0, 0}
};
static unsigned char conv_start_chars[256] = {0};
+struct win_env&
+win_env::operator = (struct win_env& x)
+{
+ name = x.name;
+ namelen = x.namelen;
+ toposix = x.toposix;
+ towin32 = x.towin32;
+ posix_len = x.posix_len;
+ win32_len = x.win32_len;
+ immediate = false;
+ return *this;
+}
+
+win_env::~win_env ()
+{
+ if (posix)
+ free (posix);
+ if (native)
+ free (native);
+}
+
void
win_env::add_cache (const char *in_posix, const char *in_native)
{
@@ -94,6 +115,14 @@ win_env::add_cache (const char *in_posix, const char *in_native)
towin32 (in_posix, native + namelen);
}
MALLOC_CHECK;
+ if (immediate)
+ {
+ char s[namelen];
+ size_t n = namelen - 1;
+ memcpy (s, name, n);
+ s[n] = '\0';
+ SetEnvironmentVariable (s, native + namelen);
+ }
debug_printf ("posix %s", posix);
debug_printf ("native %s", native);
}
@@ -104,7 +133,7 @@ win_env::add_cache (const char *in_posix, const char *in_native)
known posix value for the environment variable. Returns a pointer to
the appropriate conversion structure. */
win_env * __stdcall
-getwinenv (const char *env, const char *in_posix)
+getwinenv (const char *env, const char *in_posix, win_env *temp)
{
if (!conv_start_chars[(unsigned char)*env])
return NULL;
@@ -112,13 +141,20 @@ getwinenv (const char *env, const char *in_posix)
for (int i = 0; conv_envvars[i].name != NULL; i++)
if (strncmp (env, conv_envvars[i].name, conv_envvars[i].namelen) == 0)
{
- win_env * const we = conv_envvars + i;
+ win_env *we = conv_envvars + i;
const char *val;
if (!cur_environ () || !(val = in_posix ?: getenv (we->name)))
debug_printf ("can't set native for %s since no environ yet",
we->name);
else if (!envcache || !we->posix || strcmp (val, we->posix) != 0)
- we->add_cache (val);
+ {
+ if (temp)
+ {
+ *temp = *we;
+ we = temp;
+ }
+ we->add_cache (val);
+ }
return we;
}
return NULL;
@@ -825,6 +861,7 @@ struct spenv
const char *name;
size_t namelen;
bool add_always; /* If true, always add to env if missing */
+ bool force; /* if true, retrieve value from cache */
const char * (cygheap_user::*from_cygheap) (const char *, size_t);
char *retrieve (bool, const char * const = NULL)
@@ -836,20 +873,21 @@ struct spenv
/* Keep this list in upper case and sorted */
static NO_COPY spenv spenvs[] =
{
- {NL ("HOMEDRIVE="), false, &cygheap_user::env_homedrive},
- {NL ("HOMEPATH="), false, &cygheap_user::env_homepath},
- {NL ("LOGONSERVER="), false, &cygheap_user::env_logsrv},
- {NL ("SYSTEMDRIVE="), false, NULL},
- {NL ("SYSTEMROOT="), true, &cygheap_user::env_systemroot},
- {NL ("USERDOMAIN="), false, &cygheap_user::env_domain},
- {NL ("USERNAME="), false, &cygheap_user::env_name},
- {NL ("USERPROFILE="), false, &cygheap_user::env_userprofile},
+ {NL ("HOMEDRIVE="), false, false, &cygheap_user::env_homedrive},
+ {NL ("HOMEPATH="), false, false, &cygheap_user::env_homepath},
+ {NL ("LOGONSERVER="), false, false, &cygheap_user::env_logsrv},
+ {NL ("PATH="), false, true, NULL},
+ {NL ("SYSTEMDRIVE="), false, false, NULL},
+ {NL ("SYSTEMROOT="), true, false, &cygheap_user::env_systemroot},
+ {NL ("USERDOMAIN="), false, false, &cygheap_user::env_domain},
+ {NL ("USERNAME="), false, false, &cygheap_user::env_name},
+ {NL ("USERPROFILE="), false, false, &cygheap_user::env_userprofile}
};
char *
-spenv::retrieve (bool no_envblock, const char *const envname)
+spenv::retrieve (bool no_envblock, const char *const env)
{
- if (envname && !strncasematch (envname, name, namelen))
+ if (env && !strncasematch (env, name, namelen))
return NULL;
debug_printf ("no_envblock %d", no_envblock);
@@ -857,16 +895,16 @@ spenv::retrieve (bool no_envblock, const char *const envname)
if (from_cygheap)
{
const char *p;
- if (envname && !cygheap->user.issetuid ())
+ if (env && !cygheap->user.issetuid ())
{
debug_printf ("duping existing value for '%s'", name);
- return cstrdup1 (envname); /* Don't really care what it's set to
- if we're calling a cygwin program */
+ /* Don't really care what it's set to if we're calling a cygwin program */
+ return (no_envblock && !force) ? env_dontadd : cstrdup1 (env);
}
/* Calculate (potentially) value for given environment variable. */
p = (cygheap->user.*from_cygheap) (name, namelen);
- if (!p || (no_envblock && !envname) || (p == env_dontadd))
+ if (!p || (p == env_dontadd) || (!force && (no_envblock && !env)))
return env_dontadd;
char *s = (char *) cmalloc (HEAP_1_STR, namelen + strlen (p) + 1);
strcpy (s, name);
@@ -875,8 +913,10 @@ spenv::retrieve (bool no_envblock, const char *const envname)
return s;
}
- if (envname)
- return cstrdup1 (envname);
+ if (!force && no_envblock)
+ return env_dontadd;
+ if (env)
+ return cstrdup1 (env);
return getwinenveq (name, namelen, HEAP_1_STR);
}
@@ -916,11 +956,13 @@ build_env (const char * const *envp, char *&envblock, int &envc,
if (!saw_spenv[i] && (*dstp = spenvs[i].retrieve (no_envblock, *srcp)))
{
saw_spenv[i] = 1;
- if (*dstp == env_dontadd)
- goto next1;
- goto next0;
+ if (*dstp != env_dontadd)
+ goto next0;
+ goto next1;
}
+ if (no_envblock)
+ goto next1;
/* Add entry to new environment */
*dstp = cstrdup1 (*srcp);
@@ -950,11 +992,13 @@ build_env (const char * const *envp, char *&envblock, int &envc,
assert ((size_t) envc <= (n + SPENVS_SIZE));
*dstp = NULL; /* Terminate */
- if (no_envblock)
+ if (!envc)
envblock = NULL;
else
{
debug_printf ("env count %d, bytes %d", envc, tl);
+ win_env temp;
+ temp.reset ();
/* Windows programs expect the environment block to be sorted. */
qsort (newenv, envc, sizeof (char *), env_sort);
@@ -978,7 +1022,7 @@ build_env (const char * const *envp, char *&envblock, int &envc,
continue;
/* See if this entry requires posix->win32 conversion. */
- conv = getwinenv (*srcp, *srcp + len);
+ conv = getwinenv (*srcp, *srcp + len, &temp);
if (conv)
p = conv->native; /* Use win32 path */
else
@@ -1017,6 +1061,7 @@ build_env (const char * const *envp, char *&envblock, int &envc,
of buffer */
}
+
debug_printf ("envp %p, envc %d", newenv, envc);
return newenv;
}
diff --git a/winsup/cygwin/environ.h b/winsup/cygwin/environ.h
index f6a1797ad..b953148b4 100644
--- a/winsup/cygwin/environ.h
+++ b/winsup/cygwin/environ.h
@@ -27,13 +27,17 @@ struct win_env
int (*towin32) (const char *, char *);
int (*posix_len) (const char *);
int (*win32_len) (const char *);
+ bool immediate;
void add_cache (const char *in_posix, const char *in_native = NULL)
__attribute__ ((regparm (3)));
const char * get_native () const {return native ? native + namelen : NULL;}
const char * get_posix () const {return posix ? posix : NULL;}
+ struct win_env& operator = (struct win_env& x);
+ void reset () {native = posix = NULL;}
+ ~win_env ();
};
-win_env * __stdcall getwinenv (const char *name, const char *posix = NULL)
+win_env * __stdcall getwinenv (const char *name, const char *posix = NULL, win_env * = NULL)
__attribute__ ((regparm (3)));
char * __stdcall getwinenveq (const char *name, size_t len, int)
__attribute__ ((regparm (3)));