[Libguestfs] [PATCH v6 05/41] utils: Split out cleanups into common/cleanups.

Richard W.M. Jones
Thu, 15 Jun 2017 17:05:55 -0000

Those cleanups which only depend on libc, gnulib or libxml2 are split
out into a separate common/cleanups directory.
---
 .gitignore                                         |  3 +-
 Makefile.am                                        |  4 +-
 align/Makefile.am                                  |  2 +
 builder/Makefile.am                                |  4 +
 cat/Makefile.am                                    | 10 +++
 common/cleanups/Makefile.am                        | 35 ++++++++
 common/cleanups/cleanups.h                         | 78 ++++++++++++++++++
 common/cleanups/gnulib-cleanups.c                  | 37 +++++++++
 common/cleanups/libxml2-cleanups.c                 | 94 ++++++++++++++++++++++
 .../cleanup.c => cleanups/stdlib-cleanups.c}       | 90
+--------------------
 common/edit/Makefile.am                            |  2 +
 common/options/Makefile.am                         |  2 +
 common/parallel/Makefile.am                        |  2 +
 common/progress/Makefile.am                        |  2 +
 common/utils/Makefile.am                           |  2 +-
 common/utils/guestfs-internal-frontend.h           | 52 +-----------
 common/utils/utils.c                               |  6 ++
 common/visit/Makefile.am                           |  1 +
 common/windows/Makefile.am                         |  2 +
 configure.ac                                       |  1 +
 customize/Makefile.am                              |  3 +
 df/Makefile.am                                     |  2 +
 diff/Makefile.am                                   |  2 +
 docs/C_SOURCE_FILES                                |  5 +-
 docs/guestfs-hacking.pod                           |  5 ++
 edit/Makefile.am                                   |  2 +
 erlang/Makefile.am                                 |  2 +
 fish/Makefile.am                                   |  4 +
 format/Makefile.am                                 |  2 +
 fuse/Makefile.am                                   | 10 +++
 get-kernel/Makefile.am                             |  3 +
 inspector/Makefile.am                              |  2 +
 java/Makefile.am                                   |  2 +
 lib/Makefile.am                                    |  4 +
 lua/Makefile.am                                    |  2 +
 make-fs/Makefile.am                                |  2 +
 mllib/Makefile.am                                  |  9 ++-
 ocaml/Makefile.am                                  |  4 +-
 p2v/Makefile.am                                    |  2 +
 php/Makefile.am                                    |  2 +-
 python/Makefile.am                                 | 14 +++-
 rescue/Makefile.am                                 |  2 +
 ruby/Rakefile.in                                   |  2 +-
 sysprep/Makefile.am                                |  3 +
 test-tool/Makefile.am                              |  2 +
 tests/c-api/Makefile.am                            | 24 ++++++
 tests/charsets/Makefile.am                         |  2 +
 tests/disks/Makefile.am                            |  2 +
 tests/events/Makefile.am                           |  2 +
 tests/mount-local/Makefile.am                      |  2 +
 tests/parallel/Makefile.am                         |  2 +
 tests/regressions/Makefile.am                      | 10 +++
 utils/boot-analysis/Makefile.am                    |  2 +
 utils/boot-benchmark/Makefile.am                   |  2 +
 utils/qemu-boot/Makefile.am                        |  2 +
 utils/qemu-speed-test/Makefile.am                  |  2 +
 v2v/Makefile.am                                    |  4 +
 57 files changed, 426 insertions(+), 151 deletions(-)

diff --git a/.gitignore b/.gitignore
index 991b1ab94..97fe2f050 100644
--- a/.gitignore
+++ b/.gitignore
@@ -488,6 +488,7 @@ Makefile.in
 /python/bindtests.py
 /python/build
 /python/c-ctype.h
+/python/cleanups.h
 /python/config.h
 /python/dist
 /python/examples/guestfs-python.3
@@ -496,11 +497,11 @@ Makefile.in
 /python/guestfs.pyc
 /python/guestfs.pyo
 /python/guestfs-internal-all.h
-/python/guestfs-internal-frontend-cleanups.h
 /python/guestfs-internal-frontend.h
 /python/ignore-value.h
 /python/MANIFEST
 /python/module.c
+/python/stdlib-cleanups.c
 /python/structs.c
 /python/__pycache__
 /python/setup.py
diff --git a/Makefile.am b/Makefile.am
index 64ac23f2e..7189519fb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,7 +38,9 @@ SUBDIRS += gnulib/tests
 endif

 # Basic source for the library.
-SUBDIRS += common/errnostring common/protocol common/qemuopts common/utils
+SUBDIRS += common/errnostring common/protocol common/qemuopts
+SUBDIRS += common/cleanups
+SUBDIRS += common/utils
 SUBDIRS += lib docs examples po

 # The daemon and the appliance.
diff --git a/align/Makefile.am b/align/Makefile.am
index 8d4fce11b..99a80dd73 100644
--- a/align/Makefile.am
+++ b/align/Makefile.am
@@ -30,6 +30,7 @@ virt_alignment_scan_SOURCES = \

 virt_alignment_scan_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -47,6 +48,7 @@ virt_alignment_scan_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/parallel/libparallel.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/builder/Makefile.am b/builder/Makefile.am
