C++ Logo


Advanced search

Re: [isocpp-lib-ext] std::environment

From: Jake Arkinstall <jake.arkinstall_at_[hidden]>
Date: Mon, 2 Jan 2023 02:16:46 +0000
On Mon, 2 Jan 2023, 00:36 Corentin Jabot via Lib-Ext, <
lib-ext_at_[hidden]> wrote:

> (putenv is not a system facility, it has no effect whatsoever on the
> system, in only affect the current process)

And, I believe, processes spawned from the current process, such as via
fork. It also has an effect on std::system calls. I don't use this
functionality but I imagine that, if I did, I'd want the ability to control
its environment.

Environment variables are predominantly used as input - even more so in
recent years - but they can be used as "output" too. Otherwise they
wouldn't be provided to be read as input to begin with.

So if we want to be able to launch processes but don't want to mutate the
environment, we need a mechanism to pass environment variables to the

It would also make sense that, if we must have an immutable global
pseudo-environment, we allow transformations that provide new
pseudo-environments that we can pass around. At the very least, std::system
should gain an overload that accepts a pseudo-environment that results from

Are we providing a way to query the environment or a global map of strings?

The above being said, I would still find it surprising if a call to putenv
didn't change the output from something that is supposed to abstract and
modernise environment access. I imagine many others would.

I would also find it surprising if something that is supposed to abstract
and modernise environment access only provided read-only functionality,
especially if the justification of that was based on the premise that
reading and writing isn't thread safe. Anyone wanting to write would be
forced to use setenv or putenv anyway, and the problem still emerges.

Or, more generally:

- We have an unsafe thing.
- We make a safe alternative that is incomplete because some parts weren't
possible to to in a safe manner
- We still have the unsafe thing because we don't break things for users.
- Therefore we still have an unsafe thing.

We can only add footguns. We can't take them away. I worry that trying to
avoid footguns by pushing users to use the old ones, and then making any
kind of decision based on the wrong assumption that the footgun is dealt
with, can only lead to new footguns.

In the case of environment variables, this is just the nature of global
state managed by the operating system. The safety is at the hands of the
operating system. Rust has its own battles with it, too - and recent ones,
resulting from CVEs relating to setenv safety.
https://github.com/rust-lang/rust/issues/90308 tentatively concludes with
removing the safety guarantee of setting environment variables. We don't
have a concept of safety in the language, but I feel that avoiding the
functionality altogether for that reason doesn't make sense.

So to actually get to your question, I think storing state and hoping
existing code doesn't change it via the features already available to it is
a bad move, and I think it should be the former: a way to query the current

If, however, the alternate path is chosen, then it needs to be named well.
Environment variables are mutable. If what the user is querying is actually
the environment variables at startup, then it should be named accordingly
to avoid confusion.

Received on 2023-01-02 02:16:58