Rearrange the python scripting support a bit.
[screen-lua.git] / src / putenv.c
blob2a907f902553a2da9c597da3edba8e1d57a031f1
1 /* Copyright (c) 2008, 2009
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Micah Cowan (micah@cowan.name)
5 * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
6 * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
7 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
8 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
9 * Copyright (c) 1987 Oliver Laumann
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3, or (at your option)
14 * any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program (see the file COPYING); if not, see
23 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 ****************************************************************
30 * putenv -- put value into environment
32 * Usage: i = putenv (string)
33 * int i;
34 * char *string;
36 * where string is of the form <name>=<value>.
37 * If "value" is 0, then "name" will be deleted from the environment.
38 * Putenv returns 0 normally, -1 on error (not enough core for malloc).
40 * Putenv may need to add a new name into the environment, or to
41 * associate a value longer than the current value with a particular
42 * name. So, to make life simpler, putenv() copies your entire
43 * environment into the heap (i.e. malloc()) from the stack
44 * (i.e. where it resides when your process is initiated) the first
45 * time you call it.
47 * HISTORY
48 * 3-Sep-91 Michael Schroeder (mlschroe). Modified to behave as
49 * as putenv.
50 * 16-Aug-91 Tim MacKenzie (tym) at Monash University. Modified for
51 * use in screen (iScreen) (ignores final int parameter)
52 * 14-Oct-85 Michael Mauldin (mlm) at Carnegie-Mellon University
53 * Ripped out of CMU lib for Rob-O-Matic portability
54 * 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University
55 * Created for VAX. Too bad Bell Labs didn't provide this. It's
56 * unfortunate that you have to copy the whole environment onto the
57 * heap, but the bookkeeping-and-not-so-much-copying approach turns
58 * out to be much hairier. So, I decided to do the simple thing,
59 * copying the entire environment onto the heap the first time you
60 * call putenv(), then doing realloc() uniformly later on.
63 #include "config.h"
65 #ifdef NEEDPUTENV
67 #if defined(__STDC__)
68 # define __P(a) a
69 #else
70 # define __P(a) ()
71 #endif
73 char *malloc __P((int));
74 char *realloc __P((char *, int));
75 void free __P((char *));
76 int sprintf __P((char *, char *, ...));
78 #define EXTRASIZE 5 /* increment to add to env. size */
80 static int envsize = -1; /* current size of environment */
81 extern char **environ; /* the global which is your env. */
83 static int findenv __P((char *)); /* look for a name in the env. */
84 static int newenv __P((void)); /* copy env. from stack to heap */
85 static int moreenv __P((void)); /* incr. size of env. */
87 int
88 unsetenv(name)
89 char *name;
91 register int i;
93 if (envsize < 0)
94 { /* first time putenv called */
95 if (newenv() < 0) /* copy env. to heap */
96 return -1;
98 i = findenv(name);
99 if (i < 0)
100 return 0; /* Already here */
102 free(environ[i]);
103 if (envsize > 0)
104 envsize--;
105 for (; environ[i]; i++)
106 environ[i] = environ[i+1];
107 return 0; /* Already here */
111 putenv(string)
112 char *string;
114 register int i;
115 register char *p;
117 if (envsize < 0)
118 { /* first time putenv called */
119 if (newenv() < 0) /* copy env. to heap */
120 return -1;
123 i = findenv(string); /* look for name in environment */
125 if (i < 0)
126 { /* name must be added */
127 for (i = 0; environ[i]; i++);
128 if (i >= (envsize - 1))
129 { /* need new slot */
130 if (moreenv() < 0)
131 return -1;
133 p = malloc(strlen(string) + 1);
134 if (p == 0) /* not enough core */
135 return -1;
136 environ[i + 1] = 0; /* new end of env. */
138 else
139 { /* name already in env. */
140 p = realloc(environ[i], strlen(string) + 1);
141 if (p == 0)
142 return -1;
144 sprintf(p, "%s", string); /* copy into env. */
145 environ[i] = p;
147 return 0;
150 static int
151 findenv(name)
152 char *name;
154 register char *namechar, *envchar;
155 register int i, found;
157 found = 0;
158 for (i = 0; environ[i] && !found; i++)
160 envchar = environ[i];
161 namechar = name;
162 while (*namechar && *namechar != '=' && (*namechar == *envchar))
164 namechar++;
165 envchar++;
167 found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
169 return found ? i - 1 : -1;
172 static int
173 newenv()
175 register char **env, *elem;
176 register int i, esize;
178 for (i = 0; environ[i]; i++)
180 esize = i + EXTRASIZE + 1;
181 env = (char **)malloc(esize * sizeof (elem));
182 if (env == 0)
183 return -1;
185 for (i = 0; environ[i]; i++)
187 elem = malloc(strlen(environ[i]) + 1);
188 if (elem == 0)
189 return -1;
190 env[i] = elem;
191 strcpy(elem, environ[i]);
194 env[i] = 0;
195 environ = env;
196 envsize = esize;
197 return 0;
200 static int
201 moreenv()
203 register int esize;
204 register char **env;
206 esize = envsize + EXTRASIZE;
207 env = (char **)realloc((char *)environ, esize * sizeof (*env));
208 if (env == 0)
209 return -1;
210 environ = env;
211 envsize = esize;
212 return 0;
215 #endif /* NEEDPUTENV */