Back to index

glibc  2.9
Defines | Functions | Variables
setenv.c File Reference
#include <errno.h>

Go to the source code of this file.

Defines

#define __set_errno(ev)   ((errno) = (ev))
#define __environ   environ
#define LOCK
#define UNLOCK
#define KNOWN_VALUE(Str)   NULL
#define STORE_VALUE(Str)   do { } while (0)

Functions

int __add_to_environ (char *name, const char *value, const char *combined, int replace) const
int setenv (char *name, const char *value, int replace) const
int unsetenv (char *name) const
int clearenv ()

Variables

int errno
char ** environ
static char ** last_environ

Define Documentation

#define __environ   environ

Definition at line 42 of file setenv.c.

#define __set_errno (   ev)    ((errno) = (ev))

Definition at line 28 of file setenv.c.

#define KNOWN_VALUE (   Str)    NULL

Definition at line 92 of file setenv.c.

#define LOCK

Definition at line 55 of file setenv.c.

#define STORE_VALUE (   Str)    do { } while (0)

Definition at line 93 of file setenv.c.

#define UNLOCK

Definition at line 56 of file setenv.c.


Function Documentation

int __add_to_environ ( char *  name,
const char *  value,
const char *  combined,
int  replace 
) const

Definition at line 110 of file setenv.c.

{
  register char **ep;
  register size_t size;
  const size_t namelen = strlen (name);
  const size_t vallen = value != NULL ? strlen (value) + 1 : 0;

  LOCK;

  /* We have to get the pointer now that we have the lock and not earlier
     since another thread might have created a new environment.  */
  ep = __environ;

  size = 0;
  if (ep != NULL)
    {
      for (; *ep != NULL; ++ep)
       if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
         break;
       else
         ++size;
    }

  if (ep == NULL || __builtin_expect (*ep == NULL, 1))
    {
      char **new_environ;

      /* We allocated this space; we can extend it.  */
      new_environ = (char **) realloc (last_environ,
                                   (size + 2) * sizeof (char *));
      if (new_environ == NULL)
       {
         UNLOCK;
         return -1;
       }

      /* 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
# ifdef __GNUC__
         char new_value[namelen + 1 + vallen];
# else
         char *new_value = (char *) alloca (namelen + 1 + vallen);
# endif
# ifdef _LIBC
         __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);
# endif

         new_environ[size] = KNOWN_VALUE (new_value);
         if (__builtin_expect (new_environ[size] == NULL, 1))
#endif
           {
             new_environ[size] = (char *) malloc (namelen + 1 + vallen);
             if (__builtin_expect (new_environ[size] == NULL, 0))
              {
                __set_errno (ENOMEM);
                UNLOCK;
                return -1;
              }

#ifdef USE_TSEARCH
             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);
#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)
       memcpy ((char *) new_environ, (char *) __environ,
              size * sizeof (char *));

      new_environ[size + 1] = NULL;

      last_environ = __environ = new_environ;
    }
  else if (replace)
    {
      char *np;

      /* Use the user string if given.  */
      if (combined != NULL)
       np = (char *) combined;
      else
       {
#ifdef USE_TSEARCH
# ifdef __GNUC__
         char new_value[namelen + 1 + vallen];
# else
         char *new_value = (char *) alloca (namelen + 1 + vallen);
# endif
# ifdef _LIBC
         __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);
# endif

         np = KNOWN_VALUE (new_value);
         if (__builtin_expect (np == NULL, 1))
#endif
           {
             np = malloc (namelen + 1 + vallen);
             if (__builtin_expect (np == NULL, 0))
              {
                UNLOCK;
                return -1;
              }

#ifdef USE_TSEARCH
             memcpy (np, new_value, namelen + 1 + vallen);
#else
             memcpy (np, name, namelen);
             np[namelen] = '=';
             memcpy (&np[namelen + 1], value, vallen);
#endif
             /* And remember the value.  */
             STORE_VALUE (np);
           }
       }

      *ep = np;
    }

  UNLOCK;

  return 0;
}

Here is the call graph for this function:

Definition at line 318 of file setenv.c.

{
  LOCK;

  if (__environ == last_environ && __environ != NULL)
    {
      /* We allocated this environment so we can free it.  */
      free (__environ);
      last_environ = NULL;
    }

  /* Clear the environment pointer removes the whole environment.  */
  __environ = NULL;

  UNLOCK;

  return 0;
}
int setenv ( char *  name,
const char *  value,
int  replace 
) const

Definition at line 263 of file setenv.c.

{
  if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

  return __add_to_environ (name, value, NULL, replace);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int unsetenv ( char *  name) const

Definition at line 278 of file setenv.c.

{
  size_t len;
  char **ep;

  if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

  len = strlen (name);

  LOCK;

  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;

       do
         dp[0] = dp[1];
       while (*dp++);
       /* Continue the loop in case NAME appears again.  */
      }
    else
      ++ep;

  UNLOCK;

  return 0;
}

Here is the call graph for this function:


Variable Documentation

char** environ

Definition at line 22 of file sysdep.c.

char** last_environ [static]

Definition at line 100 of file setenv.c.