[Libguestfs] [PATCH nbdkit 6/9] common/utils: Add a copy_environ utility function.

Richard W.M. Jones rjones at redhat.com
Wed Apr 15 20:54:47 UTC 2020


On Wed, Apr 15, 2020 at 03:41:06PM -0500, Eric Blake wrote:
> On 4/15/20 11:16 AM, Richard W.M. Jones wrote:
> >This allows you to copy an environ, while optionally adding extra
> >(key, value) pairs to it.
> >---
> >  common/utils/Makefile.am |   2 +
> >  common/utils/utils.h     |   1 +
> >  common/utils/environ.c   | 116 +++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 119 insertions(+)
> >
> 
> >+++ b/common/utils/utils.h
> >@@ -38,5 +38,6 @@ extern void uri_quote (const char *str, FILE *fp);
> >  extern int exit_status_to_nbd_error (int status, const char *cmd);
> >  extern int set_cloexec (int fd);
> >  extern int set_nonblock (int fd);
> >+extern char **copy_environ (char **env, ...);
> 
> Should use __attribute__((sentinel)), to let the compiler enforce
> that we don't forget a trailing NULL.

Ooops ... I had this in an earlier version and somehow
managed to drop it :-(  I think when it was originally
in a separate header file.

Fixed my copy.

> Unfortunately true. There's no guarantee that the original environ
> is sorted to make this more efficient, but the overhead of storing
> our replacement in a hash just to avoid the O(n^2) seems wasted.
> That argues that we should try to avoid invoking copy_environ in
> hot-spots (for example, in the sh plugin, can we get away with doing
> it once in .get_ready, rather than before every single callback?)
> 
> hmm - looking at patch 8, you delayed things because of --run.  We
> already know we have to call .config_complete before run_command(),
> but would it hurt if we reordered things to call run_command() prior
> to .get_ready?)

Yes we can do it once in .get_ready, to add tmpdir (which never
changes).  If we need to add further environment variables that change
on each script invocation then we'd do it a second time in the
function.

It's fine to do it in .get_ready because we would still store it in a
char **env variable, rather than updating the global environ or
calling setenv.

I'll update my version.

> >+  va_end (argp);
> 
> Ouch - you skip va_end() on some error paths.  On most systems, this
> is harmless, but POSIX says that va_start() without an unmatched
> va_end() is undefined behavior (a memory leak on some platforms)

Yeah I was wondering about this ...  I'll try to fix it.

Thanks,

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html




More information about the Libguestfs mailing list