+++ /dev/null
-/*
- * (c) The GRASP/AQUA Project, Glasgow University, 1995-1996
- *
- * \subsection[env.lc]{Environment Handling for LibPosix}
- *
- * Many useful environment functions are not necessarily provided by libc.
- * To get around this problem, we introduce our own. The first time that
- * you modify your environment, we copy the environment wholesale into
- * malloc'ed locations, so that subsequent modifications can do proper
- * memory management. The $environ$ variable is updated with a pointer
- * to the current environment so that the normal $getenv$ and $exec*$ functions
- * should continue to work properly.
- */
-
-#include "Rts.h"
-#include "libposix.h"
-
-/* Switch this on once we've moved the environment to the malloc arena */
-int dirtyEnv = 0;
-
-/*
- * For some reason, OSF turns off the prototype for this if we're
- * _POSIX_SOURCE. Seems to me that this ought to be an ANSI-ism
- * rather than a POSIX-ism, but no matter. (JSM(?))
- */
-
-char *
-strDup(const char *src)
-{
- int len = strlen(src) + 1;
- char *dst;
-
- if ((dst = malloc(len)) != NULL)
- memcpy(dst, src, len);
- return dst;
-}
-
-/* Replace the entire environment */
-int
-setenviron(char **envp)
-{
- char **old = environ;
- int dirtyOld = dirtyEnv;
- int i;
-
- /* A quick hack to move the strings out of the heap */
- environ = envp;
- if (copyenv() != 0) {
- environ = old;
- return -1;
- }
- /* Release the old space if we allocated it ourselves earlier */
- if (dirtyOld) {
- for (i = 0; old[i] != NULL; i++)
- free(old[i]);
- free(old);
- }
- return 0;
-}
-
-/* Copy initial environment into malloc arena */
-int
-copyenv(void)
-{
- char **new;
- int i;
-
- for (i = 0; environ[i] != NULL; i++)
- ;
-
- if ((new = (char **) malloc((i + 1) * sizeof(char *))) == NULL)
- return -1;
-
- new[i] = NULL;
-
- while (--i >= 0) {
- if ((new[i] = strDup(environ[i])) == NULL) {
- while (new[++i] != NULL)
- free(new[i]);
- free(new);
- return -1;
- }
- }
- environ = new;
- dirtyEnv = 1;
- return 0;
-}
-
-/* Set or replace an environment variable
- * simonm 14/2/96 - this is different to the standard C library
- * implementation and the prototypes clash, so I'm calling it _setenv.
- */
-int
-_setenv(char *mapping)
-{
- int i, keylen;
- char *p;
- char **new;
-
- /* We must have a non-empty key and an '=' */
- if (mapping[0] == '=' || (p = strchr(mapping, '=')) == NULL) {
- errno = EINVAL;
- return -1;
- }
- /* Include through the '=' for matching */
- keylen = p - mapping + 1;
-
- if (!dirtyEnv && copyenv() != 0)
- return -1;
-
- if ((p = strDup(mapping)) == NULL)
- return -1;
-
- /* Look for an existing key that matches */
- for (i = 0; environ[i] != NULL && strncmp(environ[i], p, keylen) != 0; i++);
-
- if (environ[i] != NULL) {
- free(environ[i]);
- environ[i] = p;
- } else {
- /* We want to grow the table by *two*, one for the new entry, one for the terminator */
- if ((new = (char **) realloc((void*)environ, (i + 2) * sizeof(char *))) == NULL) {
- free(p);
- return -1;
- }
- new[i] = p;
- new[i + 1] = NULL;
- environ = new;
- }
- return 0;
-}
-
-/* Delete a variable from the environment */
-int
-delenv(char *name)
-{
- int i, keylen;
-
- if (strchr(name, '=') != NULL) {
- errno = EINVAL;
- return -1;
- }
- keylen = strlen(name);
-
- if (!dirtyEnv && copyenv() != 0)
- return -1;
-
- /* Look for a matching key */
- for (i = 0; environ[i] != NULL &&
- (strncmp(environ[i], name, keylen) != 0 || environ[i][keylen] != '='); i++);
-
- /* Don't complain if it wasn't there to begin with */
- if (environ[i] == NULL) {
- return 0;
- }
- free(environ[i]);
-
- do {
- environ[i] = environ[i + 1];
- i++;
- } while (environ[i] != NULL);
-
- return 0;
-}