[BACK]Return to setenv.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils / dist / libiberty

Annotation of src/external/gpl3/binutils/dist/libiberty/setenv.c, Revision 1.1.1.1

1.1       skrll       1: /* Copyright (C) 1992, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
                      2:    This file based on setenv.c in the GNU C Library.
                      3:
                      4:    The GNU C Library is free software; you can redistribute it and/or
                      5:    modify it under the terms of the GNU Library General Public License as
                      6:    published by the Free Software Foundation; either version 2 of the
                      7:    License, or (at your option) any later version.
                      8:
                      9:    The GNU C Library is distributed in the hope that it will be useful,
                     10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:    Library General Public License for more details.
                     13:
                     14:    You should have received a copy of the GNU Library General Public
                     15:    License along with the GNU C Library; see the file COPYING.LIB.  If not,
                     16:    write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
                     17:    Boston, MA 02110-1301, USA.  */
                     18:
                     19:
                     20: /*
                     21:
                     22: @deftypefn Supplemental int setenv (const char *@var{name}, const char *@var{value}, int @var{overwrite})
                     23: @deftypefnx Supplemental void unsetenv (const char *@var{name})
                     24:
                     25: @code{setenv} adds @var{name} to the environment with value
                     26: @var{value}.  If the name was already present in the environment,
                     27: the new value will be stored only if @var{overwrite} is nonzero.
                     28: The companion @code{unsetenv} function removes @var{name} from the
                     29: environment.  This implementation is not safe for multithreaded code.
                     30:
                     31: @end deftypefn
                     32:
                     33: */
                     34:
                     35: #if HAVE_CONFIG_H
                     36: # include <config.h>
                     37: #endif
                     38:
                     39: #define setenv libiberty_setenv
                     40: #define unsetenv libiberty_unsetenv
                     41:
                     42: #include "ansidecl.h"
                     43: #include <sys/types.h> /* For `size_t' */
                     44: #include <stdio.h>     /* For `NULL' */
                     45:
                     46: #include <errno.h>
                     47: #if !defined(errno) && !defined(HAVE_ERRNO_DECL)
                     48: extern int errno;
                     49: #endif
                     50: #define __set_errno(ev) ((errno) = (ev))
                     51:
                     52: #if HAVE_STDLIB_H
                     53: # include <stdlib.h>
                     54: #endif
                     55: #if HAVE_STRING_H
                     56: # include <string.h>
                     57: #endif
                     58: #if HAVE_UNISTD_H
                     59: # include <unistd.h>
                     60: #endif
                     61:
                     62: #define __environ      environ
                     63: #ifndef HAVE_ENVIRON_DECL
                     64: extern char **environ;
                     65: #endif
                     66:
                     67: #undef setenv
                     68: #undef unsetenv
                     69:
                     70: /* LOCK and UNLOCK are defined as no-ops.  This makes the libiberty
                     71:  * implementation MT-Unsafe. */
                     72: #define LOCK
                     73: #define UNLOCK
                     74:
                     75: /* Below this point, it's verbatim code from the glibc-2.0 implementation */
                     76:
                     77: /* If this variable is not a null pointer we allocated the current
                     78:    environment.  */
                     79: static char **last_environ;
                     80:
                     81:
                     82: int
                     83: setenv (const char *name, const char *value, int replace)
                     84: {
                     85:   register char **ep = 0;
                     86:   register size_t size;
                     87:   const size_t namelen = strlen (name);
                     88:   const size_t vallen = strlen (value) + 1;
                     89:
                     90:   LOCK;
                     91:
                     92:   size = 0;
                     93:   if (__environ != NULL)
                     94:     {
                     95:       for (ep = __environ; *ep != NULL; ++ep)
                     96:        if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
                     97:          break;
                     98:        else
                     99:          ++size;
                    100:     }
                    101:
                    102:   if (__environ == NULL || *ep == NULL)
                    103:     {
                    104:       char **new_environ;
                    105:       if (__environ == last_environ && __environ != NULL)
                    106:        /* We allocated this space; we can extend it.  */
                    107:        new_environ = (char **) realloc (last_environ,
                    108:                                         (size + 2) * sizeof (char *));
                    109:       else
                    110:        new_environ = (char **) malloc ((size + 2) * sizeof (char *));
                    111:
                    112:       if (new_environ == NULL)
                    113:        {
                    114:          UNLOCK;
                    115:          return -1;
                    116:        }
                    117:
                    118:       new_environ[size] = (char *) malloc (namelen + 1 + vallen);
                    119:       if (new_environ[size] == NULL)
                    120:        {
                    121:          free ((char *) new_environ);
                    122:          __set_errno (ENOMEM);
                    123:          UNLOCK;
                    124:          return -1;
                    125:        }
                    126:
                    127:       if (__environ != last_environ)
                    128:        memcpy ((char *) new_environ, (char *) __environ,
                    129:                size * sizeof (char *));
                    130:
                    131:       memcpy (new_environ[size], name, namelen);
                    132:       new_environ[size][namelen] = '=';
                    133:       memcpy (&new_environ[size][namelen + 1], value, vallen);
                    134:
                    135:       new_environ[size + 1] = NULL;
                    136:
                    137:       last_environ = __environ = new_environ;
                    138:     }
                    139:   else if (replace)
                    140:     {
                    141:       size_t len = strlen (*ep);
                    142:       if (len + 1 < namelen + 1 + vallen)
                    143:        {
                    144:          /* The existing string is too short; malloc a new one.  */
                    145:          char *new_string = (char *) malloc (namelen + 1 + vallen);
                    146:          if (new_string == NULL)
                    147:            {
                    148:              UNLOCK;
                    149:              return -1;
                    150:            }
                    151:          *ep = new_string;
                    152:        }
                    153:       memcpy (*ep, name, namelen);
                    154:       (*ep)[namelen] = '=';
                    155:       memcpy (&(*ep)[namelen + 1], value, vallen);
                    156:     }
                    157:
                    158:   UNLOCK;
                    159:
                    160:   return 0;
                    161: }
                    162:
                    163: void
                    164: unsetenv (const char *name)
                    165: {
                    166:   const size_t len = strlen (name);
                    167:   char **ep;
                    168:
                    169:   LOCK;
                    170:
                    171:   for (ep = __environ; *ep; ++ep)
                    172:     if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
                    173:       {
                    174:        /* Found it.  Remove this pointer by moving later ones back.  */
                    175:        char **dp = ep;
                    176:        do
                    177:          dp[0] = dp[1];
                    178:        while (*dp++);
                    179:        /* Continue the loop in case NAME appears again.  */
                    180:       }
                    181:
                    182:   UNLOCK;
                    183: }

CVSweb <webmaster@jp.NetBSD.org>