]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/libc/9sys/getenv.c
libaml: fix gc bug, need to amltake()/amldrop() temporary buffer
[plan9front.git] / sys / src / libc / 9sys / getenv.c
index 146b35b625e73f129607e3cf476c3fd8017ef534..e1c89c1d123de7288aa94bab7a219818384ae47b 100644 (file)
@@ -4,33 +4,43 @@
 char*
 getenv(char *name)
 {
-       int r, f;
-       long s;
-       char *ans;
-       char *p, *ep, ename[100];
+       enum { HUNK = 100, };
+       char *s, *p;
+       int f, r, n;
 
-       if(strchr(name, '/') != nil)
+       if(name[0]=='\0' || strcmp(name, ".")==0 || strcmp(name, "..")==0 || strchr(name, '/')!=nil
+       || strlen(name) >= HUNK-5){
+               werrstr("bad env name: %s", name);
                return nil;
-       snprint(ename, sizeof ename, "/env/%s", name);
-       if(strcmp(ename+5, name) != 0)
+       }
+       if((s = malloc(HUNK)) == nil)
                return nil;
-       f = open(ename, OREAD);
-       if(f < 0)
-               return 0;
-       s = seek(f, 0, 2);
-       ans = malloc(s+1);
-       if(ans) {
-               setmalloctag(ans, getcallerpc(&name));
-               seek(f, 0, 0);
-               r = read(f, ans, s);
-               if(r >= 0) {
-                       ep = ans + s - 1;
-                       for(p = ans; p < ep; p++)
-                               if(*p == '\0')
-                                       *p = ' ';
-                       ans[s] = '\0';
+       snprint(s, HUNK, "/env/%s", name);
+       n = 0;
+       r = -1;
+       f = open(s, OREAD|OCEXEC);
+       if(f >= 0){
+               while((r = read(f, s+n, HUNK)) > 0){
+                       n += r;
+                       r = -1;
+                       if((p = realloc(s, n+HUNK)) == nil)
+                               break;
+                       s = p;
                }
+               close(f);
+       }
+       if(r < 0 || (p = realloc(s, n+1)) == nil){
+               free(s);
+               return nil;
+       }
+       s = p;
+       setmalloctag(s, getcallerpc(&name));
+       while(n > 0 && s[n-1] == '\0')
+               n--;
+       s[n] = '\0';
+       while(--n >= 0){
+               if(s[n] == '\0')
+                       s[n] = ' ';
        }
-       close(f);
-       return ans;
+       return s;
 }