index 5f0606ca4..cfe302f9d 100644
--- a/builder/Makefile.am
+++ b/builder/Makefile.am
@@ -100,6 +100,7 @@ virt_builder_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
 	-I$(shell $(OCAMLC) -where) \
 	-I$(top_srcdir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups \
 	-I$(top_srcdir)/common/utils \
 	-I$(top_srcdir)/lib \
 	-I$(top_srcdir)/fish
@@ -121,6 +122,7 @@ XOBJECTS = $(BOBJECTS:.cmo=.cmx)
 OCAMLPACKAGES = \
 	-package str,unix \
 	-I $(top_builddir)/common/utils/.libs \
+	-I $(top_builddir)/common/cleanups/.libs \
 	-I $(top_builddir)/lib/.libs \
 	-I $(top_builddir)/gnulib/lib/.libs \
 	-I $(top_builddir)/ocaml \
@@ -138,6 +140,7 @@ endif
 OCAMLCLIBS = \
 	-pthread -lpthread \
 	-lutils \
+	-lcleanups \
 	$(LIBTINFO_LIBS) \
 	$(LIBCRYPT_LIBS) \
 	$(LIBLZMA_LIBS) \
@@ -344,6 +347,7 @@ virt_index_validate_CPPFLAGS = \
 	-I. \
 	-I$(top_builddir) \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups \
 	-I$(top_srcdir)/common/utils \
 	-I$(top_srcdir)/lib
 virt_index_validate_CFLAGS = \
diff --git a/cat/Makefile.am b/cat/Makefile.am
index 4b9171937..94e0285af 100644
--- a/cat/Makefile.am
+++ b/cat/Makefile.am
@@ -38,6 +38,7 @@ virt_cat_SOURCES = \
 virt_cat_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -52,6 +53,7 @@ virt_cat_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/windows/libwindows.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
@@ -64,6 +66,7 @@ virt_filesystems_SOURCES = \
 virt_filesystems_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -78,6 +81,7 @@ virt_filesystems_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/windows/libwindows.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
@@ -90,6 +94,7 @@ virt_log_SOURCES = \
 virt_log_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -103,6 +108,7 @@ virt_log_CFLAGS = \
 virt_log_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
@@ -115,6 +121,7 @@ virt_ls_SOURCES = \
 virt_ls_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/visit \
@@ -130,6 +137,7 @@ virt_ls_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/visit/libvisit.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
@@ -142,6 +150,7 @@ virt_tail_SOURCES = \
 virt_tail_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -156,6 +165,7 @@ virt_tail_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/windows/libwindows.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/common/cleanups/Makefile.am b/common/cleanups/Makefile.am
new file mode 100644
index 000000000..f36b8d47c
--- /dev/null
+++ b/common/cleanups/Makefile.am
@@ -0,0 +1,35 @@
+# libguestfs
+# Copyright (C) 2017 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+include $(top_srcdir)/subdir-rules.mk
+
+noinst_LTLIBRARIES = libcleanups.la
+
+# These are split into several source files so that we can link
+# to libcleanup.a and have it work even if gnulib or libxml2 are
+# not linked to the main program.
+libcleanups_la_SOURCES = \
+	cleanups.h \
+	stdlib-cleanups.c \
+	gnulib-cleanups.c \
+	libxml2-cleanups.c
+libcleanups_la_CPPFLAGS = \
+	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib
+libcleanups_la_CFLAGS = \
+	$(WARN_CFLAGS) $(WERROR_CFLAGS) \
+	$(GCC_VISIBILITY_HIDDEN) \
+	$(LIBXML2_CFLAGS)
diff --git a/common/cleanups/cleanups.h b/common/cleanups/cleanups.h
new file mode 100644
index 000000000..211bce98a
--- /dev/null
+++ b/common/cleanups/cleanups.h
@@ -0,0 +1,78 @@
+/* libguestfs
+ * Copyright (C) 2013-2017 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef GUESTFS_CLEANUPS_H_
+#define GUESTFS_CLEANUPS_H_
+
+#ifdef HAVE_ATTRIBUTE_CLEANUP
+#define CLEANUP_FREE                                    \
+  __attribute__((cleanup(guestfs_int_cleanup_free)))
+#define CLEANUP_HASH_FREE                                       \
+  __attribute__((cleanup(guestfs_int_cleanup_hash_free)))
+#define CLEANUP_UNLINK_FREE                                     \
+  __attribute__((cleanup(guestfs_int_cleanup_unlink_free)))
+#define CLEANUP_FCLOSE                                  \
+  __attribute__((cleanup(guestfs_int_cleanup_fclose)))
+#define CLEANUP_PCLOSE                                  \
+  __attribute__((cleanup(guestfs_int_cleanup_pclose)))
+#define CLEANUP_XMLFREE                                 \
+  __attribute__((cleanup(guestfs_int_cleanup_xmlFree)))
+#define CLEANUP_XMLBUFFERFREE                                   \
+  __attribute__((cleanup(guestfs_int_cleanup_xmlBufferFree)))
+#define CLEANUP_XMLFREEDOC                                      \
+  __attribute__((cleanup(guestfs_int_cleanup_xmlFreeDoc)))
+#define CLEANUP_XMLFREEURI                                              \
+  __attribute__((cleanup(guestfs_int_cleanup_xmlFreeURI)))
+#define CLEANUP_XMLFREETEXTWRITER                               \
+  __attribute__((cleanup(guestfs_int_cleanup_xmlFreeTextWriter)))
+#define CLEANUP_XMLXPATHFREECONTEXT                                     \
+  __attribute__((cleanup(guestfs_int_cleanup_xmlXPathFreeContext)))
+#define CLEANUP_XMLXPATHFREEOBJECT                                      \
+  __attribute__((cleanup(guestfs_int_cleanup_xmlXPathFreeObject)))
+#else
+#define CLEANUP_FREE
+#define CLEANUP_HASH_FREE
+#define CLEANUP_UNLINK_FREE
+#define CLEANUP_FCLOSE
+#define CLEANUP_PCLOSE
+#define CLEANUP_XMLFREE
+#define CLEANUP_XMLBUFFERFREE
+#define CLEANUP_XMLFREEDOC
+#define CLEANUP_XMLFREEURI
+#define CLEANUP_XMLFREETEXTWRITER
+#define CLEANUP_XMLXPATHFREECONTEXT
+#define CLEANUP_XMLXPATHFREEOBJECT
+#endif
+
+/* These functions are used internally by the CLEANUP_* macros.
+ * Don't call them directly.
+ */
+extern void guestfs_int_cleanup_free (void *ptr);
+extern void guestfs_int_cleanup_hash_free (void *ptr);
+extern void guestfs_int_cleanup_unlink_free (char **ptr);
+extern void guestfs_int_cleanup_fclose (void *ptr);
+extern void guestfs_int_cleanup_pclose (void *ptr);
+extern void guestfs_int_cleanup_xmlFree (void *ptr);
+extern void guestfs_int_cleanup_xmlBufferFree (void *ptr);
+extern void guestfs_int_cleanup_xmlFreeDoc (void *ptr);
+extern void guestfs_int_cleanup_xmlFreeURI (void *ptr);
+extern void guestfs_int_cleanup_xmlFreeTextWriter (void *ptr);
+extern void guestfs_int_cleanup_xmlXPathFreeContext (void *ptr);
+extern void guestfs_int_cleanup_xmlXPathFreeObject (void *ptr);
+
+#endif /* GUESTFS_CLEANUPS_H_ */
diff --git a/common/cleanups/gnulib-cleanups.c
b/common/cleanups/gnulib-cleanups.c
new file mode 100644
index 000000000..45b99c513
--- /dev/null
+++ b/common/cleanups/gnulib-cleanups.c
@@ -0,0 +1,37 @@
+/* libguestfs
+ * Copyright (C) 2013-2017 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "hash.h"
+
+#include "cleanups.h"
+
+void
+guestfs_int_cleanup_hash_free (void *ptr)
+{
+  Hash_table *h = * (Hash_table **) ptr;
+
+  if (h)
+    hash_free (h);
+}
diff --git a/common/cleanups/libxml2-cleanups.c
b/common/cleanups/libxml2-cleanups.c
new file mode 100644
index 000000000..066573fef
--- /dev/null
+++ b/common/cleanups/libxml2-cleanups.c
@@ -0,0 +1,94 @@
+/* libguestfs
+ * Copyright (C) 2013-2017 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <libxml/uri.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+#include <libxml/xmlwriter.h>
+
+#include "cleanups.h"
+
+void
+guestfs_int_cleanup_xmlFree (void *ptr)
+{
+  xmlChar *buf = * (xmlChar **) ptr;
+
+  if (buf)
+    xmlFree (buf);
+}
+
+void
+guestfs_int_cleanup_xmlBufferFree (void *ptr)
+{
+  xmlBufferPtr xb = * (xmlBufferPtr *) ptr;
+
+  if (xb)
+    xmlBufferFree (xb);
+}
+
+void
+guestfs_int_cleanup_xmlFreeDoc (void *ptr)
+{
+  xmlDocPtr doc = * (xmlDocPtr *) ptr;
+
+  if (doc)
+    xmlFreeDoc (doc);
+}
+
+void
+guestfs_int_cleanup_xmlFreeURI (void *ptr)
+{
+  xmlURIPtr uri = * (xmlURIPtr *) ptr;
+
+  if (uri)
+    xmlFreeURI (uri);
+}
+
+void
+guestfs_int_cleanup_xmlFreeTextWriter (void *ptr)
+{
+  xmlTextWriterPtr xo = * (xmlTextWriterPtr *) ptr;
+
+  if (xo)
+    xmlFreeTextWriter (xo);
+}
+
+void
+guestfs_int_cleanup_xmlXPathFreeContext (void *ptr)
+{
+  xmlXPathContextPtr ctx = * (xmlXPathContextPtr *) ptr;
+
+  if (ctx)
+    xmlXPathFreeContext (ctx);
+}
+
+void
+guestfs_int_cleanup_xmlXPathFreeObject (void *ptr)
+{
+  xmlXPathObjectPtr obj = * (xmlXPathObjectPtr *) ptr;
+
+  if (obj)
+    xmlXPathFreeObject (obj);
+}
diff --git a/common/utils/cleanup.c b/common/cleanups/stdlib-cleanups.c
similarity index 62%
rename from common/utils/cleanup.c
rename to common/cleanups/stdlib-cleanups.c
index 6c4558c39..0512a86a2 100644
--- a/common/utils/cleanup.c
+++ b/common/cleanups/stdlib-cleanups.c
@@ -1,5 +1,5 @@
 /* libguestfs
- * Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2013-2017 Red Hat Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -63,15 +63,7 @@
 #include <unistd.h>
 #include <string.h>

-#include <libxml/uri.h>
-#include <libxml/tree.h>
-#include <libxml/xpath.h>
-#include <libxml/xmlwriter.h>
-
-#include "hash.h"
-
-#include "guestfs.h"
-#include "guestfs-internal-frontend.h"
+#include "cleanups.h"

 void
 guestfs_int_cleanup_free (void *ptr)
@@ -80,21 +72,6 @@ guestfs_int_cleanup_free (void *ptr)
 }

 void
-guestfs_int_cleanup_free_string_list (char ***ptr)
-{
-  guestfs_int_free_string_list (*ptr);
-}
-
-void
-guestfs_int_cleanup_hash_free (void *ptr)
-{
-  Hash_table *h = * (Hash_table **) ptr;
-
-  if (h)
-    hash_free (h);
-}
-
-void
 guestfs_int_cleanup_unlink_free (char **ptr)
 {
   char *filename = *ptr;
@@ -106,69 +83,6 @@ guestfs_int_cleanup_unlink_free (char **ptr)
 }

 void
-guestfs_int_cleanup_xmlFree (void *ptr)
-{
-  xmlChar *buf = * (xmlChar **) ptr;
-
-  if (buf)
-    xmlFree (buf);
-}
-
-void
-guestfs_int_cleanup_xmlBufferFree (void *ptr)
-{
-  xmlBufferPtr xb = * (xmlBufferPtr *) ptr;
-
-  if (xb)
-    xmlBufferFree (xb);
-}
-
-void
-guestfs_int_cleanup_xmlFreeDoc (void *ptr)
-{
-  xmlDocPtr doc = * (xmlDocPtr *) ptr;
-
-  if (doc)
-    xmlFreeDoc (doc);
-}
-
-void
-guestfs_int_cleanup_xmlFreeURI (void *ptr)
-{
-  xmlURIPtr uri = * (xmlURIPtr *) ptr;
-
-  if (uri)
-    xmlFreeURI (uri);
-}
-
-void
-guestfs_int_cleanup_xmlFreeTextWriter (void *ptr)
-{
-  xmlTextWriterPtr xo = * (xmlTextWriterPtr *) ptr;
-
-  if (xo)
-    xmlFreeTextWriter (xo);
-}
-
-void
-guestfs_int_cleanup_xmlXPathFreeContext (void *ptr)
-{
-  xmlXPathContextPtr ctx = * (xmlXPathContextPtr *) ptr;
-
-  if (ctx)
-    xmlXPathFreeContext (ctx);
-}
-
-void
-guestfs_int_cleanup_xmlXPathFreeObject (void *ptr)
-{
-  xmlXPathObjectPtr obj = * (xmlXPathObjectPtr *) ptr;
-
-  if (obj)
-    xmlXPathFreeObject (obj);
-}
-
-void
 guestfs_int_cleanup_fclose (void *ptr)
 {
   FILE *f = * (FILE **) ptr;
diff --git a/common/edit/Makefile.am b/common/edit/Makefile.am
index 592f6fc36..93a1bf5b0 100644
--- a/common/edit/Makefile.am
+++ b/common/edit/Makefile.am
@@ -26,10 +26,12 @@ libedit_la_SOURCES = \
 	file-edit.h
 libedit_la_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 libedit_la_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 libedit_la_LIBADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la
diff --git a/common/options/Makefile.am b/common/options/Makefile.am
index 4aab6b110..372653e82 100644
--- a/common/options/Makefile.am
+++ b/common/options/Makefile.am
@@ -35,6 +35,7 @@ liboptions_la_SOURCES = \
 	uri.c
 liboptions_la_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib
@@ -44,6 +45,7 @@ liboptions_la_CFLAGS = \
 	$(LIBXML2_CFLAGS)
 liboptions_la_LIBADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBCONFIG_LIBS) \
 	$(LIBXML2_LIBS) \
diff --git a/common/parallel/Makefile.am b/common/parallel/Makefile.am
index 5518e8909..ba541bc4e 100644
--- a/common/parallel/Makefile.am
+++ b/common/parallel/Makefile.am
@@ -31,6 +31,7 @@ libparallel_la_SOURCES = \
 	parallel.h
 libparallel_la_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -43,6 +44,7 @@ libparallel_la_CFLAGS = \
 libparallel_la_LIBADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/common/progress/Makefile.am b/common/progress/Makefile.am
index afb03c876..d70b34bf6 100644
--- a/common/progress/Makefile.am
+++ b/common/progress/Makefile.am
@@ -26,6 +26,7 @@ libprogress_la_SOURCES = \
 	progress.h
 libprogress_la_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 libprogress_la_CFLAGS = \
@@ -33,5 +34,6 @@ libprogress_la_CFLAGS = \
 	$(LIBTINFO_CFLAGS)
 libprogress_la_LIBADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBTINFO_LIBS)
diff --git a/common/utils/Makefile.am b/common/utils/Makefile.am
index 81a567b86..485909bbe 100644
--- a/common/utils/Makefile.am
+++ b/common/utils/Makefile.am
@@ -34,7 +34,6 @@ noinst_LTLIBRARIES = libutils.la

 libutils_la_SOURCES = \
 	../../lib/guestfs.h \
-	cleanup.c \
 	guestfs-internal-frontend.h \
 	guestfs-internal-frontend-cleanups.h \
 	structs-cleanup.c \
@@ -46,6 +45,7 @@ libutils_la_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DGUESTFS_PRIVATE=1 \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 libutils_la_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS) \
diff --git a/common/utils/guestfs-internal-frontend.h
b/common/utils/guestfs-internal-frontend.h
index e48f4eb49..dacc92e49 100644
--- a/common/utils/guestfs-internal-frontend.h
+++ b/common/utils/guestfs-internal-frontend.h
@@ -35,48 +35,16 @@
 #include <stdbool.h>

 #include "guestfs-internal-all.h"
+#include "cleanups.h"

 #define _(str) dgettext(PACKAGE, (str))
 #define N_(str) dgettext(PACKAGE, (str))

 #ifdef HAVE_ATTRIBUTE_CLEANUP
-#define CLEANUP_FREE __attribute__((cleanup(guestfs_int_cleanup_free)))
 #define CLEANUP_FREE_STRING_LIST                                \
   __attribute__((cleanup(guestfs_int_cleanup_free_string_list)))
-#define CLEANUP_HASH_FREE                               \
-  __attribute__((cleanup(guestfs_int_cleanup_hash_free)))
-#define CLEANUP_UNLINK_FREE                                     \
-  __attribute__((cleanup(guestfs_int_cleanup_unlink_free)))
-#define CLEANUP_XMLFREE                                         \
-  __attribute__((cleanup(guestfs_int_cleanup_xmlFree)))
-#define CLEANUP_XMLBUFFERFREE                                   \
-  __attribute__((cleanup(guestfs_int_cleanup_xmlBufferFree)))
-#define CLEANUP_XMLFREEDOC                                      \
-  __attribute__((cleanup(guestfs_int_cleanup_xmlFreeDoc)))
-#define CLEANUP_XMLFREEURI                                              \
-  __attribute__((cleanup(guestfs_int_cleanup_xmlFreeURI)))
-#define CLEANUP_XMLFREETEXTWRITER                               \
-  __attribute__((cleanup(guestfs_int_cleanup_xmlFreeTextWriter)))
-#define CLEANUP_XMLXPATHFREECONTEXT                                     \
-  __attribute__((cleanup(guestfs_int_cleanup_xmlXPathFreeContext)))
-#define CLEANUP_XMLXPATHFREEOBJECT                                      \
-  __attribute__((cleanup(guestfs_int_cleanup_xmlXPathFreeObject)))
-#define CLEANUP_FCLOSE __attribute__((cleanup(guestfs_int_cleanup_fclose)))
-#define CLEANUP_PCLOSE __attribute__((cleanup(guestfs_int_cleanup_pclose)))
 #else
-#define CLEANUP_FREE
 #define CLEANUP_FREE_STRING_LIST
-#define CLEANUP_HASH_FREE
-#define CLEANUP_UNLINK_FREE
-#define CLEANUP_XMLFREE
-#define CLEANUP_XMLBUFFERFREE
-#define CLEANUP_XMLFREEDOC
-#define CLEANUP_XMLFREEURI
-#define CLEANUP_XMLFREETEXTWRITER
-#define CLEANUP_XMLXPATHFREECONTEXT
-#define CLEANUP_XMLXPATHFREEOBJECT
-#define CLEANUP_FCLOSE
-#define CLEANUP_PCLOSE
 #endif

 /* utils.c */
@@ -101,6 +69,7 @@ extern void guestfs_int_fadvise_noreuse (int fd);
 //extern void guestfs_int_fadvise_dontneed (int fd);
 //extern void guestfs_int_fadvise_willneed (int fd);
 extern char *guestfs_int_shell_unquote (const char *str);
+extern void guestfs_int_cleanup_free_string_list (char ***ptr);

 /* uefi.c */
 struct uefi_firmware {
@@ -114,23 +83,6 @@ extern struct uefi_firmware
guestfs_int_uefi_i386_firmware[];
 extern struct uefi_firmware guestfs_int_uefi_x86_64_firmware[];
 extern struct uefi_firmware guestfs_int_uefi_aarch64_firmware[];

-/* These functions are used internally by the CLEANUP_* macros.
- * Don't call them directly.
- */
-extern void guestfs_int_cleanup_free (void *ptr);
-extern void guestfs_int_cleanup_free_string_list (char ***ptr);
-extern void guestfs_int_cleanup_hash_free (void *ptr);
-extern void guestfs_int_cleanup_unlink_free (char **ptr);
-extern void guestfs_int_cleanup_xmlFree (void *ptr);
-extern void guestfs_int_cleanup_xmlBufferFree (void *ptr);
-extern void guestfs_int_cleanup_xmlFreeDoc (void *ptr);
-extern void guestfs_int_cleanup_xmlFreeURI (void *ptr);
-extern void guestfs_int_cleanup_xmlFreeTextWriter (void *ptr);
-extern void guestfs_int_cleanup_xmlXPathFreeContext (void *ptr);
-extern void guestfs_int_cleanup_xmlXPathFreeObject (void *ptr);
-extern void guestfs_int_cleanup_fclose (void *ptr);
-extern void guestfs_int_cleanup_pclose (void *ptr);
-
 /* These are in a separate header so the header can be generated.
  * Don't include the following file directly:
  */
diff --git a/common/utils/utils.c b/common/utils/utils.c
index bdc8449a2..4ac214ded 100644
--- a/common/utils/utils.c
+++ b/common/utils/utils.c
@@ -624,3 +624,9 @@ guestfs_int_shell_unquote (const char *str)

   return strdup (str);
 }
+
+void
+guestfs_int_cleanup_free_string_list (char ***ptr)
+{
+  guestfs_int_free_string_list (*ptr);
+}
diff --git a/common/visit/Makefile.am b/common/visit/Makefile.am
index e95954a11..519088769 100644
--- a/common/visit/Makefile.am
+++ b/common/visit/Makefile.am
@@ -27,6 +27,7 @@ libvisit_la_CPPFLAGS = \
 	-DGUESTFS_PRIVATE=1 \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils
 libvisit_la_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS) \
