From: John Kelly on

On NetBSD 5.0.1 getpwuid fails unless I set a dummy environment
variable, which apparently causes the environ memory to be reallocated.
I guess this is just a NetBSD bug, but it leads to another question.

What's the preferred way to clear the environment, in the absence of
clearenv()?

Google found this:

http://lists.freebsd.org/pipermail/freebsd-stable/2008-June/043136.html

>environ = NULL does not work on:
>1. MacOS/Darwin
>2. Haiku
>
>environ[0] = NULL does not work on:
>1. FreeBSD 7+
>2. OpenSolaris
>
>static char *emptyenv[1] = { NULL };
>environ = emptyenv; does not work on:
>1. Haiku
>2. MacOS?
>
>environ = calloc(1, sizeof(*environ)); should work on all assuming NULL
>was not returned.


--
Webmail for Dialup Users
http://www.isp2dial.com/freeaccounts.html

From: Geoff Clare on
John Kelly wrote:

> What's the preferred way to clear the environment, in the absence of
> clearenv()?

Obtain the name from environ[0] (the part before the '=').
Call unsetenv() with that name.
Repeat until environ[0] is NULL.

Note that clearing the environment completely may cause subsequent
function calls or utility executions to behave in a non-standard way.
This is because some systems rely on environment variable settings to
choose whether to behave in a standard-conforming or traditional way.
This might just be PATH, as on Solaris, but it can also be one or more
implementation-specific variables such as UNIX95=1 on HP-UX or
POSIXLY_CORRECT on Linux. The latest POSIX standard provides a way to
query which environment variables other than PATH are needed to ensure
a conforming environment (confstr() with _CS_V7_ENV from C, or getconf
V7_ENV from shell).

--
Geoff Clare <netnews(a)gclare.org.uk>
From: Rainer Weikusat on
Geoff Clare <geoff(a)clare.See-My-Signature.invalid> writes:
> John Kelly wrote:
>
>> What's the preferred way to clear the environment, in the absence of
>> clearenv()?
>
> Obtain the name from environ[0] (the part before the '=').
> Call unsetenv() with that name.
> Repeat until environ[0] is NULL.

Is there are particular reason for this complicated procedure? It is
supposed to be possible to manipulate the environment via environ both
for the current process and for other programs invoked by an
exec-routine without an env-pointer. This seems to imply that code
like this:

----------------
#include <unistd.h>

static char **nullenv = { NULL };

int main(void)
{
extern char **environ;

environ = nullenv;
execl("/usr/bin/env", "env", (char *)0);

return 1;
}
-----------------

should be OK.
From: TerryP on
On Oct 8, 3:52 pm, Rainer Weikusat <rweiku...(a)mssgmbh.com> wrote:
> Is there are particular reason for this complicated procedure? It is
> supposed to be possible to manipulate the environment via environ both
> for the current process and for other programs invoked by an
> exec-routine without an env-pointer. This seems to imply that code
> like this:
>
> ----------------
> #include <unistd.h>
>
> static char **nullenv = { NULL };
>
> int main(void)
> {
>     extern char **environ;
>
>     environ = nullenv;
>     execl("/usr/bin/env", "env", (char *)0);
>
>     return 1;}
>
> -----------------
>
> should be OK.

That code works under OpenBSD, both for nuking the current environment
and the exec'd program.

From: Geoff Clare on
Rainer Weikusat wrote:
> Geoff Clare <geoff(a)clare.See-My-Signature.invalid> writes:
>> John Kelly wrote:
>>
>>> What's the preferred way to clear the environment, in the absence of
>>> clearenv()?
>> Obtain the name from environ[0] (the part before the '=').
>> Call unsetenv() with that name.
>> Repeat until environ[0] is NULL.
>
> Is there are particular reason for this complicated procedure? It is
> supposed to be possible to manipulate the environment via environ both
> for the current process and for other programs invoked by an
> exec-routine without an env-pointer.

POSIX says "If the application modifies environ or the pointers to
which it points, the behavior of getenv() is undefined." It has
similar statements for setenv() and unsetenv(). I assume the same
would apply to other functions that use environment variables (i.e.
which effectively use getenv() internally), although that doesn't
appear to be stated anywhere in the standard.

So modifying environ or its pointers directly is okay, as long as
you don't subsequently try to use getenv(), setenv() or unsetenv()
(or possibly any other standard function that uses an environment variable).

This restriction is what makes the unsetenv() loop the "preferred way"
the OP asked for.

--
Geoff Clare <netnews(a)gclare.org.uk>