Date: Mon, 2 Jan 2023 14:51:47 -0500
On 1/1/23 8:18 PM, Ville Voutilainen wrote:
> On Mon, 2 Jan 2023 at 02:36, Corentin Jabot via Lib-Ext
> <lib-ext_at_[hidden]> wrote:
>> Moreover, the ability to modify the view over the environment makes the thing hard to use, if not pointless.
>> If someone overrides the value of an environment variable, there is no (easy/portable/reliable) way to get to the original value (which was put there by the parent process).
>> This is an issue for example with libraries overwriting "LC_XXX", thereby making them unusable to determine how to communicate with the parent process.
> Seems like a rather unfortunate situation when I can't write that
> parent process program in C++ when the most suitable way to launch
> the child is to set up the current environment and fork().
Or to call fork(), then setup the current environment, and then call
execv() or similar.
Unfortunately, use of fork() in multithreaded programs is problematic.
Only the calling thread is cloned in the child process. This can result
in the child process being in a state where thread synchronization
resources (such as those that might be used by a thread-safe
implementation of getenv() and/or putenv()) may be in a permanently
locked state such that an attempt to modify the environment might result
in a deadlock. Implementations can and do try to prevent such things via
the equivalent of pthread_atfork()
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html>,
but those techniques break down when fork() is called from within a
signal handler. A future revision of POSIX will include _Fork() as a
replacement for fork() in signal handlers (Austin Group 0000062
<https://austingroupbugs.net/view.php?id=62>), but the thread
synchronization resource issues will remain in that case.
I think Jeff's future work to add process spawning support to the C++
standard library should build on posix_spawn()
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html>
with more emphasis on providing a suitable environment than on modifying
the current environment to suit the needs of the child process. I have
long wished that POSIX included functions similar to
posix_spawnattr_setflags()
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawnattr_setflags.html>
that enabled adding per-environment-variable mutation options. E.g.,
something like posix_spawnattr_inheritenv(true),
posix_spawnattr_setenv("FOO", "VALUE"), posix_spawnattr_unsetenv("FOO"),
posix_spawnattr_appendenv("PATH", ";", "/path/to/bin"). Similar
functionality for Microsoft's CreateProcess() suite of functions would
be welcome as well.
Tom.
> On Mon, 2 Jan 2023 at 02:36, Corentin Jabot via Lib-Ext
> <lib-ext_at_[hidden]> wrote:
>> Moreover, the ability to modify the view over the environment makes the thing hard to use, if not pointless.
>> If someone overrides the value of an environment variable, there is no (easy/portable/reliable) way to get to the original value (which was put there by the parent process).
>> This is an issue for example with libraries overwriting "LC_XXX", thereby making them unusable to determine how to communicate with the parent process.
> Seems like a rather unfortunate situation when I can't write that
> parent process program in C++ when the most suitable way to launch
> the child is to set up the current environment and fork().
Or to call fork(), then setup the current environment, and then call
execv() or similar.
Unfortunately, use of fork() in multithreaded programs is problematic.
Only the calling thread is cloned in the child process. This can result
in the child process being in a state where thread synchronization
resources (such as those that might be used by a thread-safe
implementation of getenv() and/or putenv()) may be in a permanently
locked state such that an attempt to modify the environment might result
in a deadlock. Implementations can and do try to prevent such things via
the equivalent of pthread_atfork()
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html>,
but those techniques break down when fork() is called from within a
signal handler. A future revision of POSIX will include _Fork() as a
replacement for fork() in signal handlers (Austin Group 0000062
<https://austingroupbugs.net/view.php?id=62>), but the thread
synchronization resource issues will remain in that case.
I think Jeff's future work to add process spawning support to the C++
standard library should build on posix_spawn()
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html>
with more emphasis on providing a suitable environment than on modifying
the current environment to suit the needs of the child process. I have
long wished that POSIX included functions similar to
posix_spawnattr_setflags()
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawnattr_setflags.html>
that enabled adding per-environment-variable mutation options. E.g.,
something like posix_spawnattr_inheritenv(true),
posix_spawnattr_setenv("FOO", "VALUE"), posix_spawnattr_unsetenv("FOO"),
posix_spawnattr_appendenv("PATH", ";", "/path/to/bin"). Similar
functionality for Microsoft's CreateProcess() suite of functions would
be welcome as well.
Tom.
Received on 2023-01-02 19:51:51