diff --git a/common/windows/Makefile.am b/common/windows/Makefile.am
index 043252b71..16cfc6ce0 100644
--- a/common/windows/Makefile.am
+++ b/common/windows/Makefile.am
@@ -26,6 +26,7 @@ libwindows_la_SOURCES = \
 	windows.h
 libwindows_la_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib
@@ -33,5 +34,6 @@ libwindows_la_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 libwindows_la_LIBADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LTLIBINTL)
diff --git a/configure.ac b/configure.ac
index eba149241..33cdbd39e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -182,6 +182,7 @@ AC_CONFIG_FILES([Makefile
                  builder/test-simplestreams/virt-builder/repos.d/cirros.conf
                  builder/test-website/virt-builder/repos.d/libguestfs.conf
                  cat/Makefile
+                 common/cleanups/Makefile
                  common/errnostring/Makefile
                  common/edit/Makefile
                  common/miniexpect/Makefile
diff --git a/customize/Makefile.am b/customize/Makefile.am
index 674134b70..815513b25 100644
--- a/customize/Makefile.am
+++ b/customize/Makefile.am
@@ -96,6 +96,7 @@ libcustomize_a_CPPFLAGS = \
 	-I$(top_builddir) \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
 	-I$(shell $(OCAMLC) -where) \
+	-I$(top_srcdir)/common/cleanups \
 	-I$(top_srcdir)/common/utils \
 	-I$(top_srcdir)/lib \
 	-I$(top_srcdir)/common/edit
@@ -120,6 +121,7 @@ endif
 OCAMLPACKAGES = \
 	-package str,unix \
 	-I $(top_builddir)/common/utils/.libs \
+	-I $(top_builddir)/common/cleanups/.libs \
 	-I $(top_builddir)/lib/.libs \
 	-I $(top_builddir)/gnulib/lib/.libs \
 	-I $(top_builddir)/ocaml \
@@ -159,6 +161,7 @@ OCAMLLINKFLAGS = \

 OCAMLCLIBS = \
 	-lutils \
+	-lcleanups \
 	$(LIBTINFO_LIBS) \
 	$(LIBCRYPT_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/df/Makefile.am b/df/Makefile.am
index 8725402bc..30faf3ee1 100644
--- a/df/Makefile.am
+++ b/df/Makefile.am
@@ -35,6 +35,7 @@ virt_df_SOURCES = \
 virt_df_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -51,6 +52,7 @@ virt_df_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/parallel/libparallel.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/diff/Makefile.am b/diff/Makefile.am
index 5e71b74de..06378dc78 100644
--- a/diff/Makefile.am
+++ b/diff/Makefile.am
@@ -30,6 +30,7 @@ virt_diff_SOURCES = \
 virt_diff_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/visit -I$(top_builddir)/common/visit \
@@ -45,6 +46,7 @@ virt_diff_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/visit/libvisit.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
index 71c17603f..3382fce56 100644
--- a/docs/C_SOURCE_FILES
+++ b/docs/C_SOURCE_FILES
@@ -11,6 +11,10 @@ cat/filesystems.c
 cat/log.c
 cat/ls.c
 cat/tail.c
+common/cleanups/cleanups.h
+common/cleanups/gnulib-cleanups.c
+common/cleanups/libxml2-cleanups.c
+common/cleanups/stdlib-cleanups.c
 common/edit/file-edit.c
 common/edit/file-edit.h
 common/miniexpect/miniexpect.c
@@ -42,7 +46,6 @@ common/progress/progress.h
 common/qemuopts/qemuopts-tests.c
 common/qemuopts/qemuopts.c
 common/qemuopts/qemuopts.h
-common/utils/cleanup.c
 common/utils/guestfs-internal-frontend-cleanups.h
 common/utils/guestfs-internal-frontend.h
 common/utils/structs-cleanup.c
diff --git a/docs/guestfs-hacking.pod b/docs/guestfs-hacking.pod
index beb44d2dc..fdb7a9e63 100644
--- a/docs/guestfs-hacking.pod
+++ b/docs/guestfs-hacking.pod
@@ -83,6 +83,11 @@ subdirectory:

 =over 4

+=item F<common/cleanups>
+
+Common code for implementing C<CLEANUP_FREE> (and similar) macros used
+to automatically free pointers at the end of the current code block.
+
 =item F<common/edit>

 Common code for interactively and non-interactively editing files
diff --git a/edit/Makefile.am b/edit/Makefile.am
index f98e374f5..9fb9e5a12 100644
--- a/edit/Makefile.am
+++ b/edit/Makefile.am
@@ -30,6 +30,7 @@ virt_edit_SOURCES = \
 virt_edit_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/edit -I$(top_builddir)/common/edit \
@@ -46,6 +47,7 @@ virt_edit_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/windows/libwindows.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/erlang/Makefile.am b/erlang/Makefile.am
index 75b3ec9d5..93f6f1e3d 100644
--- a/erlang/Makefile.am
+++ b/erlang/Makefile.am
@@ -80,6 +80,7 @@ erl_guestfs_SOURCES = \

 erl_guestfs_CPPFLAGS = \
 	-DGUESTFS_PRIVATE=1 \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(srcdir)/../gnulib/lib -I../gnulib/lib \
@@ -93,6 +94,7 @@ erl_guestfs_LDADD = \
 	$(ERLANG_LIB_DIR_erl_interface)/lib/libei.a \
 	-lpthread \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/fish/Makefile.am b/fish/Makefile.am
index 9c07761e2..d74a70af7 100644
--- a/fish/Makefile.am
+++ b/fish/Makefile.am
@@ -107,12 +107,14 @@ librc_protocol_la_CFLAGS = -Wall -Wno-unused
-fno-strict-aliasing
 # lots of warnings so we must compile it in a separate mini-library.
 libcmds_la_SOURCES = cmds-gperf.c
 libcmds_la_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(srcdir)/../gnulib/lib -I../gnulib/lib
 libcmds_la_CFLAGS  libcmds_la_LIBADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(LTLIBINTL)

 cmds-gperf.c: cmds-gperf.gperf
@@ -123,6 +125,7 @@ cmds-gperf.c: cmds-gperf.gperf
 guestfish_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/edit -I$(top_builddir)/common/edit \
@@ -142,6 +145,7 @@ guestfish_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/progress/libprogress.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBCONFIG_LIBS) \
diff --git a/format/Makefile.am b/format/Makefile.am
index 2d3cc774c..fa04c86ea 100644
--- a/format/Makefile.am
+++ b/format/Makefile.am
@@ -30,6 +30,7 @@ virt_format_SOURCES = \
 virt_format_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -44,6 +45,7 @@ virt_format_CFLAGS = \
 virt_format_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/fuse/Makefile.am b/fuse/Makefile.am
index c3d4398a0..486ab0048 100644
--- a/fuse/Makefile.am
+++ b/fuse/Makefile.am
@@ -38,6 +38,7 @@ guestmount_SOURCES = \
 guestmount_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -53,6 +54,7 @@ guestmount_LDADD = \
 	$(FUSE_LIBS) \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBCONFIG_LIBS) \
 	$(LIBXML2_LIBS) \
@@ -67,6 +69,7 @@ guestunmount_SOURCES = \

 guestunmount_CPPFLAGS = \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -79,6 +82,7 @@ guestunmount_CFLAGS = \
 guestunmount_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
@@ -140,6 +144,7 @@ test_fuse_SOURCES = \
 	test-fuse.c

 test_fuse_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(srcdir)/../gnulib/lib -I../gnulib/lib
@@ -149,6 +154,7 @@ test_fuse_CFLAGS = \

 test_fuse_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
@@ -159,6 +165,7 @@ test_guestmount_fd_SOURCES = \
 	test-guestmount-fd.c

 test_guestmount_fd_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(srcdir)/../gnulib/lib -I../gnulib/lib
@@ -168,6 +175,7 @@ test_guestmount_fd_CFLAGS = \

 test_guestmount_fd_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
@@ -178,6 +186,7 @@ test_guestunmount_fd_SOURCES = \
 	test-guestunmount-fd.c

 test_guestunmount_fd_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(srcdir)/../gnulib/lib -I../gnulib/lib
@@ -187,6 +196,7 @@ test_guestunmount_fd_CFLAGS = \

 test_guestunmount_fd_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/get-kernel/Makefile.am b/get-kernel/Makefile.am
index c6454d7a4..16cf90eb9 100644
--- a/get-kernel/Makefile.am
+++ b/get-kernel/Makefile.am
@@ -43,6 +43,7 @@ virt_get_kernel_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
 	-I$(shell $(OCAMLC) -where) \
 	-I$(top_srcdir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups \
 	-I$(top_srcdir)/common/utils \
 	-I$(top_srcdir)/lib \
 	-I$(top_srcdir)/fish
@@ -59,6 +60,7 @@ XOBJECTS = $(BOBJECTS:.cmo=.cmx)
 # installed copy of libguestfs.
 OCAMLPACKAGES = \
 	-package str,unix \
+	-I $(top_builddir)/common/cleanups/.libs \
 	-I $(top_builddir)/common/utils/.libs \
 	-I $(top_builddir)/lib/.libs \
 	-I $(top_builddir)/gnulib/lib/.libs \
@@ -72,6 +74,7 @@ endif
 OCAMLCLIBS = \
 	-pthread -lpthread \
 	-lutils \
+	-lcleanups \
 	$(LIBXML2_LIBS) \
 	$(LIBINTL) \
 	-lgnu
diff --git a/inspector/Makefile.am b/inspector/Makefile.am
index 753e2c93c..980852cde 100644
--- a/inspector/Makefile.am
+++ b/inspector/Makefile.am
@@ -58,6 +58,7 @@ virt_inspector_SOURCES = \
 virt_inspector_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -71,6 +72,7 @@ virt_inspector_CFLAGS = \
 virt_inspector_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/java/Makefile.am b/java/Makefile.am
index ea64f5525..089ac0177 100644
--- a/java/Makefile.am
+++ b/java/Makefile.am
@@ -108,6 +108,7 @@ libguestfs_jni_la_SOURCES = \

 libguestfs_jni_la_CPPFLAGS = \
 	-DGUESTFS_PRIVATE=1 \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib

@@ -117,6 +118,7 @@ libguestfs_jni_la_CFLAGS = \

 libguestfs_jni_la_LIBADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la

 libguestfs_jni_la_LDFLAGS = -version-info $(JNI_VERSION_INFO) -shared
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 360ce9c92..90c657514 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -138,6 +138,7 @@ libguestfs_la_CPPFLAGS = \
 	-I$(top_srcdir)/common/errnostring -I$(top_builddir)/common/errnostring \
 	-I$(top_srcdir)/common/protocol -I$(top_builddir)/common/protocol \
 	-I$(top_srcdir)/common/qemuopts -I$(top_builddir)/common/qemuopts \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib

@@ -155,6 +156,7 @@ libguestfs_la_LIBADD = \
 	../common/protocol/libprotocol.la \
 	../common/qemuopts/libqemuopts.la \
 	../common/utils/libutils.la \
+	../common/cleanups/libcleanups.la \
 	$(PCRE_LIBS) $(MAGIC_LIBS) \
 	$(LIBVIRT_LIBS) $(LIBXML2_LIBS) \
 	$(SELINUX_LIBS) \
@@ -214,6 +216,7 @@ check_PROGRAMS = unit-tests
 unit_tests_SOURCES = unit-tests.c
 unit_tests_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I.
 unit_tests_CFLAGS = \
@@ -223,6 +226,7 @@ unit_tests_CFLAGS = \
 # library.
 unit_tests_LDADD = \
 	../common/utils/libutils.la \
+	../common/cleanups/libcleanups.la \
 	$(libguestfs_la_OBJECTS) \
 	$(libguestfs_la_LIBADD)

diff --git a/lua/Makefile.am b/lua/Makefile.am
index f90c1d7cb..83d1621a5 100644
--- a/lua/Makefile.am
+++ b/lua/Makefile.am
@@ -41,6 +41,7 @@ libluaguestfs_la_SOURCES = lua-guestfs.c

 libluaguestfs_la_CPPFLAGS = \
 	-DGUESTFS_PRIVATE=1 \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib

@@ -50,6 +51,7 @@ libluaguestfs_la_CFLAGS = \

 libluaguestfs_la_LIBADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/make-fs/Makefile.am b/make-fs/Makefile.am
index bef0e7bf8..7b5dee127 100644
--- a/make-fs/Makefile.am
+++ b/make-fs/Makefile.am
@@ -30,6 +30,7 @@ virt_make_fs_SOURCES = \
 virt_make_fs_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -43,6 +44,7 @@ virt_make_fs_CFLAGS = \
 virt_make_fs_LDADD = \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LTLIBINTL) \
diff --git a/mllib/Makefile.am b/mllib/Makefile.am
index 5f6f7fa85..ee251e99d 100644
--- a/mllib/Makefile.am
+++ b/mllib/Makefile.am
@@ -86,6 +86,7 @@ libmllib_a_CPPFLAGS = \
 	-I$(top_builddir) \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
 	-I$(shell $(OCAMLC) -where) \
+	-I$(top_srcdir)/common/cleanups \
 	-I$(top_srcdir)/common/utils \
 	-I$(top_srcdir)/lib \
 	-I$(top_srcdir)/common/options \
@@ -105,6 +106,7 @@ XOBJECTS = $(BOBJECTS:.cmo=.cmx)
 OCAMLPACKAGES = \
 	-package str,unix \
 	-I $(top_builddir)/common/utils/.libs \
+	-I $(top_builddir)/common/cleanups/.libs \
 	-I $(top_builddir)/lib/.libs \
 	-I $(top_builddir)/gnulib/lib/.libs \
 	-I $(top_builddir)/ocaml \
@@ -121,6 +123,7 @@ endif

 OCAMLCLIBS = \
 	-lutils \
+	-lcleanups \
 	$(LIBTINFO_LIBS) \
 	$(LIBCRYPT_LIBS) \
 	$(LIBVIRT_LIBS) \
@@ -198,7 +201,8 @@ common_utils_tests_DEPENDENCIES = \
 	$(MLLIB_CMA) \
 	$(top_srcdir)/ocaml-link.sh
 common_utils_tests_LINK = \
-	$(top_srcdir)/ocaml-link.sh -cclib '-lutils $(LIBXML2_LIBS) -lgnu' --
\
+	$(top_srcdir)/ocaml-link.sh \
+	  -cclib '-lutils -lcleanups $(LIBXML2_LIBS) -lgnu' -- \
 	  $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLLINKFLAGS) \
 	  $(OCAMLPACKAGES) $(OCAMLPACKAGES_TESTS) \
 	  $(common_utils_tests_THEOBJECTS) -o $@
