r22988: fixed 2 bugs in our unsetenv() replacement code
authorAndrew Tridgell <tridge@samba.org>
Fri, 18 May 2007 06:53:57 +0000 (06:53 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:52:36 +0000 (14:52 -0500)
 1) you must not free the memory, as it is possible the memory did not
 come from malloc (try it under valgrind to test)

 2) the old code didn't cope with duplicate environment variables

I hope this will fix some of the build farm errors on irix, and maybe solaris
(This used to be commit ec6900171d066e927f004b621fb39cc7b8dcfd90)

source4/lib/replace/replace.c

index db299130e5197e04d78730e32e656310572303b9..87e73d001c1e063ce190bd9a55729601057cb430 100644 (file)
@@ -568,20 +568,24 @@ int rep_unsetenv(const char *name)
 {
        extern char **environ;
        size_t len = strlen(name);
-       size_t i; 
-       int found = 0;
+       size_t i, count;
 
-       for (i=0; (environ && environ[i]); i++) {
-               if (found) {
-                       environ[i-1] = environ[i];
-                       continue;
-               }
+       if (environ == NULL || getenv(name) == NULL) {
+               return 0;
+       }
 
+       for (i=0;environ[i];i++) /* noop */ ;
+
+       count=i;
+       
+       for (i=0;i<count;) {
                if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
-                       free(environ[i]);
-                       environ[i] = NULL;
-                       found = 1;
-                       continue;
+                       /* note: we do _not_ free the old variable here. It is unsafe to 
+                          do so, as the pointer may not have come from malloc */
+                       memmove(&environ[i], &environ[i+1], (count-i)*sizeof(char *));
+                       count--;
+               } else {
+                       i++;
                }
        }