Start converting to GPL v3+ (ref: ticket #23900)
[screen-lua.git] / src / putenv.c
blob6e8f3efe32610719708c28794d50f56380fd2878
1 /* Copyright (c) 1993-2002
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Copyright (c) 1987 Oliver Laumann
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file COPYING); if not, see
18 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
21 ****************************************************************
25 * putenv -- put value into environment
27 * Usage: i = putenv (string)
28 * int i;
29 * char *string;
31 * where string is of the form <name>=<value>.
32 * If "value" is 0, then "name" will be deleted from the environment.
33 * Putenv returns 0 normally, -1 on error (not enough core for malloc).
35 * Putenv may need to add a new name into the environment, or to
36 * associate a value longer than the current value with a particular
37 * name. So, to make life simpler, putenv() copies your entire
38 * environment into the heap (i.e. malloc()) from the stack
39 * (i.e. where it resides when your process is initiated) the first
40 * time you call it.
42 * HISTORY
43 * 3-Sep-91 Michael Schroeder (mlschroe). Modified to behave as
44 * as putenv.
45 * 16-Aug-91 Tim MacKenzie (tym) at Monash University. Modified for
46 * use in screen (iScreen) (ignores final int parameter)
47 * 14-Oct-85 Michael Mauldin (mlm) at Carnegie-Mellon University
48 * Ripped out of CMU lib for Rob-O-Matic portability
49 * 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University
50 * Created for VAX. Too bad Bell Labs didn't provide this. It's
51 * unfortunate that you have to copy the whole environment onto the
52 * heap, but the bookkeeping-and-not-so-much-copying approach turns
53 * out to be much hairier. So, I decided to do the simple thing,
54 * copying the entire environment onto the heap the first time you
55 * call putenv(), then doing realloc() uniformly later on.
58 #include "config.h"
60 #ifdef NEEDPUTENV
62 #if defined(__STDC__)
63 # define __P(a) a
64 #else
65 # define __P(a) ()
66 #endif
68 char *malloc __P((int));
69 char *realloc __P((char *, int));
70 void free __P((char *));
71 int sprintf __P((char *, char *, ...));
73 #define EXTRASIZE 5 /* increment to add to env. size */
75 static int envsize = -1; /* current size of environment */
76 extern char **environ; /* the global which is your env. */
78 static int findenv __P((char *)); /* look for a name in the env. */
79 static int newenv __P((void)); /* copy env. from stack to heap */
80 static int moreenv __P((void)); /* incr. size of env. */
82 int
83 unsetenv(name)
84 char *name;
86 register int i;
88 if (envsize < 0)
89 { /* first time putenv called */
90 if (newenv() < 0) /* copy env. to heap */
91 return -1;
93 i = findenv(name);
94 if (i < 0)
95 return 0; /* Already here */
97 free(environ[i]);
98 if (envsize > 0)
99 envsize--;
100 for (; environ[i]; i++)
101 environ[i] = environ[i+1];
102 return 0; /* Already here */
106 putenv(string)
107 char *string;
109 register int i;
110 register char *p;
112 if (envsize < 0)
113 { /* first time putenv called */
114 if (newenv() < 0) /* copy env. to heap */
115 return -1;
118 i = findenv(string); /* look for name in environment */
120 if (i < 0)
121 { /* name must be added */
122 for (i = 0; environ[i]; i++);
123 if (i >= (envsize - 1))
124 { /* need new slot */
125 if (moreenv() < 0)
126 return -1;
128 p = malloc(strlen(string) + 1);
129 if (p == 0) /* not enough core */
130 return -1;
131 environ[i + 1] = 0; /* new end of env. */
133 else
134 { /* name already in env. */
135 p = realloc(environ[i], strlen(string) + 1);
136 if (p == 0)
137 return -1;
139 sprintf(p, "%s", string); /* copy into env. */
140 environ[i] = p;
142 return 0;
145 static int
146 findenv(name)
147 char *name;
149 register char *namechar, *envchar;
150 register int i, found;
152 found = 0;
153 for (i = 0; environ[i] && !found; i++)
155 envchar = environ[i];
156 namechar = name;
157 while (*namechar && *namechar != '=' && (*namechar == *envchar))
159 namechar++;
160 envchar++;
162 found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
164 return found ? i - 1 : -1;
167 static int
168 newenv()
170 register char **env, *elem;
171 register int i, esize;
173 for (i = 0; environ[i]; i++)
175 esize = i + EXTRASIZE + 1;
176 env = (char **)malloc(esize * sizeof (elem));
177 if (env == 0)
178 return -1;
180 for (i = 0; environ[i]; i++)
182 elem = malloc(strlen(environ[i]) + 1);
183 if (elem == 0)
184 return -1;
185 env[i] = elem;
186 strcpy(elem, environ[i]);
189 env[i] = 0;
190 environ = env;
191 envsize = esize;
192 return 0;
195 static int
196 moreenv()
198 register int esize;
199 register char **env;
201 esize = envsize + EXTRASIZE;
202 env = (char **)realloc((char *)environ, esize * sizeof (*env));
203 if (env == 0)
204 return -1;
205 environ = env;
206 envsize = esize;
207 return 0;
210 #endif /* NEEDPUTENV */