xref: /f-stack/lib/ff_kern_environment.c (revision a9643ea8)
1 /*
2  * Copyright (c) 1998 Michael Smith. All rights reserved.
3  * Copyright (c) 2013 Patrick Kelsey. All rights reserved.
4  * Copyright (C) 2017 THL A29 Limited, a Tencent company.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *   list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *   this list of conditions and the following disclaimer in the documentation
14  *   and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * Derived from libuinet's uinet_kern_environment.c.
28  */
29 
30 /*
31  * This is an override of ken_environment.c so that get/set/put/unsetenv()
32  * from libc will be used, and the extended kernel environment API will
33  * still be available.
34  */
35 
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD: release/9.1.0/sys/kern/kern_environment.c 225617 2011-09-16 13:58:51Z kmacy $");
38 
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/proc.h>
42 #include <sys/queue.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mutex.h>
46 #include <sys/priv.h>
47 #include <sys/kernel.h>
48 #include <sys/systm.h>
49 #include <sys/sysent.h>
50 #include <sys/sysproto.h>
51 #include <sys/libkern.h>
52 #include <sys/kenv.h>
53 
54 #include "ff_host_interface.h"
55 
56 static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment");
57 
58 #define KENV_SIZE    512    /* Maximum number of environment strings */
59 
60 /* pointer to the static environment */
61 char *kern_envp; /* NULL */
62 
63 /* dynamic environment variables */
64 char **kenvp = &kern_envp; /* points to a pointer to NULL */
65 struct mtx kenv_lock;  /* does not need initialization - it will not be used as dynamic_kenv == 0 */
66 
67 /*
68  * No need to protect this with a mutex since SYSINITS are single threaded.
69  */
70 int dynamic_kenv = 0;
71 
72 char *
73 kern_getenv(const char *name)
74 {
75     return ff_getenv(name);
76 }
77 
78 int
79 kern_setenv(const char *name, const char *value)
80 {
81     return ff_setenv(name, value);
82 }
83 
84 void
85 freeenv(char *env)
86 {
87     ;
88 }
89 
90 
91 /*
92  * Test if an environment variable is defined.
93  */
94 int
95 testenv(const char *name)
96 {
97     return (kern_getenv(name) != NULL);
98 }
99 
100 
101 
102 /*
103  * Return a string value from an environment variable.
104  */
105 int
106 getenv_string(const char *name, char *data, int size)
107 {
108     char *tmp;
109 
110     tmp = kern_getenv(name);
111     if (tmp != NULL) {
112         strlcpy(data, tmp, size);
113         freeenv(tmp);
114         return (1);
115     } else
116         return (0);
117 }
118 
119 /*
120  * Return an integer value from an environment variable.
121  */
122 int
123 getenv_int(const char *name, int *data)
124 {
125     quad_t tmp;
126     int rval;
127 
128     rval = getenv_quad(name, &tmp);
129     if (rval)
130         *data = (int) tmp;
131     return (rval);
132 }
133 
134 /*
135  * Return an unsigned integer value from an environment variable.
136  */
137 int
138 getenv_uint(const char *name, unsigned int *data)
139 {
140     quad_t tmp;
141     int rval;
142 
143     rval = getenv_quad(name, &tmp);
144     if (rval)
145         *data = (unsigned int) tmp;
146     return (rval);
147 }
148 
149 /*
150  * Return a long value from an environment variable.
151  */
152 int
153 getenv_long(const char *name, long *data)
154 {
155     quad_t tmp;
156     int rval;
157 
158     rval = getenv_quad(name, &tmp);
159     if (rval)
160         *data = (long) tmp;
161     return (rval);
162 }
163 
164 /*
165  * Return an unsigned long value from an environment variable.
166  */
167 int
168 getenv_ulong(const char *name, unsigned long *data)
169 {
170     quad_t tmp;
171     int rval;
172 
173     rval = getenv_quad(name, &tmp);
174     if (rval)
175         *data = (unsigned long) tmp;
176     return (rval);
177 }
178 
179 /*
180  * Return a quad_t value from an environment variable.
181  */
182 int
183 getenv_quad(const char *name, quad_t *data)
184 {
185     char *value;
186     char *vtp;
187     quad_t iv;
188 
189     value = kern_getenv(name);
190     if (value == NULL)
191         return (0);
192     iv = strtoq(value, &vtp, 0);
193     if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) {
194         freeenv(value);
195         return (0);
196     }
197     switch (vtp[0]) {
198     case 't': case 'T':
199         iv *= 1024;
200     case 'g': case 'G':
201         iv *= 1024;
202     case 'm': case 'M':
203         iv *= 1024;
204     case 'k': case 'K':
205         iv *= 1024;
206     case '\0':
207         break;
208     default:
209         freeenv(value);
210         return (0);
211     }
212     *data = iv;
213     freeenv(value);
214     return (1);
215 }
216 
217 
218 void
219 tunable_int_init(void *data)
220 {
221     struct tunable_int *d = (struct tunable_int *)data;
222 
223     TUNABLE_INT_FETCH(d->path, d->var);
224 }
225 
226 void
227 tunable_long_init(void *data)
228 {
229     struct tunable_long *d = (struct tunable_long *)data;
230 
231     TUNABLE_LONG_FETCH(d->path, d->var);
232 }
233 
234 void
235 tunable_ulong_init(void *data)
236 {
237     struct tunable_ulong *d = (struct tunable_ulong *)data;
238 
239     TUNABLE_ULONG_FETCH(d->path, d->var);
240 }
241 
242 void
243 tunable_quad_init(void *data)
244 {
245     struct tunable_quad *d = (struct tunable_quad *)data;
246 
247     TUNABLE_QUAD_FETCH(d->path, d->var);
248 }
249 
250 void
251 tunable_str_init(void *data)
252 {
253     struct tunable_str *d = (struct tunable_str *)data;
254 
255     TUNABLE_STR_FETCH(d->path, d->var, d->size);
256 }
257 
258