@@ -209,7 +213,8 @@ getopt_tests_DEPENDENCIES = \
 	$(MLLIB_CMA) \
 	$(top_srcdir)/ocaml-link.sh
 getopt_tests_LINK = \
-	$(top_srcdir)/ocaml-link.sh -cclib '-lutils $(LIBXML2_LIBS) -lgnu' --
\
+	$(top_srcdir)/ocaml-link.sh \
+	  -cclib '-lutils -lcleanups $(LIBXML2_LIBS) -lgnu' -- \
 	  $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLLINKFLAGS) \
 	  $(OCAMLPACKAGES) $(OCAMLPACKAGES_TESTS) \
 	  $(getopt_tests_THEOBJECTS) -o $@
diff --git a/ocaml/Makefile.am b/ocaml/Makefile.am
index 57ecd608b..d85e8ea6d 100644
--- a/ocaml/Makefile.am
+++ b/ocaml/Makefile.am
@@ -82,6 +82,7 @@ endif
 libguestfsocaml_a_CPPFLAGS = \
 	-DGUESTFS_PRIVATE=1 \
 	-I$(top_builddir) -I$(OCAMLLIB) -I$(top_srcdir)/ocaml \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/gnulib/lib -I../gnulib/lib
@@ -94,7 +95,8 @@ libguestfsocaml_a_SOURCES = \
 	guestfs-c.c \
 	guestfs-c-actions.c \
 	guestfs-c-errnos.c \
