A few ports make use of clearenv(3), a GNU extension.  This function was
rejected by POSIX, so what's left?

If all you want to do is clear the environment before exec(), you can
construct a new environment and use execve, which is specified by POSIX.

Now if a port is not using execve, but clearenv then a bunch of setenv,
what can we do?  It turns out that replacing clearenv with "environ =
NULL" doesn't work, because setenv will later dereference environ.  *BZZT*
"environ = calloc(1, sizeof(*environ))" seems portable, as noted by the
dovecot project

  http://hg.dovecot.org/dovecot-2.0/file/74d9f61e224d/src/lib/env-util.c#l56

I think ports should probably use calloc here if we want to push those
patches upstream.  But supporting the "environ = NULL" method looks
cheap.

Thoughts?

Index: setenv.c
===================================================================
RCS file: /cvs/src/lib/libc/stdlib/setenv.c,v
retrieving revision 1.17
diff -u -p -p -u -r1.17 setenv.c
--- setenv.c    13 Mar 2016 18:34:21 -0000      1.17
+++ setenv.c    25 Apr 2016 19:29:58 -0000
@@ -43,7 +43,7 @@ int
 putenv(char *str)
 {
        char **P, *cp;
-       size_t cnt;
+       size_t cnt = 0;
        int offset = 0;
 
        for (cp = str; *cp && *cp != '='; ++cp)
@@ -65,9 +65,8 @@ putenv(char *str)
        }
 
        /* create new slot for string */
-       for (P = environ; *P != NULL; P++)
-               ;
-       cnt = P - environ;
+       for (P = environ; P != NULL && *P != NULL; P++)
+               cnt++;
        P = reallocarray(lastenv, cnt + 2, sizeof(char *));
        if (!P)
                return (-1);
@@ -122,11 +121,10 @@ setenv(const char *name, const char *val
                                        break;
                }
        } else {                                        /* create new slot */
-               size_t cnt;
+               size_t cnt = 0;
 
-               for (P = environ; *P != NULL; P++)
-                       ;
-               cnt = P - environ;
+               for (P = environ; P != NULL && *P != NULL; P++)
+                       cnt++;
                P = reallocarray(lastenv, cnt + 2, sizeof(char *));
                if (!P)
                        return (-1);


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to