4 ms·
Same way anything would be: the set is atomic, and if you the programmer want something specific then you'll have to arrange that. It doesn't have to be magic -
by to3m 10y ago
Same way anything would be: the set is atomic, and if you the programmer want something specific then you'll have to arrange that. It doesn't have to be magic - it just has not to crash. That's a much lower bar.
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.
- agwa 10y ago> 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.
- to3m 10y agoYes - 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.