-	../common/utils/utils.c
+	../common/utils/utils.c \
+	../common/cleanups/stdlib-cleanups.c

 if HAVE_OCAMLDOC

diff --git a/p2v/Makefile.am b/p2v/Makefile.am
index 12509c369..c1473bd7a 100644
--- a/p2v/Makefile.am
+++ b/p2v/Makefile.am
@@ -98,6 +98,7 @@ virt_p2v_SOURCES = \

 virt_p2v_CPPFLAGS = \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/miniexpect -I$(top_builddir)/common/miniexpect \
@@ -113,6 +114,7 @@ virt_p2v_CFLAGS = \

 virt_p2v_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/common/miniexpect/libminiexpect.la \
 	$(PCRE_LIBS) \
 	$(LIBXML2_LIBS) \
diff --git a/php/Makefile.am b/php/Makefile.am
index a974cdf21..74921d388 100644
--- a/php/Makefile.am
+++ b/php/Makefile.am
@@ -38,7 +38,7 @@ php_DATA = guestfs_php.ini
 # and we need to add the library to EXTRA_LDFLAGS.
 all: check-builddir-equals-srcdir extension/config.h
 	$(MAKE) -C extension \
-	  EXTRA_INCLUDES="-I$(abs_srcdir)/../common/utils
-I$(abs_srcdir)/../lib" \
+	  EXTRA_INCLUDES="-I$(abs_srcdir)/../common/cleanups
-I$(abs_srcdir)/../common/utils -I$(abs_srcdir)/../lib" \
 	  EXTRA_LDFLAGS="-L$(abs_srcdir)/../lib/.libs -lguestfs" \
 	  EXTRA_CFLAGS="-DGUESTFS_PRIVATE=1" \
 	  all
