3 ms·
The only thread-safe way to implement getenv/setenv as they currently exist is to leak the previous state when setenv allocates, such that existing pointers sta
by debugnik 2y ago
The only thread-safe way to implement getenv/setenv as they currently exist is to leak the previous state when setenv allocates, such that existing pointers stay valid. The existing API simply lacks a mechanism to synchronize correctly.
Leaking would be good enough for many use cases, but it would break long-running users of setenv (mainly those with libraries abusing env vars, as in TFA), and doesn't even solve how they interact with putenv and environ. This whole API is just cursed.
Libc could of course get better APIs, like GetEnvironmentVariable on Windows, but that won't fix all existing code.
- HarHarVeryFunny 2y agoDo you mean pointers returned by getenv() ? Those could point to thread-local buffers that data gets copied into when getenv() is called.
- debugnik 2y agoOnly if we're willing to take for granted that a call to getenv invalidates the previous one. POSIX allows it, but I'm concerned about runtimes scheduling user tasks on the same thread. If current platforms are safely making a copy of getenv before allowing their scheduler to interrupt, then yes I'd be ok with your solution.
- HarHarVeryFunny 2y agoIf you wanted to avoid "only latest getenv pointer per thread is valid", then the thread local data structure could be a var-name-> buffer map rather than a single reused buffer. Worst case memory usage (all threads get all vars) is that you end up having a separate copy of the environment per thread, but it seems this is the best that can be done given the awful API.