Magellan Linux

Contents of /trunk/mkinitrd-magellan/klibc/usr/klibc/__put_env.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (show annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 1523 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 /*
2 * __put_env.c - common code for putenv() and setenv()
3 */
4
5 #include <errno.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include "env.h"
10
11 static size_t __environ_size;
12 static char **__environ_alloc;
13
14 /* str should be a duplicated version of the input string;
15 len is the length of the key including the = sign */
16
17 int __put_env(char *str, size_t len, int overwrite)
18 {
19 static char *const null_environ = { NULL };
20 char **p, *q;
21 char **newenv;
22 size_t n;
23
24 if (!environ)
25 environ = (char **)null_environ;
26
27 n = 1; /* Include space for final NULL */
28 for (p = environ; (q = *p); p++) {
29 n++;
30 if (!strncmp(q, str, len)) {
31 if (!overwrite)
32 free(str);
33 else
34 *p = str; /* Possible memory leak... */
35 return 0;
36 }
37 }
38
39 if (__environ_alloc && environ != __environ_alloc) {
40 free(__environ_alloc);
41 __environ_alloc = NULL;
42 }
43
44 /* Need to extend the environment */
45 if (n < __environ_size) {
46 p[1] = NULL;
47 *p = str;
48 return 0;
49 } else {
50 if (__environ_alloc) {
51 newenv =
52 realloc(__environ_alloc,
53 (__environ_size << 1) * sizeof(char *));
54 if (!newenv)
55 return -1;
56
57 __environ_size <<= 1;
58 } else {
59 /* Make a reasonable guess how much more space
60 we need */
61 size_t newsize = n + 32;
62 newenv = malloc(newsize * sizeof(char *));
63 if (!newenv)
64 return -1;
65
66 memcpy(newenv, environ, n * sizeof(char *));
67 __environ_size = newsize;
68 }
69 newenv[n-1] = str; /* Old NULL position */
70 newenv[n] = NULL;
71 environ = newenv;
72 }
73 return 0;
74 }