diff --git a/python/Makefile.am b/python/Makefile.am
index ae90aa01d..fd0825648 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -67,6 +67,7 @@ libguestfsmod_la_SOURCES = \
 libguestfsmod_la_CPPFLAGS = \
 	-DGUESTFS_PRIVATE=1 \
 	$(PYTHON_CFLAGS) \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib

@@ -75,6 +76,7 @@ libguestfsmod_la_CFLAGS = \

 libguestfsmod_la_LIBADD = \
 	$(top_builddir)/common/utils/libutils_la-utils.lo \
+	$(top_builddir)/common/cleanups/libcleanups_la-stdlib-cleanups.lo \
 	$(top_builddir)/lib/libguestfs.la

 libguestfsmod_la_LDFLAGS = -avoid-version -shared -module -shrext
$(PYTHON_EXT_SUFFIX)
@@ -97,11 +99,12 @@ setup-install: setup.py stamp-extra-files
 # to hard-link any extra files we need into the local directory.
 stamp-extra-files: \
 	  c-ctype.h \
+	  cleanups.h \
 	  config.h \
 	  guestfs-internal-all.h \
-	  guestfs-internal-frontend-cleanups.h \
 	  guestfs-internal-frontend.h \
 	  ignore-value.h \
+	  stdlib-cleanups.c \
 	  utils.c
 	touch $@

@@ -111,18 +114,21 @@ config.h:
 c-ctype.h:
 	ln $(top_srcdir)/gnulib/lib/c-ctype.h $@

+cleanups.h:
+	ln $(top_srcdir)/common/cleanups/cleanups.h $@
+
 ignore-value.h:
 	ln $(top_srcdir)/gnulib/lib/ignore-value.h $@

 guestfs-internal-all.h:
 	ln $(top_srcdir)/lib/guestfs-internal-all.h $@

-guestfs-internal-frontend-cleanups.h:
-	ln $(top_srcdir)/common/utils/guestfs-internal-frontend-cleanups.h $@
-
 guestfs-internal-frontend.h:
 	ln $(top_srcdir)/common/utils/guestfs-internal-frontend.h $@

+stdlib-cleanups.c:
+	ln $(top_srcdir)/common/cleanups/stdlib-cleanups.c $@
+
 utils.c:
 	ln $(top_srcdir)/common/utils/utils.c $@

diff --git a/rescue/Makefile.am b/rescue/Makefile.am
index d478c8e3d..20950d2f8 100644
--- a/rescue/Makefile.am
+++ b/rescue/Makefile.am
@@ -35,6 +35,7 @@ virt_rescue_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-DGUESTFS_PRIVATE=1 \
 	-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/options -I$(top_builddir)/common/options \
