Re: [PATCH 0/6] getenv() timing fixes
- From
Jeff King <peff@peff.net>
- Date
- Jan 15, 2019, 19:47 UTC
- Message-ID
- <20190115194726.GA5818@sigill.intra.peff.net>
- In-Reply-To
- <20190115194142.GG4886@sigill.intra.peff.net>
On Tue, Jan 15, 2019 at 02:41:42PM -0500, Jeff King wrote:
Show 26 quoted lines
> 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