14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
238462SApril.Chin@Sun.COM
248462SApril.Chin@Sun.COM #include "intercepts.h"
258462SApril.Chin@Sun.COM
268462SApril.Chin@Sun.COM #include <fs3d.h>
278462SApril.Chin@Sun.COM
284887Schin /*
294887Schin * put name=value in the environment
304887Schin * pointer to value returned
314887Schin * environ==0 is ok
324887Schin *
334887Schin * setenviron("N=V") add N=V
344887Schin * setenviron("N") delete N
354887Schin * setenviron(0) expect more (pre-fork optimization)
364887Schin *
374887Schin * _ always placed at the top
384887Schin */
394887Schin
404887Schin #define INCREMENT 16 /* environ increment */
414887Schin
424887Schin char*
setenviron(const char * akey)434887Schin setenviron(const char* akey)
444887Schin {
458462SApril.Chin@Sun.COM #undef setenviron
464887Schin static char** envv; /* recorded environ */
474887Schin static char** next; /* next free slot */
484887Schin static char** last; /* last free slot (0) */
494887Schin static char ok[] = ""; /* delete/optimization ok return*/
504887Schin
514887Schin char* key = (char*)akey;
524887Schin register char** v = environ;
534887Schin register char** p = envv;
544887Schin register char* s;
554887Schin register char* t;
564887Schin int n;
574887Schin
584887Schin ast.env_serial++;
598462SApril.Chin@Sun.COM if (intercepts.intercept_setenviron)
608462SApril.Chin@Sun.COM return (*intercepts.intercept_setenviron)(akey);
614887Schin if (p && !v)
624887Schin {
634887Schin environ = next = p;
644887Schin *++next = 0;
654887Schin }
664887Schin else if (p != v || !v)
674887Schin {
684887Schin if (v)
694887Schin {
704887Schin while (*v++);
714887Schin n = v - environ + INCREMENT;
724887Schin v = environ;
734887Schin }
744887Schin else
754887Schin n = INCREMENT;
764887Schin if (!p || (last - p + 1) < n)
774887Schin {
784887Schin if (!p && fs3d(FS3D_TEST))
794887Schin {
804887Schin /*
814887Schin * kick 3d initialization
824887Schin */
834887Schin
844887Schin close(open(".", O_RDONLY));
854887Schin v = environ;
864887Schin }
874887Schin if (!(p = newof(p, char*, n, 0)))
884887Schin return 0;
894887Schin last = p + n - 1;
904887Schin }
914887Schin envv = environ = p;
924887Schin if (v && v[0] && v[0][0] == '_' && v[0][1] == '=')
934887Schin *p++ = *v++;
944887Schin else
954887Schin *p++ = "_=";
964887Schin if (!v)
974887Schin *p = 0;
984887Schin else
994887Schin while (*p = *v++)
1004887Schin if (p[0][0] == '_' && p[0][1] == '=')
1014887Schin envv[0] = *p;
1024887Schin else
1034887Schin p++;
1044887Schin next = p;
1054887Schin p = envv;
1064887Schin }
1074887Schin else if (next == last)
1084887Schin {
1094887Schin n = last - v + INCREMENT + 1;
1104887Schin if (!(p = newof(p, char*, n, 0)))
1114887Schin return 0;
1124887Schin last = p + n - 1;
1134887Schin next = last - INCREMENT;
1144887Schin envv = environ = p;
1154887Schin }
1164887Schin if (!key)
1174887Schin return ok;
1184887Schin for (; s = *p; p++)
1194887Schin {
1204887Schin t = key;
1214887Schin do
1224887Schin {
1234887Schin if (!*t || *t == '=')
1244887Schin {
1254887Schin if (*s == '=')
1264887Schin {
1274887Schin if (!*t)
1284887Schin {
1294887Schin v = p++;
1304887Schin while (*v++ = *p++);
1314887Schin next--;
1324887Schin return ok;
1334887Schin }
1344887Schin *p = key;
1354887Schin return (s = strchr(key, '=')) ? s + 1 : (char*)0;
1364887Schin }
1374887Schin break;
1384887Schin }
1394887Schin } while (*t++ == *s++);
1404887Schin }
1414887Schin if (!(s = strchr(key, '=')))
1424887Schin return ok;
1434887Schin p = next;
1444887Schin *++next = 0;
1454887Schin *p = key;
1464887Schin return s + 1;
1474887Schin }
148