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.
> 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