Re: [PATCH 0/6] getenv() timing fixes
From: Jeff King <hidden>
Date: 2019-01-15 19:47:29
On Tue, Jan 15, 2019 at 02:41:42PM -0500, Jeff King wrote:
The more involved one (that doesn't pass along memory ownership) is
something like:
static struct hashmap env_cache;
const char *getenv_safe(const char *name)
{
if (e = hashmap_get(&env_cache, name))
return e->value;
/* need some trickery to make sure xstrdup does not call getenv */
e->value = xstrdup_or_null(getenv(name));
e->name = xstrdup(name);
hashmap_put(&env_cache, e);
return e->value;
}
with a matching setenv_safe() to drop the hashmap entry. Come to think
of it, this is really pretty equivalent to string-interning, which we
already have a hashmap for. I think one could argue that string
interning is basically just a controlled form of memory leaking, but
it's probably a reasonable compromise in this instance (i.e., we expect
to ask about a finite number of variables anyway; the important thing is
just that we don't leak memory for the same variable over and over).So actually, that's pretty easy to do without writing much code at all. Something like: #define xgetenv(name) strintern(getenv(name)) It means we're effectively storing the environment twice in the worst case, but that's probably not a big deal. Unless we have a loop which does repeated setenv()/getenv() calls, the strintern hashmap can't grow without bound. -Peff