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