2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
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.
20 /* Switch this on once we've moved the environment to the malloc arena */
24 * For some reason, OSF turns off the prototype for this if we're
25 * _POSIX_SOURCE. Seems to me that this ought to be an ANSI-ism
26 * rather than a POSIX-ism, but no matter. (JSM(?))
30 strdup(char *src) /* should be "const char *" but then some
31 bozo OS (e.g., AIX) will come along and disagree.
32 The alt is to rename this routine (WDP 96/01) */
34 int len = strlen(src) + 1;
37 if ((dst = malloc(len)) != NULL)
38 memcpy(dst, src, len);
42 /* Replace the entire environment */
48 int dirtyOld = dirtyEnv;
51 /* A quick hack to move the strings out of the heap */
57 /* Release the old space if we allocated it ourselves earlier */
59 for (i = 0; old[i] != NULL; i++)
66 /* Copy initial environment into malloc arena */
73 for (i = 0; environ[i] != NULL; i++);
75 if ((new = (char **) malloc((i + 1) * sizeof(char *))) == NULL)
81 if ((new[i] = strdup(environ[i])) == NULL) {
82 while (new[++i] != NULL)
93 /* Set or replace an environment variable */
102 /* We must have a non-empty key and an '=' */
103 if (mapping[0] == '=' || (p = strchr(mapping, '=')) == NULL) {
107 /* Include through the '=' for matching */
108 keylen = p - mapping + 1;
110 if (!dirtyEnv && copyenv() != 0)
113 if ((p = strdup(mapping)) == NULL)
116 /* Look for an existing key that matches */
117 for (i = 0; environ[i] != NULL && strncmp(environ[i], p, keylen) != 0; i++);
119 if (environ[i] != NULL) {
123 if ((new = (char **) realloc(environ, (i + 1) * sizeof(char *))) == NULL) {
134 /* Delete a variable from the environment */
141 if (strchr(name, '=') != NULL) {
145 keylen = strlen(name);
147 if (!dirtyEnv && copyenv() != 0)
150 /* Look for a matching key */
151 for (i = 0; environ[i] != NULL &&
152 (strncmp(environ[i], name, keylen) != 0 || environ[i][keylen] != '='); i++);
154 /* Don't complain if it wasn't there to begin with */
155 if (environ[i] == NULL) {
161 environ[i] = environ[i + 1];
163 } while (environ[i] != NULL);