mirror of
https://sourceware.org/git/glibc.git
synced 2025-06-16 17:41:01 +03:00
Update.
* sysdeps/generic/setenv.c: Move setenv code in new function __add_to_environ. Add new parameter specifying already constructed string for the environment. (setenv): Call __add_to_environ with new parameter set to NULL. (unsetenv): Really test all elements for duplicated name. Missed those cases where the two are following each other. * sysdeps/generic/putenv.c: Use __add_to_environ instead of setenv. * include/stdlib.h: Add prototype of __add_to_environ. * stdlib/tst-environ.c: New file.
This commit is contained in:
10
ChangeLog
10
ChangeLog
@ -1,5 +1,15 @@
|
||||
1999-07-29 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* sysdeps/generic/setenv.c: Move setenv code in new function
|
||||
__add_to_environ. Add new parameter specifying already
|
||||
constructed string for the environment.
|
||||
(setenv): Call __add_to_environ with new parameter set to NULL.
|
||||
(unsetenv): Really test all elements for duplicated name. Missed those
|
||||
cases where the two are following each other.
|
||||
* sysdeps/generic/putenv.c: Use __add_to_environ instead of setenv.
|
||||
* include/stdlib.h: Add prototype of __add_to_environ.
|
||||
* stdlib/tst-environ.c: New file.
|
||||
|
||||
* sysdeps/i386/bits/string.h (__memset_cc): Fix typo in last patch.
|
||||
|
||||
* nis/nss_nis/nis-initgroups.c (_nss_nis_initgroups): Correct size
|
||||
|
@ -46,6 +46,9 @@ extern char *__canonicalize_file_name __P ((__const char *__name));
|
||||
extern char *__realpath __P ((__const char *__name, char *__resolved));
|
||||
extern int __ptsname_r __P ((int __fd, char *__buf, size_t __buflen));
|
||||
extern int __getpt __P ((void));
|
||||
|
||||
extern int __add_to_environ (const char *name, const char *value,
|
||||
const char *combines, int replace);
|
||||
#endif
|
||||
#undef __Need_M_And_C
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -64,7 +64,7 @@ putenv (string)
|
||||
memcpy (name, string, name_end - string);
|
||||
name[name_end - string] = '\0';
|
||||
#endif
|
||||
return __setenv (name, name_end + 1, 1);
|
||||
return __add_to_environ (name, NULL, string, 1);
|
||||
}
|
||||
|
||||
__unsetenv (string);
|
||||
|
@ -16,23 +16,6 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Issues:
|
||||
|
||||
1. putenv must not use setenv since the string provided by the user
|
||||
must be used, not a copy
|
||||
|
||||
2. a common function should determine the place where to insert the
|
||||
new entry and if necessary take care of extending the array
|
||||
|
||||
3. It must be kept track of whether an entry was inserted via putenv
|
||||
or setenv. In the former case the entry must not be put into
|
||||
the search tree since removing it could mean it will not be
|
||||
available anymore (e.g., when allocated on the stack)
|
||||
|
||||
To handle this an array parallel to the __environ array must specify
|
||||
whether the entry was added via putenv or not
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
@ -117,16 +100,23 @@ static void *known_values;
|
||||
static char **last_environ;
|
||||
|
||||
|
||||
/* This function is used by `setenv' and `putenv'. The difference between
|
||||
the two functions is that for the former must create a new string which
|
||||
is then placed in the environment, while the argument of `putenv'
|
||||
must be used directly. This is all complicated by the fact that we try
|
||||
to reuse values once generated for a `setenv' call since we can never
|
||||
free the strings. */
|
||||
int
|
||||
setenv (name, value, replace)
|
||||
__add_to_environ (name, value, combined, replace)
|
||||
const char *name;
|
||||
const char *value;
|
||||
const char *combined;
|
||||
int replace;
|
||||
{
|
||||
register char **ep;
|
||||
register size_t size;
|
||||
const size_t namelen = strlen (name);
|
||||
const size_t vallen = strlen (value) + 1;
|
||||
const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
|
||||
|
||||
LOCK;
|
||||
|
||||
@ -156,37 +146,49 @@ setenv (name, value, replace)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* See whether the value is already known. */
|
||||
/* If the whole entry is given add it. */
|
||||
if (combined != NULL)
|
||||
/* We must not add the string to the search tree since it belongs
|
||||
to the user. */
|
||||
new_environ[size] = (char *) combined;
|
||||
else
|
||||
{
|
||||
/* See whether the value is already known. */
|
||||
#ifdef USE_TSEARCH
|
||||
new_value = alloca (namelen + 1 + vallen);
|
||||
new_value = (char *) alloca (namelen + 1 + vallen);
|
||||
# ifdef _LIBC
|
||||
__mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
|
||||
value, vallen);
|
||||
__mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
|
||||
value, vallen);
|
||||
# else
|
||||
memcpy (new_value, name, namelen);
|
||||
new_value[namelen] = '=';
|
||||
memcpy (&new_value[namelen + 1], value, vallen);
|
||||
memcpy (new_value, name, namelen);
|
||||
new_value[namelen] = '=';
|
||||
memcpy (&new_value[namelen + 1], value, vallen);
|
||||
# endif
|
||||
|
||||
new_environ[size] = KNOWN_VALUE (new_value);
|
||||
if (new_environ[size] == NULL)
|
||||
#endif
|
||||
{
|
||||
new_environ[size] = malloc (namelen + 1 + vallen);
|
||||
new_environ[size] = KNOWN_VALUE (new_value);
|
||||
if (new_environ[size] == NULL)
|
||||
#endif
|
||||
{
|
||||
__set_errno (ENOMEM);
|
||||
UNLOCK;
|
||||
return -1;
|
||||
}
|
||||
new_environ[size] = (char *) malloc (namelen + 1 + vallen);
|
||||
if (new_environ[size] == NULL)
|
||||
{
|
||||
__set_errno (ENOMEM);
|
||||
UNLOCK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_TSEARCH
|
||||
memcpy (new_environ[size], new_value, namelen + 1 + vallen);
|
||||
memcpy (new_environ[size], new_value, namelen + 1 + vallen);
|
||||
#else
|
||||
memcpy (new_environ[size], name, namelen);
|
||||
new_environ[size][namelen] = '=';
|
||||
memcpy (&new_environ[size][namelen + 1], value, vallen);
|
||||
memcpy (new_environ[size], name, namelen);
|
||||
new_environ[size][namelen] = '=';
|
||||
memcpy (&new_environ[size][namelen + 1], value, vallen);
|
||||
#endif
|
||||
/* And save the value now. We cannot do this when we remove
|
||||
the string since then we cannot decide whether it is a
|
||||
user string or not. */
|
||||
STORE_VALUE (new_environ[size]);
|
||||
}
|
||||
}
|
||||
|
||||
if (__environ != last_environ)
|
||||
@ -199,43 +201,47 @@ setenv (name, value, replace)
|
||||
}
|
||||
else if (replace)
|
||||
{
|
||||
char *new_value;
|
||||
char *np;
|
||||
|
||||
/* The existing string is too short; malloc a new one. */
|
||||
/* Use the user string if given. */
|
||||
if (combined != NULL)
|
||||
np = (char *) combined;
|
||||
else
|
||||
{
|
||||
#ifdef USE_TSEARCH
|
||||
new_value = alloca (namelen + 1 + vallen);
|
||||
char *new_value = alloca (namelen + 1 + vallen);
|
||||
# ifdef _LIBC
|
||||
__mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
|
||||
value, vallen);
|
||||
__mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
|
||||
value, vallen);
|
||||
# else
|
||||
memcpy (new_value, name, namelen);
|
||||
new_value[namelen] = '=';
|
||||
memcpy (&new_value[namelen + 1], value, vallen);
|
||||
memcpy (new_value, name, namelen);
|
||||
new_value[namelen] = '=';
|
||||
memcpy (&new_value[namelen + 1], value, vallen);
|
||||
# endif
|
||||
|
||||
np = KNOWN_VALUE (new_value);
|
||||
if (np == NULL)
|
||||
#endif
|
||||
{
|
||||
np = malloc (namelen + 1 + vallen);
|
||||
np = KNOWN_VALUE (new_value);
|
||||
if (np == NULL)
|
||||
#endif
|
||||
{
|
||||
UNLOCK;
|
||||
return -1;
|
||||
}
|
||||
np = malloc (namelen + 1 + vallen);
|
||||
if (np == NULL)
|
||||
{
|
||||
UNLOCK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_TSEARCH
|
||||
memcpy (np, new_value, namelen + 1 + vallen);
|
||||
memcpy (np, new_value, namelen + 1 + vallen);
|
||||
#else
|
||||
memcpy (np, name, namelen);
|
||||
np[namelen] = '=';
|
||||
memcpy (&np[namelen + 1], value, vallen);
|
||||
memcpy (np, name, namelen);
|
||||
np[namelen] = '=';
|
||||
memcpy (&np[namelen + 1], value, vallen);
|
||||
#endif
|
||||
/* And remember the value. */
|
||||
STORE_VALUE (np);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep the old value around. */
|
||||
STORE_VALUE (*ep);
|
||||
*ep = np;
|
||||
}
|
||||
|
||||
@ -244,6 +250,15 @@ setenv (name, value, replace)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
setenv (name, value, replace)
|
||||
const char *name;
|
||||
const char *value;
|
||||
int replace;
|
||||
{
|
||||
return __add_to_environ (name, value, NULL, replace);
|
||||
}
|
||||
|
||||
void
|
||||
unsetenv (name)
|
||||
const char *name;
|
||||
@ -253,20 +268,20 @@ unsetenv (name)
|
||||
|
||||
LOCK;
|
||||
|
||||
for (ep = __environ; *ep != NULL; ++ep)
|
||||
ep = __environ;
|
||||
while (*ep != NULL)
|
||||
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
|
||||
{
|
||||
/* Found it. Remove this pointer by moving later ones back. */
|
||||
char **dp = ep;
|
||||
|
||||
/* Store the value so that we can reuse it later. */
|
||||
STORE_VALUE (*ep);
|
||||
|
||||
do
|
||||
dp[0] = dp[1];
|
||||
while (*dp++);
|
||||
/* Continue the loop in case NAME appears again. */
|
||||
}
|
||||
else
|
||||
++ep;
|
||||
|
||||
UNLOCK;
|
||||
}
|
||||
@ -281,12 +296,7 @@ clearenv ()
|
||||
|
||||
if (__environ == last_environ && __environ != NULL)
|
||||
{
|
||||
/* We allocated this environment so we can free it. Store all the
|
||||
strings. */
|
||||
char **ep = __environ;
|
||||
while (*ep != NULL)
|
||||
STORE_VALUE (*ep++);
|
||||
|
||||
/* We allocated this environment so we can free it. */
|
||||
free (__environ);
|
||||
last_environ = NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user