da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include "intercepts.h"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include <fs3d.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * put name=value in the environment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pointer to value returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * environ==0 is ok
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * setenviron("N=V") add N=V
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * setenviron("N") delete N
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * setenviron(0) expect more (pre-fork optimization)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * _ always placed at the top
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INCREMENT 16 /* environ increment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsetenviron(const char* akey)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#undef setenviron
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char** envv; /* recorded environ */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char** next; /* next free slot */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char** last; /* last free slot (0) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char ok[] = ""; /* delete/optimization ok return*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* key = (char*)akey;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char** v = environ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char** p = envv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ast.env_serial++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (intercepts.intercept_setenviron)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return (*intercepts.intercept_setenviron)(akey);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p && !v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin environ = next = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *++next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (p != v || !v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*v++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = v - environ + INCREMENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = environ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = INCREMENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p || (last - p + 1) < n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p && fs3d(FS3D_TEST))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * kick 3d initialization
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(open(".", O_RDONLY));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = environ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = newof(p, char*, n, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = p + n - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envv = environ = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (v && v[0] && v[0][0] == '_' && v[0][1] == '=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = *v++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = "_=";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*p = *v++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p[0][0] == '_' && p[0][1] == '=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envv[0] = *p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = envv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (next == last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = last - v + INCREMENT + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = newof(p, char*, n, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = p + n - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next = last - INCREMENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envv = environ = p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!key)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; s = *p; p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*t || *t == '=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == '=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = p++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*v++ = *p++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (s = strchr(key, '=')) ? s + 1 : (char*)0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (*t++ == *s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = strchr(key, '=')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return ok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *++next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p = key;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return s + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}