3 ms·
Of course you can. Mutexes are system objects, so it's not a huge problem to sync across processes, if you really have to (is it really expected that one proces
by tsimionescu 2y ago
Of course you can. Mutexes are system objects, so it's not a huge problem to sync across processes, if you really have to (is it really expected that one process can set env vars inside another process?).
Making global state, especially state that has no reason to be modified or even read very often like the env, thread safe is a trivial issue, well studied and understood. Could an intern do it? Probably not. Could literally any maintainer of a standard C library? Easily.
This is much more of a culture problem preventing such obvious flaws from being recognized as such.
Side-note: your set-then-get example is a theoretical problem in search of a use case. Why would you ever want to concurrently set an env var and expect to be guaranteed to read that same value? And even if this is a real thing that applications really use, exposing a new function to sync anything on the env mutex is, again, trivial. So, if you really needed that, you could do
lockenv
setenv
getenv
unlockenv
And problem solved.
- kelnos 2y agoThat doesn't solve anything. You could be using a library (perhaps a closed-source one) that doesn't use these hypothetical lockenv()/unlockenv() functions. This needs to be fixed inside libc, but there's no way to do so completely without breaking backward-compatibility.
- tsimionescu 2y agoYes, I was talking about fixes inside libc. The poster above was claiming it can't be done inside libc. And the lockvenv/unlockvenv functions I was mentioning were meant to exist besides the internal locking inside setenv/getenv. They would only be used if you needed transactional access (a combination of setting/getting multiple env vars atomically).
- xxs 2y agousing copy on write would be easier (and more performant), along with getenv_r. POSIX requires not to copy the data which makes the entire mutex/lock or CoW pointless. Of course, there will be the mandatory mentioning of "extern char *environ;"[0]. That returns are raw C strings as you can find them. What could work is per thread env. changes - but that's not likely to happen [0]: https://linux.die.net/man/3/environ https://linux.die.net/man/3/environ
- sunshowers 2y agoThat is a technical solution. What is your solution to the much more serious social problem of adding this check to every codebase in existence? What points of leverage do you have?
- tsimionescu 2y agoThe point was about adding a mutex inside libc in getenv and setenv. That way, every codebase in existence automatically gets this safety. The poster I was replying to claimed that this wouldn't help, because it would still not offer thread safety when doing multiple operations. I pointed out that, in addition to libc setenv/getenv using a mutex internally, they could also expose new functions to allow transactional access for anyone that really needs it - though I suspect that is a vanishingly small minority.
- sunshowers 2y agoAh I see — in that case you might be interested in the lockless illumos impl https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/gen/getenv.c https://github.com/illumos/illumos-gate/blob/master/usr/src/...