setenv.c revision 60484
1/* Copyright (C) 1992, 1995, 1996, 1997 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., 59 Temple Place - Suite 330, 17 Boston, MA 02111-1307, USA. */ 18 19#if HAVE_CONFIG_H 20# include <config.h> 21#endif 22 23#include "ansidecl.h" 24#include <sys/types.h> /* For `size_t' */ 25#include <stdio.h> /* For `NULL' */ 26 27#include <errno.h> 28#if !defined(errno) && !defined(HAVE_ERRNO_DECL) 29extern int errno; 30#endif 31#define __set_errno(ev) ((errno) = (ev)) 32 33#if HAVE_STDLIB_H 34# include <stdlib.h> 35#endif 36#if HAVE_STRING_H 37# include <string.h> 38#endif 39#if HAVE_UNISTD_H 40# include <unistd.h> 41#endif 42 43#define __environ environ 44#ifndef HAVE_ENVIRON_DECL 45extern char **environ; 46#endif 47 48/* LOCK and UNLOCK are defined as no-ops. This makes the libiberty 49 * implementation MT-Unsafe. */ 50#define LOCK 51#define UNLOCK 52 53/* Below this point, it's verbatim code from the glibc-2.0 implementation */ 54 55/* If this variable is not a null pointer we allocated the current 56 environment. */ 57static char **last_environ; 58 59 60int 61setenv (name, value, replace) 62 const char *name; 63 const char *value; 64 int replace; 65{ 66 register char **ep; 67 register size_t size; 68 const size_t namelen = strlen (name); 69 const size_t vallen = strlen (value) + 1; 70 71 LOCK; 72 73 size = 0; 74 if (__environ != NULL) 75 for (ep = __environ; *ep != NULL; ++ep) 76 if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') 77 break; 78 else 79 ++size; 80 81 if (__environ == NULL || *ep == NULL) 82 { 83 char **new_environ; 84 if (__environ == last_environ && __environ != NULL) 85 /* We allocated this space; we can extend it. */ 86 new_environ = (char **) realloc (last_environ, 87 (size + 2) * sizeof (char *)); 88 else 89 new_environ = (char **) malloc ((size + 2) * sizeof (char *)); 90 91 if (new_environ == NULL) 92 { 93 UNLOCK; 94 return -1; 95 } 96 97 new_environ[size] = malloc (namelen + 1 + vallen); 98 if (new_environ[size] == NULL) 99 { 100 free ((char *) new_environ); 101 __set_errno (ENOMEM); 102 UNLOCK; 103 return -1; 104 } 105 106 if (__environ != last_environ) 107 memcpy ((char *) new_environ, (char *) __environ, 108 size * sizeof (char *)); 109 110 memcpy (new_environ[size], name, namelen); 111 new_environ[size][namelen] = '='; 112 memcpy (&new_environ[size][namelen + 1], value, vallen); 113 114 new_environ[size + 1] = NULL; 115 116 last_environ = __environ = new_environ; 117 } 118 else if (replace) 119 { 120 size_t len = strlen (*ep); 121 if (len + 1 < namelen + 1 + vallen) 122 { 123 /* The existing string is too short; malloc a new one. */ 124 char *new = malloc (namelen + 1 + vallen); 125 if (new == NULL) 126 { 127 UNLOCK; 128 return -1; 129 } 130 *ep = new; 131 } 132 memcpy (*ep, name, namelen); 133 (*ep)[namelen] = '='; 134 memcpy (&(*ep)[namelen + 1], value, vallen); 135 } 136 137 UNLOCK; 138 139 return 0; 140} 141 142void 143unsetenv (name) 144 const char *name; 145{ 146 const size_t len = strlen (name); 147 char **ep; 148 149 LOCK; 150 151 for (ep = __environ; *ep; ++ep) 152 if (!strncmp (*ep, name, len) && (*ep)[len] == '=') 153 { 154 /* Found it. Remove this pointer by moving later ones back. */ 155 char **dp = ep; 156 do 157 dp[0] = dp[1]; 158 while (*dp++); 159 /* Continue the loop in case NAME appears again. */ 160 } 161 162 UNLOCK; 163} 164