1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2007 AT&T Knowledge Ventures * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Knowledge Ventures * 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 * put name=value in the environment 25 * pointer to value returned 26 * environ==0 is ok 27 * 28 * setenviron("N=V") add N=V 29 * setenviron("N") delete N 30 * setenviron(0) expect more (pre-fork optimization) 31 * 32 * _ always placed at the top 33 */ 34 35 #include <ast.h> 36 #include <fs3d.h> 37 38 #define INCREMENT 16 /* environ increment */ 39 40 char* 41 setenviron(const char* akey) 42 { 43 static char** envv; /* recorded environ */ 44 static char** next; /* next free slot */ 45 static char** last; /* last free slot (0) */ 46 static char ok[] = ""; /* delete/optimization ok return*/ 47 48 char* key = (char*)akey; 49 register char** v = environ; 50 register char** p = envv; 51 register char* s; 52 register char* t; 53 int n; 54 55 ast.env_serial++; 56 if (p && !v) 57 { 58 environ = next = p; 59 *++next = 0; 60 } 61 else if (p != v || !v) 62 { 63 if (v) 64 { 65 while (*v++); 66 n = v - environ + INCREMENT; 67 v = environ; 68 } 69 else 70 n = INCREMENT; 71 if (!p || (last - p + 1) < n) 72 { 73 if (!p && fs3d(FS3D_TEST)) 74 { 75 /* 76 * kick 3d initialization 77 */ 78 79 close(open(".", O_RDONLY)); 80 v = environ; 81 } 82 if (!(p = newof(p, char*, n, 0))) 83 return 0; 84 last = p + n - 1; 85 } 86 envv = environ = p; 87 if (v && v[0] && v[0][0] == '_' && v[0][1] == '=') 88 *p++ = *v++; 89 else 90 *p++ = "_="; 91 if (!v) 92 *p = 0; 93 else 94 while (*p = *v++) 95 if (p[0][0] == '_' && p[0][1] == '=') 96 envv[0] = *p; 97 else 98 p++; 99 next = p; 100 p = envv; 101 } 102 else if (next == last) 103 { 104 n = last - v + INCREMENT + 1; 105 if (!(p = newof(p, char*, n, 0))) 106 return 0; 107 last = p + n - 1; 108 next = last - INCREMENT; 109 envv = environ = p; 110 } 111 if (!key) 112 return ok; 113 for (; s = *p; p++) 114 { 115 t = key; 116 do 117 { 118 if (!*t || *t == '=') 119 { 120 if (*s == '=') 121 { 122 if (!*t) 123 { 124 v = p++; 125 while (*v++ = *p++); 126 next--; 127 return ok; 128 } 129 *p = key; 130 return (s = strchr(key, '=')) ? s + 1 : (char*)0; 131 } 132 break; 133 } 134 } while (*t++ == *s++); 135 } 136 if (!(s = strchr(key, '='))) 137 return ok; 138 p = next; 139 *++next = 0; 140 *p = key; 141 return s + 1; 142 } 143