Skip to content

Commit 5c46fcb

Browse files
cfriedtnashif
authored andcommitted
posix: env: move most implementations to env-common.c
Move most implementations to env-common.c in preparation for adding putenv.c . We also take this as an opportunity to switch from using k_spinlock to sys_sem. Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
1 parent 4137c48 commit 5c46fcb

File tree

3 files changed

+270
-256
lines changed

3 files changed

+270
-256
lines changed

lib/posix/options/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ if (NOT CONFIG_TC_PROVIDES_POSIX_SINGLE_PROCESS)
102102
zephyr_library_sources_ifdef(CONFIG_POSIX_SINGLE_PROCESS
103103
confstr.c
104104
env.c
105+
env_common.c
105106
sysconf.c
106107
uname.c
107108
)

lib/posix/options/env.c

Lines changed: 5 additions & 256 deletions
Original file line numberDiff line numberDiff line change
@@ -4,279 +4,28 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
#include <errno.h>
8-
#include <stdio.h>
9-
#include <stdlib.h>
10-
#include <string.h>
7+
#include <stddef.h>
118

12-
#include <zephyr/logging/log.h>
13-
#include <zephyr/spinlock.h>
9+
extern char *z_getenv(const char *name);
10+
extern int z_getenv_r(const char *name, char *buf, size_t len);
11+
extern int z_setenv(const char *name, const char *val, int overwrite);
12+
extern int z_unsetenv(const char *name);
1413

15-
#define TRACK_ALLOC (IS_ENABLED(CONFIG_POSIX_ENV_LOG_LEVEL_DBG) || IS_ENABLED(CONFIG_ZTEST))
16-
17-
LOG_MODULE_REGISTER(posix_env, CONFIG_POSIX_ENV_LOG_LEVEL);
18-
19-
static struct k_spinlock environ_lock;
20-
static size_t allocated;
21-
char **environ;
22-
23-
#ifdef CONFIG_ZTEST
24-
size_t posix_env_get_allocated_space(void)
25-
{
26-
return allocated;
27-
}
28-
#endif
29-
30-
static size_t environ_size(void)
31-
{
32-
size_t ret;
33-
34-
if (environ == NULL) {
35-
return 0;
36-
}
37-
38-
for (ret = 0; environ[ret] != NULL; ++ret) {
39-
}
40-
41-
return ret;
42-
}
43-
44-
static int findenv(const char *name, size_t namelen)
45-
{
46-
const char *env;
47-
48-
if (name == NULL || namelen == 0 || strchr(name, '=') != NULL) {
49-
/* Note: '=' is not a valid name character */
50-
return -EINVAL;
51-
}
52-
53-
if (environ == NULL) {
54-
return -ENOENT;
55-
}
56-
57-
for (char **envp = &environ[0]; *envp != NULL; ++envp) {
58-
env = *envp;
59-
if (strncmp(env, name, namelen) == 0 && env[namelen] == '=') {
60-
return envp - environ;
61-
}
62-
}
63-
64-
return -ENOENT;
65-
}
66-
67-
char *z_getenv(const char *name)
68-
{
69-
int ret;
70-
size_t nsize;
71-
char *val = NULL;
72-
73-
nsize = (name == NULL) ? 0 : strlen(name);
74-
K_SPINLOCK(&environ_lock)
75-
{
76-
ret = findenv(name, nsize);
77-
if (ret < 0) {
78-
K_SPINLOCK_BREAK;
79-
}
80-
81-
val = environ[ret] + nsize + 1;
82-
}
83-
84-
return val;
85-
}
8614
char *getenv(const char *name)
8715
{
8816
return z_getenv(name);
8917
}
9018

91-
int z_getenv_r(const char *name, char *buf, size_t len)
92-
{
93-
int ret = 0;
94-
size_t vsize;
95-
size_t nsize;
96-
char *val = NULL;
97-
98-
nsize = (name == NULL) ? 0 : strlen(name);
99-
K_SPINLOCK(&environ_lock)
100-
{
101-
ret = findenv(name, nsize);
102-
if (ret < 0) {
103-
LOG_DBG("No entry for name '%s'", name);
104-
K_SPINLOCK_BREAK;
105-
}
106-
107-
val = environ[ret] + nsize + 1;
108-
vsize = strlen(val) + 1;
109-
if (vsize > len) {
110-
ret = -ERANGE;
111-
K_SPINLOCK_BREAK;
112-
}
113-
strcpy(buf, val);
114-
LOG_DBG("Found entry %s", environ[ret]);
115-
}
116-
117-
if (ret < 0) {
118-
errno = -ret;
119-
ret = -1;
120-
}
121-
122-
return ret;
123-
}
12419
int getenv_r(const char *name, char *buf, size_t len)
12520
{
12621
return z_getenv_r(name, buf, len);
12722
}
12823

