Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/misc/setenviron.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
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|O_cloexec));
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
149