2 * (c) The GRASP/AQUA Project, Glasgow University, 1995-1996
4 * \subsection[env.lc]{Environment Handling for LibPosix}
6 * Many useful environment functions are not necessarily provided by libc.
7 * To get around this problem, we introduce our own. The first time that
8 * you modify your environment, we copy the environment wholesale into
9 * malloc'ed locations, so that subsequent modifications can do proper
10 * memory management. The $environ$ variable is updated with a pointer
11 * to the current environment so that the normal $getenv$ and $exec*$ functions
12 * should continue to work properly.
18 /* Switch this on once we've moved the environment to the malloc arena */
22 * For some reason, OSF turns off the prototype for this if we're
23 * _POSIX_SOURCE. Seems to me that this ought to be an ANSI-ism
24 * rather than a POSIX-ism, but no matter. (JSM(?))
28 strDup(const char *src)
30 int len = strlen(src) + 1;
33 if ((dst = malloc(len)) != NULL)
34 memcpy(dst, src, len);
38 /* Replace the entire environment */
40 setenviron(char **envp)
43 int dirtyOld = dirtyEnv;
46 /* A quick hack to move the strings out of the heap */
52 /* Release the old space if we allocated it ourselves earlier */
54 for (i = 0; old[i] != NULL; i++)
61 /* Copy initial environment into malloc arena */
68 for (i = 0; environ[i] != NULL; i++)
71 if ((new = (char **) malloc((i + 1) * sizeof(char *))) == NULL)
77 if ((new[i] = strDup(environ[i])) == NULL) {
78 while (new[++i] != NULL)
89 /* Set or replace an environment variable
90 * simonm 14/2/96 - this is different to the standard C library
91 * implementation and the prototypes clash, so I'm calling it _setenv.
94 _setenv(char *mapping)
100 /* We must have a non-empty key and an '=' */
101 if (mapping[0] == '=' || (p = strchr(mapping, '=')) == NULL) {
105 /* Include through the '=' for matching */
106 keylen = p - mapping + 1;
108 if (!dirtyEnv && copyenv() != 0)
111 if ((p = strDup(mapping)) == NULL)
114 /* Look for an existing key that matches */
115 for (i = 0; environ[i] != NULL && strncmp(environ[i], p, keylen) != 0; i++);
117 if (environ[i] != NULL) {
121 /* We want to grow the table by *two*, one for the new entry, one for the terminator */
122 if ((new = (char **) realloc((void*)environ, (i + 2) * sizeof(char *))) == NULL) {
133 /* Delete a variable from the environment */
139 if (strchr(name, '=') != NULL) {
143 keylen = strlen(name);
145 if (!dirtyEnv && copyenv() != 0)
148 /* Look for a matching key */
149 for (i = 0; environ[i] != NULL &&
150 (strncmp(environ[i], name, keylen) != 0 || environ[i][keylen] != '='); i++);
152 /* Don't complain if it wasn't there to begin with */
153 if (environ[i] == NULL) {
159 environ[i] = environ[i + 1];
161 } while (environ[i] != NULL);