Re:Don't setenv in multi-threaded code on glibc
by agwa on Tuesday January 31, 2017 @11:10AM
(#13531736)
> If this turns out actually to be a problem, introduce a second wrapper EXE that you spawn, supplying environment stuff and arguments for subchild EXE. Fork, exec the wrapper, have it do its thing, then have it exec the EXE you actually want (no fork).
It doesn't have to be that complicated. After the fork, in the child, you can construct your own local environment array, and pass it to execve or one of the other exec functions that takes an environ argument. This is perfectly safe behavior in a multi-threaded program.
Re:Don't setenv in multi-threaded code on glibc
by to3m on Tuesday January 31, 2017 @11:31AM
(#13532038)
Yes - good point. I think the wrapper approach can still make sense for CLOEXEC sometimes, but you should absolutely always ignore what I said about using it for the environment ;)
Never having needed to do exactly this myself in practice, I'd quite forgotten about the ...e functions.
As for how you do this sort of thing in general, fork/exec from a multithreaded POSIX program is a minefield and you're best off not doing it. But, if you insist, it looks like posix_spawn might help, or you can do your setenv in the child before the exec. setenv isn't async signal-safe, so strictly speaking you're not allowed to do this.
If this turns out actually to be a problem, introduce a second wrapper EXE that you spawn, supplying environment stuff and arguments for subchild EXE. Fork, exec the wrapper, have it do its thing, then have it exec the EXE you actually want (no fork).
I haven't done that for setting the environment, but I have for setting CLOEXEC on file descriptors when doing fork/exec as part of a (large, gnarly, zillions of FDs, tons of threads, closed source) program.