On Tue, Jan 15, 2019 at 11:32:56AM -0800, Junio C Hamano wrote:
> Jeff King <[email protected]> writes:
>
> > On Sat, Jan 12, 2019 at 10:51:42AM -0800, Stefan Beller wrote:
> >
> >> > I wonder, and not as "you should do this" feedback on this series, just
> >>
> >> There is a getenv_safe() in environment.c, but I guess a xgetenv() that
> >> takes the same parameters as getenv() is better for ease of use.
> >
> > Yes, but it punts on the memory ownership by stuffing everything into an
> > argv_array. That saves a few lines if you're going to ask for five
> > variables, but for a single variable it's no better than:
> >
> > char *foo = getenv_safe("FOO");
>
> You meant xstrdup_or_null(getenv("FOO")) here? And did Stefan mean
>
> #define xgetenv(e) xstrdup_or_null(getenv(e))
>
> ?
Yes, I think that would be one possible implementation of a "safe"
getenv (and what I was thinking of specifically in that example).
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).
-Peff