@@ -49,6 +50,7 @@ virt_rescue_LDADD = \
 	$(top_builddir)/common/windows/libwindows.la \
 	$(top_builddir)/common/options/liboptions.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBCONFIG_LIBS) \
 	$(LIBXML2_LIBS) \
diff --git a/ruby/Rakefile.in b/ruby/Rakefile.in
index 18ec311c5..ee4222501 100644
--- a/ruby/Rakefile.in
+++ b/ruby/Rakefile.in
@@ -65,7 +65,7 @@ CLOBBER.include [ "@builddir@/config.save",
"@builddir@/ext/**/mkmf.log",
 # Build locally

 file MAKEFILE => EXT_CONF do |t|
-     unless sh "top_srcdir=$(pwd)/@top_srcdir@;
top_builddir=$(pwd)/@top_builddir@; export ARCHFLAGS=\"-arch $(uname
-m)\"; mkdir -p @builddir@/ext/guestfs; cd @builddir@/ext/guestfs; @RUBY@
#{EXT_CONF}
--with-_guestfs-include=$top_srcdir/common/utils:$top_srcdir/lib:$top_builddir
--with-_guestfs-lib=$top_builddir/lib/.libs"
+     unless sh "top_srcdir=$(pwd)/@top_srcdir@;
top_builddir=$(pwd)/@top_builddir@; export ARCHFLAGS=\"-arch $(uname
-m)\"; mkdir -p @builddir@/ext/guestfs; cd @builddir@/ext/guestfs; @RUBY@
#{EXT_CONF}
--with-_guestfs-include=$top_srcdir/common/cleanups:$top_srcdir/common/utils:$top_srcdir/lib:$top_builddir
--with-_guestfs-lib=$top_builddir/lib/.libs"
          $stderr.puts "Failed to run extconf"
          break
      end
diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
index c2adb1a6e..fcd2923f5 100644
--- a/sysprep/Makefile.am
+++ b/sysprep/Makefile.am
@@ -92,6 +92,7 @@ virt_sysprep_CPPFLAGS = \
 	-I$(top_builddir) \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
 	-I$(shell $(OCAMLC) -where) \
+	-I$(top_srcdir)/common/cleanups \
 	-I$(top_srcdir)/common/utils \
 	-I$(top_srcdir)/lib \
 	-I$(top_srcdir)/fish
@@ -107,6 +108,7 @@ XOBJECTS = $(BOBJECTS:.cmo=.cmx)
 # installed copy of libguestfs.
 OCAMLPACKAGES = \
 	-package str,unix \
+	-I $(top_builddir)/common/cleanups/.libs \
 	-I $(top_builddir)/common/utils/.libs \
 	-I $(top_builddir)/lib/.libs \
 	-I $(top_builddir)/gnulib/lib/.libs \
@@ -123,6 +125,7 @@ endif
 OCAMLCLIBS = \
 	-lvisit \
 	-lutils \
+	-lcleanups \
 	$(LIBTINFO_LIBS) \
 	$(LIBCRYPT_LIBS) \
 	$(LIBXML2_LIBS) \
diff --git a/test-tool/Makefile.am b/test-tool/Makefile.am
index c4a1b1805..8747c561e 100644
--- a/test-tool/Makefile.am
+++ b/test-tool/Makefile.am
@@ -25,6 +25,7 @@ man_MANS = libguestfs-test-tool.1
 libguestfs_test_tool_SOURCES = test-tool.c

 libguestfs_test_tool_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
@@ -37,6 +38,7 @@ libguestfs_test_tool_CFLAGS = \

 libguestfs_test_tool_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LTLIBINTL) \
diff --git a/tests/c-api/Makefile.am b/tests/c-api/Makefile.am
index cb653f7a6..cc68e5e58 100644
--- a/tests/c-api/Makefile.am
+++ b/tests/c-api/Makefile.am
@@ -92,6 +92,7 @@ tests_SOURCES = \
 tests_CPPFLAGS = \
 	-DGUESTFS_PRIVATE=1 \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 tests_CFLAGS = \
@@ -100,6 +101,7 @@ tests_CFLAGS = \
 tests_LDADD = \
 	$(PCRE_LIBS) \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
@@ -137,12 +139,14 @@ endif

 test_create_handle_SOURCES = test-create-handle.c
 test_create_handle_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_create_handle_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_create_handle_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la

 if HAVE_LIBDL
@@ -158,60 +162,71 @@ endif

 test_config_SOURCES = test-config.c
 test_config_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_config_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_config_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la

 test_add_drive_opts_SOURCES = test-add-drive-opts.c
 test_add_drive_opts_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_add_drive_opts_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_add_drive_opts_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la

 test_last_errno_SOURCES = test-last-errno.c
 test_last_errno_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_last_errno_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_last_errno_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(top_builddir)/gnulib/lib/libgnu.la

 test_backend_settings_SOURCES = test-backend-settings.c
 test_backend_settings_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_backend_settings_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_backend_settings_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(LTLIBINTL) \
 	$(top_builddir)/lib/libguestfs.la

 test_private_data_SOURCES = test-private-data.c
 test_private_data_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_private_data_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_private_data_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la

 test_user_cancel_SOURCES = test-user-cancel.c
 test_user_cancel_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_user_cancel_CFLAGS = \
@@ -219,11 +234,13 @@ test_user_cancel_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_user_cancel_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la -lm \
 	$(top_builddir)/gnulib/lib/libgnu.la

 test_debug_to_file_SOURCES = test-debug-to-file.c
 test_debug_to_file_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/gnulib/lib \
@@ -232,11 +249,13 @@ test_debug_to_file_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_debug_to_file_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(top_builddir)/gnulib/lib/libgnu.la

 test_environment_SOURCES = test-environment.c
 test_environment_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/gnulib/lib \
@@ -245,12 +264,14 @@ test_environment_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_environment_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LTLIBINTL) \
 	$(top_builddir)/gnulib/lib/libgnu.la

 test_event_string_SOURCES = test-event-string.c
 test_event_string_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/gnulib/lib \
@@ -259,6 +280,7 @@ test_event_string_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_event_string_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LTLIBINTL) \
 	$(top_builddir)/gnulib/lib/libgnu.la
@@ -266,6 +288,7 @@ test_event_string_LDADD = \
 if HAVE_LIBVIRT
 test_add_libvirt_dom_SOURCES = test-add-libvirt-dom.c
 test_add_libvirt_dom_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/gnulib/lib \
@@ -275,6 +298,7 @@ test_add_libvirt_dom_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_add_libvirt_dom_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la $(LIBVIRT_LIBS) \
 	$(LTLIBINTL) \
 	$(LTLIBTHREAD) $(top_builddir)/gnulib/lib/libgnu.la
diff --git a/tests/charsets/Makefile.am b/tests/charsets/Makefile.am
index 7621dc252..883127c46 100644
--- a/tests/charsets/Makefile.am
+++ b/tests/charsets/Makefile.am
@@ -27,12 +27,14 @@ check_PROGRAMS = $(TESTS)
 test_charset_fidelity_SOURCES = test-charset-fidelity.c
 test_charset_fidelity_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_charset_fidelity_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_charset_fidelity_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/tests/disks/Makefile.am b/tests/disks/Makefile.am
index 779871aff..9f2d913d5 100644
--- a/tests/disks/Makefile.am
+++ b/tests/disks/Makefile.am
@@ -49,6 +49,7 @@ check_PROGRAMS = test-add-disks
 test_add_disks_SOURCES = \
 	test-add-disks.c
 test_add_disks_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib
@@ -56,6 +57,7 @@ test_add_disks_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_add_disks_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(top_builddir)/gnulib/lib/libgnu.la \
 	$(LIBXML2_LIBS)
