xref: /onnv-gate/usr/src/lib/libast/common/misc/setenviron.c (revision 12068:08a39a083754)
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