129-
int z_setenv(const char *name, const char *val, int overwrite)
130-
{
131-
int ret = 0;
132-
char *env;
133-
char **envp;
134-
size_t esize;
135-
const size_t vsize = (val == NULL) ? 0 : strlen(val);
136-
const size_t nsize = (name == NULL) ? 0 : strlen(name);
137-
/* total size of name + '=' + val + '\0' */
138-
const size_t tsize = nsize + 1 /* '=' */ + vsize + 1 /* '\0' */;
139-
140-
if (name == NULL || val == NULL) {
141-
LOG_DBG("Invalid name '%s' or value '%s'", name, val);
142-
errno = EINVAL;
143-
return -1;
144-
}
145-
146-
K_SPINLOCK(&environ_lock)
147-
{
148-
ret = findenv(name, nsize);
149-
if (ret == -EINVAL) {
150-
LOG_DBG("Invalid name '%s'", name);
151-
K_SPINLOCK_BREAK;
152-
}
153-
if (ret >= 0) {
154-
/* name was found in environ */
155-
esize = strlen(environ[ret]) + 1;
156-
if (overwrite == 0) {
157-
LOG_DBG("Found entry %s", environ[ret]);
158-
ret = 0;
159-
K_SPINLOCK_BREAK;
160-
}
161-
} else {
162-
/* name was not found in environ -> add new entry */
163-
esize = environ_size();
164-
envp = realloc(environ, sizeof(char **) *
165-
(esize + 1 /* new entry */ + 1 /* NULL */));
166-
if (envp == NULL) {
167-
ret = -ENOMEM;
168-
K_SPINLOCK_BREAK;
169-
}
170-
171-
if (TRACK_ALLOC) {
172-
allocated += sizeof(char **) * (esize + 2);
173-
LOG_DBG("realloc %zu bytes (allocated: %zu)",
174-
sizeof(char **) * (esize + 2), allocated);
175-
}
176-
177-
environ = envp;
178-
ret = esize;
179-
environ[ret] = NULL;
180-
environ[ret + 1] = NULL;
181-
esize = 0;
182-
}
183-
184-
if (esize < tsize) {
185-
/* need to malloc or realloc space for new environ entry */
186-
env = realloc(environ[ret], tsize);
187-
if (env == NULL) {
188-
ret = -ENOMEM;
189-
K_SPINLOCK_BREAK;
190-
}
191-
if (TRACK_ALLOC) {
192-
allocated += tsize - esize;
193-
LOG_DBG("realloc %zu bytes (allocated: %zu)", tsize - esize,
194-
allocated);
195-
}
196-
environ[ret] = env;
197-
}
198-
199-
strcpy(environ[ret], name);
200-
environ[ret][nsize] = '=';
201-
strncpy(environ[ret] + nsize + 1, val, vsize + 1);
202-
LOG_DBG("Added entry %s", environ[ret]);
203-
204-
ret = 0;
205-
}
206-
207-
if (ret < 0) {
208-
errno = -ret;
209-
ret = -1;
210-
}
211-
212-
return ret;
213-
}
21424
int setenv(const char *name, const char *val, int overwrite)
21525
{
21626
return z_setenv(name, val, overwrite);
21727
}
21828

219-
int z_unsetenv(const char *name)
220-
{
221-
int ret = 0;
222-
char **envp;
223-
size_t esize;
224-
size_t nsize;
225-
226-
nsize = (name == NULL) ? 0 : strlen(name);
227-
K_SPINLOCK(&environ_lock)
228-
{
229-
ret = findenv(name, nsize);
230-
if (ret < 0) {
231-
ret = (ret == -EINVAL) ? -EINVAL : 0;
232-
K_SPINLOCK_BREAK;
233-
}
234-
235-
esize = environ_size();
236-
if (TRACK_ALLOC) {
237-
allocated -= strlen(environ[ret]) + 1;
238-
LOG_DBG("free %zu bytes (allocated: %zu)", strlen(environ[ret]) + 1,
239-
allocated);
240-
}
241-
free(environ[ret]);
242-
243-
/* shuffle remaining environment variable pointers forward */
244-
for (; ret < esize; ++ret) {
245-
environ[ret] = environ[ret + 1];
246-
}
247-
/* environ must be terminated with a NULL pointer */
248-
environ[ret] = NULL;
249-
250-
/* reduce environ size and update allocation */
251-
--esize;
252-
if (esize == 0) {
253-
free(environ);
254-
environ = NULL;
255-
} else {
256-
envp = realloc(environ, (esize + 1 /* NULL */) * sizeof(char **));
257-
if (envp != NULL) {
258-
environ = envp;
259-
}
260-
}
261-
__ASSERT_NO_MSG((esize >= 1 && environ != NULL) || environ == NULL);
262-
263-
if (TRACK_ALLOC) {
264-
/* recycle nsize here */
265-
nsize = ((esize == 0) ? 2 : 1) * sizeof(char **);
266-
allocated -= nsize;
267-
LOG_DBG("free %zu bytes (allocated: %zu)", nsize, allocated);
268-
}
269-
270-
ret = 0;
271-
}
272-
273-
if (ret < 0) {
274-
errno = -ret;
275-
ret = -1;
276-
}
277-
278-
return ret;
279-
}
28029
int unsetenv(const char *name)
28130
{
28231
return z_unsetenv(name);

0 commit comments

Comments
 (0)