diff --git a/tests/events/Makefile.am b/tests/events/Makefile.am
index 944011c9f..00238e863 100644
--- a/tests/events/Makefile.am
+++ b/tests/events/Makefile.am
@@ -34,6 +34,7 @@ check_PROGRAMS += test-libvirt-auth-callbacks
 test_libvirt_auth_callbacks_SOURCES = test-libvirt-auth-callbacks.c
 test_libvirt_auth_callbacks_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_libvirt_auth_callbacks_CFLAGS = \
@@ -41,6 +42,7 @@ test_libvirt_auth_callbacks_CFLAGS = \
 	$(LIBVIRT_CFLAGS)
 test_libvirt_auth_callbacks_LDADD = \
         $(top_builddir)/common/utils/libutils.la \
+        $(top_builddir)/common/cleanups/libcleanups.la \
         $(top_builddir)/lib/libguestfs.la \
         $(LIBVIRT_LIBS) \
         $(LIBXML2_LIBS) \
diff --git a/tests/mount-local/Makefile.am b/tests/mount-local/Makefile.am
index fc4862457..777c546b0 100644
--- a/tests/mount-local/Makefile.am
+++ b/tests/mount-local/Makefile.am
@@ -31,6 +31,7 @@ test_parallel_mount_local_SOURCES = \
 test_parallel_mount_local_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/parallel -I$(top_builddir)/common/parallel \
@@ -43,6 +44,7 @@ test_parallel_mount_local_LDADD = \
 	$(FUSE_LIBS) \
 	$(top_builddir)/common/parallel/libparallel.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/tests/parallel/Makefile.am b/tests/parallel/Makefile.am
index 7f6144089..5bcadfbe4 100644
--- a/tests/parallel/Makefile.am
+++ b/tests/parallel/Makefile.am
@@ -28,6 +28,7 @@ test_parallel_SOURCES = test-parallel.c
 test_parallel_CPPFLAGS = \
 	-DGUESTFS_WARN_DEPRECATED=1 \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_parallel_CFLAGS = \
@@ -35,6 +36,7 @@ test_parallel_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_parallel_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LTLIBINTL) \
 	$(top_builddir)/gnulib/lib/libgnu.la
diff --git a/tests/regressions/Makefile.am b/tests/regressions/Makefile.am
index aef6982d1..1721d861a 100644
--- a/tests/regressions/Makefile.am
+++ b/tests/regressions/Makefile.am
@@ -104,17 +104,20 @@ check_PROGRAMS = \

 rhbz501893_SOURCES = rhbz501893.c
 rhbz501893_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 rhbz501893_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 rhbz501893_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la

 rhbz790721_SOURCES = rhbz790721.c
 rhbz790721_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 rhbz790721_CFLAGS = \
@@ -122,12 +125,14 @@ rhbz790721_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 rhbz790721_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(top_builddir)/gnulib/lib/libgnu.la

 rhbz914931_SOURCES = rhbz914931.c
 rhbz914931_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-DGUESTFS_PRIVATE=1
@@ -136,12 +141,14 @@ rhbz914931_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 rhbz914931_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(LTLIBINTL) \
 	$(top_builddir)/lib/libguestfs.la \
 	$(top_builddir)/gnulib/lib/libgnu.la

 rhbz1055452_SOURCES = rhbz1055452.c
 rhbz1055452_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 rhbz1055452_CFLAGS = \
@@ -149,16 +156,19 @@ rhbz1055452_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 rhbz1055452_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la

 test_big_heap_SOURCES = test-big-heap.c
 test_big_heap_CPPFLAGS = \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 test_big_heap_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 test_big_heap_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la

 SLOW_TESTS = \
diff --git a/utils/boot-analysis/Makefile.am b/utils/boot-analysis/Makefile.am
index 4d9149e7a..f5cafa2db 100644
--- a/utils/boot-analysis/Makefile.am
+++ b/utils/boot-analysis/Makefile.am
@@ -29,6 +29,7 @@ boot_analysis_SOURCES = \
 	boot-analysis-utils.h
 boot_analysis_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib
 boot_analysis_CFLAGS = \
@@ -37,6 +38,7 @@ boot_analysis_CFLAGS = \
 	$(PCRE_CFLAGS)
 boot_analysis_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(PCRE_LIBS) \
 	$(LIBXML2_LIBS) \
diff --git a/utils/boot-benchmark/Makefile.am b/utils/boot-benchmark/Makefile.am
index 2e6ca465c..d741a0dba 100644
--- a/utils/boot-benchmark/Makefile.am
+++ b/utils/boot-benchmark/Makefile.am
@@ -31,6 +31,7 @@ boot_benchmark_SOURCES = \
 	../boot-analysis/boot-analysis-utils.h
 boot_benchmark_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/utils/boot-analysis
@@ -38,6 +39,7 @@ boot_benchmark_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 boot_benchmark_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LTLIBINTL) \
diff --git a/utils/qemu-boot/Makefile.am b/utils/qemu-boot/Makefile.am
index 3936a0744..5bc5fe72b 100644
--- a/utils/qemu-boot/Makefile.am
+++ b/utils/qemu-boot/Makefile.am
@@ -23,6 +23,7 @@ qemu_boot_SOURCES = \
 	qemu-boot.c
 qemu_boot_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/common/parallel -I$(top_builddir)/common/parallel \
@@ -33,6 +34,7 @@ qemu_boot_CFLAGS = \
 qemu_boot_LDADD = \
 	$(top_builddir)/common/parallel/libparallel.la \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/utils/qemu-speed-test/Makefile.am
b/utils/qemu-speed-test/Makefile.am
index d7bf59a29..16dc9280b 100644
--- a/utils/qemu-speed-test/Makefile.am
+++ b/utils/qemu-speed-test/Makefile.am
@@ -23,6 +23,7 @@ qemu_speed_test_SOURCES = \
 	qemu-speed-test.c
 qemu_speed_test_CPPFLAGS = \
 	-I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \
+	-I$(top_srcdir)/common/cleanups -I$(top_builddir)/common/cleanups \
 	-I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \
 	-I$(top_srcdir)/lib -I$(top_builddir)/lib \
 	-I$(top_srcdir)/df
@@ -30,6 +31,7 @@ qemu_speed_test_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS)
 qemu_speed_test_LDADD = \
 	$(top_builddir)/common/utils/libutils.la \
+	$(top_builddir)/common/cleanups/libcleanups.la \
 	$(top_builddir)/lib/libguestfs.la \
 	$(LIBXML2_LIBS) \
 	$(LIBVIRT_LIBS) \
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index 8a831a700..41ff9af0b 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -124,6 +124,7 @@ virt_v2v_CPPFLAGS = \
 	-I$(top_builddir) \
 	-I$(shell $(OCAMLC) -where) \
 	-I$(top_srcdir)/common/qemuopts \
+	-I$(top_srcdir)/common/cleanups \
 	-I$(top_srcdir)/common/utils \
 	-I$(top_srcdir)/lib
 virt_v2v_CFLAGS = \
@@ -141,6 +142,7 @@ XOBJECTS = $(BOBJECTS:.cmo=.cmx)
 # installed copy of libguestfs.
 OCAMLPACKAGES = \
 	-package str,unix \
+	-I $(top_builddir)/common/cleanups/.libs \
 	-I $(top_builddir)/common/utils/.libs \
 	-I $(top_builddir)/common/qemuopts/.libs \
 	-I $(top_builddir)/lib/.libs \
@@ -156,6 +158,7 @@ endif

 OCAMLCLIBS = \
 	-lutils \
+	-lcleanups \
 	-lqemuopts \
 	$(LIBVIRT_LIBS) \
 	$(LIBXML2_LIBS) \
@@ -190,6 +193,7 @@ virt_v2v_copy_to_local_CPPFLAGS = \
 	-I. \
 	-I$(top_builddir) \
 	-I$(shell $(OCAMLC) -where) \
+	-I$(top_srcdir)/common/cleanups \
 	-I$(top_srcdir)/common/utils \
 	-I$(top_srcdir)/lib
 virt_v2v_copy_to_local_CFLAGS = \
--
2.13.0