1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1985-2012 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * David Korn <dgk@research.att.com> *
19da2e3ebdSchin * Phong Vo <kpv@research.att.com> *
20da2e3ebdSchin * *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #pragma prototyped
237c2fbfb3SApril Chin
247c2fbfb3SApril Chin #include "intercepts.h"
257c2fbfb3SApril Chin
267c2fbfb3SApril Chin #include <fs3d.h>
277c2fbfb3SApril Chin
28da2e3ebdSchin /*
29da2e3ebdSchin * put name=value in the environment
30da2e3ebdSchin * pointer to value returned
31da2e3ebdSchin * environ==0 is ok
32da2e3ebdSchin *
33da2e3ebdSchin * setenviron("N=V") add N=V
34da2e3ebdSchin * setenviron("N") delete N
35da2e3ebdSchin * setenviron(0) expect more (pre-fork optimization)
36da2e3ebdSchin *
37da2e3ebdSchin * _ always placed at the top
38da2e3ebdSchin */
39da2e3ebdSchin
40da2e3ebdSchin #define INCREMENT 16 /* environ increment */
41da2e3ebdSchin
42da2e3ebdSchin char*
setenviron(const char * akey)43da2e3ebdSchin setenviron(const char* akey)
44da2e3ebdSchin {
457c2fbfb3SApril Chin #undef setenviron
46da2e3ebdSchin static char** envv; /* recorded environ */
47da2e3ebdSchin static char** next; /* next free slot */
48da2e3ebdSchin static char** last; /* last free slot (0) */
49da2e3ebdSchin static char ok[] = ""; /* delete/optimization ok return*/
50da2e3ebdSchin
51da2e3ebdSchin char* key = (char*)akey;
52da2e3ebdSchin register char** v = environ;
53da2e3ebdSchin register char** p = envv;
54da2e3ebdSchin register char* s;
55da2e3ebdSchin register char* t;
56da2e3ebdSchin int n;
57da2e3ebdSchin
58da2e3ebdSchin ast.env_serial++;
597c2fbfb3SApril Chin if (intercepts.intercept_setenviron)
607c2fbfb3SApril Chin return (*intercepts.intercept_setenviron)(akey);
61da2e3ebdSchin if (p && !v)
62da2e3ebdSchin {
63da2e3ebdSchin environ = next = p;
64da2e3ebdSchin *++next = 0;
65da2e3ebdSchin }
66da2e3ebdSchin else if (p != v || !v)
67da2e3ebdSchin {
68da2e3ebdSchin if (v)
69da2e3ebdSchin {
70da2e3ebdSchin while (*v++);
71da2e3ebdSchin n = v - environ + INCREMENT;
72da2e3ebdSchin v = environ;
73da2e3ebdSchin }
74da2e3ebdSchin else
75da2e3ebdSchin n = INCREMENT;
76da2e3ebdSchin if (!p || (last - p + 1) < n)
77da2e3ebdSchin {
78da2e3ebdSchin if (!p && fs3d(FS3D_TEST))
79da2e3ebdSchin {
80da2e3ebdSchin /*
81da2e3ebdSchin * kick 3d initialization
82da2e3ebdSchin */
83da2e3ebdSchin
84*b30d1939SAndy Fiddaman close(open(".", O_RDONLY|O_cloexec));
85da2e3ebdSchin v = environ;
86da2e3ebdSchin }
87da2e3ebdSchin if (!(p = newof(p, char*, n, 0)))
88da2e3ebdSchin return 0;
89da2e3ebdSchin last = p + n - 1;
90da2e3ebdSchin }
91da2e3ebdSchin envv = environ = p;
92da2e3ebdSchin if (v && v[0] && v[0][0] == '_' && v[0][1] == '=')
93da2e3ebdSchin *p++ = *v++;
94da2e3ebdSchin else
95da2e3ebdSchin *p++ = "_=";
96da2e3ebdSchin if (!v)
97da2e3ebdSchin *p = 0;
98da2e3ebdSchin else
99da2e3ebdSchin while (*p = *v++)
100da2e3ebdSchin if (p[0][0] == '_' && p[0][1] == '=')
101da2e3ebdSchin envv[0] = *p;
102da2e3ebdSchin else
103da2e3ebdSchin p++;
104da2e3ebdSchin next = p;
105da2e3ebdSchin p = envv;
106da2e3ebdSchin }
107da2e3ebdSchin else if (next == last)
108da2e3ebdSchin {
109da2e3ebdSchin n = last - v + INCREMENT + 1;
110da2e3ebdSchin if (!(p = newof(p, char*, n, 0)))
111da2e3ebdSchin return 0;
112da2e3ebdSchin last = p + n - 1;
113da2e3ebdSchin next = last - INCREMENT;
114da2e3ebdSchin envv = environ = p;
115da2e3ebdSchin }
116da2e3ebdSchin if (!key)
117da2e3ebdSchin return ok;
118da2e3ebdSchin for (; s = *p; p++)
119da2e3ebdSchin {
120da2e3ebdSchin t = key;
121da2e3ebdSchin do
122da2e3ebdSchin {
123da2e3ebdSchin if (!*t || *t == '=')
124da2e3ebdSchin {
125da2e3ebdSchin if (*s == '=')
126da2e3ebdSchin {
127da2e3ebdSchin if (!*t)
128da2e3ebdSchin {
129da2e3ebdSchin v = p++;
130da2e3ebdSchin while (*v++ = *p++);
131da2e3ebdSchin next--;
132da2e3ebdSchin return ok;
133da2e3ebdSchin }
134da2e3ebdSchin *p = key;
135da2e3ebdSchin return (s = strchr(key, '=')) ? s + 1 : (char*)0;
136da2e3ebdSchin }
137da2e3ebdSchin break;
138da2e3ebdSchin }
139da2e3ebdSchin } while (*t++ == *s++);
140da2e3ebdSchin }
141da2e3ebdSchin if (!(s = strchr(key, '=')))
142da2e3ebdSchin return ok;
143da2e3ebdSchin p = next;
144da2e3ebdSchin *++next = 0;
145da2e3ebdSchin *p = key;
146da2e3ebdSchin return s + 1;
147da2e3ebdSchin }
148