diff options
Diffstat (limited to '')
-rw-r--r-- | putenv.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/putenv.c b/putenv.c new file mode 100644 index 0000000..2b31f6f --- /dev/null +++ b/putenv.c @@ -0,0 +1,216 @@ +/* Copyright (c) 2008, 2009 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Micah Cowan (micah@cowan.name) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * https://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +/* + * putenv -- put value into environment + * + * Usage: i = putenv (string) + * int i; + * char *string; + * + * where string is of the form <name>=<value>. + * If "value" is 0, then "name" will be deleted from the environment. + * Putenv returns 0 normally, -1 on error (not enough core for malloc). + * + * Putenv may need to add a new name into the environment, or to + * associate a value longer than the current value with a particular + * name. So, to make life simpler, putenv() copies your entire + * environment into the heap (i.e. malloc()) from the stack + * (i.e. where it resides when your process is initiated) the first + * time you call it. + * + * HISTORY + * 3-Sep-91 Michael Schroeder (mlschroe). Modified to behave as + * as putenv. + * 16-Aug-91 Tim MacKenzie (tym) at Monash University. Modified for + * use in screen (iScreen) (ignores final int parameter) + * 14-Oct-85 Michael Mauldin (mlm) at Carnegie-Mellon University + * Ripped out of CMU lib for Rob-O-Matic portability + * 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University + * Created for VAX. Too bad Bell Labs didn't provide this. It's + * unfortunate that you have to copy the whole environment onto the + * heap, but the bookkeeping-and-not-so-much-copying approach turns + * out to be much hairier. So, I decided to do the simple thing, + * copying the entire environment onto the heap the first time you + * call putenv(), then doing realloc() uniformly later on. + */ + +#include "config.h" + +#ifdef NEEDPUTENV + +#if defined(__STDC__) +# define __P(a) a +#else +# define __P(a) () +#endif + +char *malloc __P((int)); +char *realloc __P((char *, int)); +void free __P((char *)); +int sprintf __P((char *, char *, ...)); + +#define EXTRASIZE 5 /* increment to add to env. size */ + +static int envsize = -1; /* current size of environment */ +extern char **environ; /* the global which is your env. */ + +static int findenv __P((char *)); /* look for a name in the env. */ +static int newenv __P((void)); /* copy env. from stack to heap */ +static int moreenv __P((void)); /* incr. size of env. */ + +int +unsetenv(name) +char *name; +{ + register int i; + + if (envsize < 0) + { /* first time putenv called */ + if (newenv() < 0) /* copy env. to heap */ + return -1; + } + i = findenv(name); + if (i < 0) + return 0; /* Already here */ + + free(environ[i]); + if (envsize > 0) + envsize--; + for (; environ[i]; i++) + environ[i] = environ[i+1]; + return 0; /* Already here */ +} + +int +putenv(string) +char *string; +{ + register int i; + register char *p; + + if (envsize < 0) + { /* first time putenv called */ + if (newenv() < 0) /* copy env. to heap */ + return -1; + } + + i = findenv(string); /* look for name in environment */ + + if (i < 0) + { /* name must be added */ + for (i = 0; environ[i]; i++); + if (i >= (envsize - 1)) + { /* need new slot */ + if (moreenv() < 0) + return -1; + } + p = malloc(strlen(string) + 1); + if (p == 0) /* not enough core */ + return -1; + environ[i + 1] = 0; /* new end of env. */ + } + else + { /* name already in env. */ + p = realloc(environ[i], strlen(string) + 1); + if (p == 0) + return -1; + } + sprintf(p, "%s", string); /* copy into env. */ + environ[i] = p; + + return 0; +} + +static int +findenv(name) +char *name; +{ + register char *namechar, *envchar; + register int i, found; + + found = 0; + for (i = 0; environ[i] && !found; i++) + { + envchar = environ[i]; + namechar = name; + while (*namechar && *namechar != '=' && (*namechar == *envchar)) + { + namechar++; + envchar++; + } + found = ((*namechar == '\0' || *namechar == '=') && *envchar == '='); + } + return found ? i - 1 : -1; +} + +static int +newenv() +{ + register char **env, *elem; + register int i, esize; + + for (i = 0; environ[i]; i++) + ; + esize = i + EXTRASIZE + 1; + env = (char **)malloc(esize * sizeof (elem)); + if (env == 0) + return -1; + + for (i = 0; environ[i]; i++) + { + elem = malloc(strlen(environ[i]) + 1); + if (elem == 0) + return -1; + env[i] = elem; + strcpy(elem, environ[i]); + } + + env[i] = 0; + environ = env; + envsize = esize; + return 0; +} + +static int +moreenv() +{ + register int esize; + register char **env; + + esize = envsize + EXTRASIZE; + env = (char **)realloc((char *)environ, esize * sizeof (*env)); + if (env == 0) + return -1; + environ = env; + envsize = esize; + return 0; +} + +#endif /* NEEDPUTENV */ + |