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