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
