env.c (2261B)
1 /* env.c, envread.c, env.h: environ library 2 Daniel J. Bernstein, djb@silverton.berkeley.edu. 3 Depends on str.h, alloc.h. 4 Requires environ. 5 19960113: rewrite. warning: interface is different. 6 No known patent problems. 7 */ 8 9 #include "env.h" 10 11 #include "str.h" 12 #include "alloc.h" 13 14 #include <string.h> 15 16 int env_isinit = 0; /* if env_isinit: */ 17 static int ea; /* environ is a pointer to ea+1 char*'s. */ 18 static int en; /* the first en of those are ALLOCATED. environ[en] is 0. */ 19 20 static void env_goodbye(i) int i; 21 { 22 alloc_free(environ[i]); 23 environ[i] = environ[--en]; 24 environ[en] = 0; 25 } 26 27 static char *null = 0; 28 29 void env_clear() 30 { 31 if (env_isinit) while (en) env_goodbye(0); 32 else environ = &null; 33 } 34 35 static void env_unsetlen(s,len) char *s; int len; 36 { 37 int i; 38 for (i = en - 1;i >= 0;--i) 39 if (!str_diffn(s,environ[i],len)) 40 if (environ[i][len] == '=') 41 env_goodbye(i); 42 } 43 44 int env_unset(s) char *s; 45 { 46 if (!env_isinit) if (!env_init()) return 0; 47 env_unsetlen(s,str_len(s)); 48 return 1; 49 } 50 51 static int env_add(s) char *s; 52 { 53 char *t; 54 t = env_findeq(s); 55 if (t) env_unsetlen(s,t - s); 56 if (en == ea) 57 { 58 char **nenv; 59 ea += 30; 60 nenv = realloc(environ, (ea + 1) * sizeof(char *)); 61 if (nenv == NULL) 62 { ea = en; return 0; } 63 environ = nenv; 64 } 65 environ[en++] = s; 66 environ[en] = 0; 67 return 1; 68 } 69 70 int env_put(s) char *s; 71 { 72 char *u; 73 if (!env_isinit) if (!env_init()) return 0; 74 u = strdup(s); 75 if (!u) return 0; 76 if (!env_add(u)) { alloc_free(u); return 0; } 77 return 1; 78 } 79 80 int env_put2(s,t) char *s; char *t; 81 { 82 char *u; 83 int slen; 84 if (!env_isinit) if (!env_init()) return 0; 85 slen = str_len(s); 86 u = alloc(slen + str_len(t) + 2); 87 if (!u) return 0; 88 str_copy(u,s); 89 u[slen] = '='; 90 str_copy(u + slen + 1,t); 91 if (!env_add(u)) { alloc_free(u); return 0; } 92 return 1; 93 } 94 95 int env_init() 96 { 97 char **newenviron; 98 int i; 99 for (en = 0;environ[en];++en) ; 100 ea = en + 10; 101 newenviron = (char **) alloc((ea + 1) * sizeof(char *)); 102 if (!newenviron) return 0; 103 for (en = 0;environ[en];++en) 104 { 105 newenviron[en] = strdup(environ[en]); 106 if (!newenviron[en]) 107 { 108 for (i = 0;i < en;++i) alloc_free(newenviron[i]); 109 alloc_free(newenviron); 110 return 0; 111 } 112 } 113 newenviron[en] = 0; 114 environ = newenviron; 115 env_isinit = 1; 116 return 1; 117 }