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