C++ Logo

sg16

Advanced search

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

From: Tom Honermann <tom_at_[hidden]>
Date: Thu, 5 Jan 2023 16:49:39 -0500
On 1/3/23 2:11 PM, Niall Douglas via SG16 wrote:
> getenv() is weirdly enough not async signal safe. Most will consider
> that unimportant, which is true until suddenly it is extremely
> important. It would be really great if C++'s implementation gained async
> signal safety.

Agreed, though I think it is unsurprising that getenv() is not
async-signal-safe. POSIX states
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/environ.html>:

    Applications can change the entire environment in a single operation
    by assigning the environ variable to point to an array of character
    pointers to the new environment strings. After assigning a new value
    to environ, applications should not rely on the new environment
    strings remaining part of the environment, as a call to getenv()
    <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getenv.html>,
    ^[XSI] <javascript:open_code('XSI')> putenv()
    <https://pubs.opengroup.org/onlinepubs/9699919799/functions/putenv.html>,
    setenv()
    <https://pubs.opengroup.org/onlinepubs/9699919799/functions/setenv.html>,
    unsetenv()
    <https://pubs.opengroup.org/onlinepubs/9699919799/functions/unsetenv.html>,
    or any function that is dependent on an environment variable may, on
    noticing that environ has changed, copy the environment strings to a
    new array and assign environ to point to it.

    Any application that directly modifies the pointers to which the
    environ variable points has undefined behavior.

    Conforming multi-threaded applications shall not use the environ
    variable to access or modify any environment variable while any
    other thread is concurrently modifying any environment variable. A
    call to any function dependent on any environment variable shall be
    considered a use of the environ variable to access that environment
    variable.

Peter Brett and I chatted earlier today about how the situation could
potentially be improved via changes to POSIX. The approach we discussed is:

 1. Provide a RCU <https://en.wikipedia.org/wiki/Read-copy-update>-based
    alternative to the environ variable. This would suffice to enable
    thread-safe concurrent read and write access to the environment
    block via RCU handles.
 2. Update getenv(), putenv(), setenv(), and unsetenv() to operate on
    the RCU-based interface.
 3. When a RCU update occurs, the environ variable is set to point to
    the updated environment.
 4. Perhaps deprecate the environ variable.

Any concurrent use of environ or the envp pointer passed to main() with
the RCU-based interface would remain undefined behavior.

Obviously, this would be a lot of work and would take a long time.

Tom.

Received on 2023-01-05 21:49:40