mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 09:43:32 +08:00
74 lines
3.0 KiB
C
74 lines
3.0 KiB
C
|
/* Common declarations for the setenv/getenv family of functions.
|
||
|
Copyright (C) 2024 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
|
||
|
modify it under the terms of the GNU Lesser General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2.1 of the License, or (at your option) any later version.
|
||
|
|
||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Lesser General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Lesser General Public
|
||
|
License along with the GNU C Library; if not, see
|
||
|
<https://www.gnu.org/licenses/>. */
|
||
|
|
||
|
#ifndef _SETENV_H
|
||
|
#define _SETENV_H
|
||
|
|
||
|
#include <atomic.h>
|
||
|
#include <stdbool.h>
|
||
|
|
||
|
/* We use an exponential sizing policy for environment arrays. The
|
||
|
arrays are not deallocating during the lifetime of the process.
|
||
|
This adds between one and two additional pointers per active
|
||
|
environemnt entry, on top of what is used by setenv to keep track
|
||
|
of environment values used before. */
|
||
|
struct environ_array
|
||
|
{
|
||
|
struct environ_array *next; /* Previously used environment array. */
|
||
|
size_t allocated; /* Number of allocated array elments. */
|
||
|
char *array[]; /* The actual environment array. */
|
||
|
};
|
||
|
|
||
|
/* After initialization, and until the user resets environ (perhaps by
|
||
|
calling clearenv), &__environ[0] == &environ_array_list->array[0]. */
|
||
|
extern struct environ_array *__environ_array_list attribute_hidden;
|
||
|
|
||
|
/* Returns true if EP (which should be an __environ value) is a
|
||
|
pointer managed by setenv. */
|
||
|
static inline bool
|
||
|
__environ_is_from_array_list (char **ep)
|
||
|
{
|
||
|
struct environ_array *eal = atomic_load_relaxed (&__environ_array_list);
|
||
|
return eal != NULL && &eal->array[0] == ep;
|
||
|
}
|
||
|
|
||
|
/* Counter for detecting concurrent modification in unsetenv.
|
||
|
Ideally, this should be a 64-bit counter that cannot wrap around,
|
||
|
but given that counter wrapround is probably impossible to hit
|
||
|
(2**32 operations in unsetenv concurrently with getenv), using
|
||
|
<atomic_wide_counter.h> seems unnecessary. */
|
||
|
#if __HAVE_64B_ATOMICS
|
||
|
typedef uint64_t environ_counter;
|
||
|
#else
|
||
|
typedef uint32_t environ_counter;
|
||
|
#endif
|
||
|
|
||
|
/* Updated by unsetenv to detect multiple overwrites in getenv. */
|
||
|
extern environ_counter __environ_counter attribute_hidden;
|
||
|
|
||
|
/* 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 __add_to_environ (const char *name, const char *value,
|
||
|
const char *combines, int replace) attribute_hidden;
|
||
|
|
||
|
#endif /* _SETENV_H */
|