[Libguestfs] [PATCH 1/2] daemon: generate cleanup handlers for structs

Pino Toscano ptoscano at redhat.com
Fri Mar 10 13:01:16 UTC 2017


This way it is possible to cleanup properly structs in the daemon, when
using them within other daemon functions.
---
 .gitignore           |   2 +
 daemon/Makefile.am   |   4 ++
 daemon/daemon.h      |   1 +
 generator/daemon.ml  | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
 generator/daemon.mli |   2 +
 generator/main.ml    |   4 ++
 6 files changed, 114 insertions(+)

diff --git a/.gitignore b/.gitignore
index 7dd49e2..c82745e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -163,6 +163,8 @@ Makefile.in
 /daemon/optgroups.h
 /daemon/lvm-tokenization.c
 /daemon/stamp-guestfsd.pod
+/daemon/structs-cleanups.c
+/daemon/structs-cleanups.h
 /daemon/stubs-?.c
 /daemon/stubs.h
 /depcomp
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index e3ad053..8632c37 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -22,6 +22,8 @@ generator_built = \
 	dispatch.c \
 	names.c \
 	lvm-tokenization.c \
+	structs-cleanups.c \
+	structs-cleanups.h \
 	stubs-0.c \
 	stubs-1.c \
 	stubs-2.c \
@@ -142,6 +144,8 @@ guestfsd_SOURCES = \
 	stat.c \
 	statvfs.c \
 	strings.c \
+	structs-cleanups.c \
+	structs-cleanups.h \
 	stubs-0.c \
 	stubs-1.c \
 	stubs-2.c \
diff --git a/daemon/daemon.h b/daemon/daemon.h
index 793074d..abec087 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -33,6 +33,7 @@
 #include "guestfs-internal-all.h"
 
 #include "cleanups.h"
+#include "structs-cleanups.h"
 #include "command.h"
 
 /* Mountables */
diff --git a/generator/daemon.ml b/generator/daemon.ml
index 3941d97..9453d12 100644
--- a/generator/daemon.ml
+++ b/generator/daemon.ml
@@ -840,3 +840,104 @@ let generate_daemon_optgroups_h () =
   ) optgroups;
 
   pr "#endif /* GUESTFSD_OPTGROUPS_H */\n"
+
+(* Generate structs-cleanups.c file. *)
+and generate_daemon_structs_cleanups_c () =
+  generate_header CStyle GPLv2plus;
+
+  pr "\
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include \"daemon.h\"
+#include \"guestfs_protocol.h\"
+
+";
+
+  pr "/* Cleanup functions used by CLEANUP_* macros.  Do not call\n";
+  pr " * these functions directly.\n";
+  pr " */\n";
+  pr "\n";
+
+  List.iter (
+    fun { s_name = typ; s_cols = cols } ->
+      pr "void\n";
+      pr "cleanup_free_int_%s (void *ptr)\n" typ;
+      pr "{\n";
+      pr "  struct guestfs_int_%s *x = (* (struct guestfs_int_%s **) ptr);\n" typ typ;
+      pr "\n";
+      pr "  if (x) {\n";
+      pr "    xdr_free ((xdrproc_t) xdr_guestfs_int_%s, (char *) x);\n" typ;
+      pr "    free (x);\n";
+      pr "  }\n";
+      pr "}\n";
+      pr "\n";
+
+      pr "void\n";
+      pr "cleanup_free_int_%s_list (void *ptr)\n" typ;
+      pr "{\n";
+      pr "  struct guestfs_int_%s_list *x = (* (struct guestfs_int_%s_list **) ptr);\n"
+        typ typ;
+      pr "\n";
+      pr "  if (x) {\n";
+      pr "    xdr_free ((xdrproc_t) xdr_guestfs_int_%s_list, (char *) x);\n"
+        typ;
+      pr "    free (x);\n";
+      pr "  }\n";
+      pr "}\n";
+      pr "\n";
+
+  ) structs
+
+(* Generate structs-cleanups.h file. *)
+and generate_daemon_structs_cleanups_h () =
+  generate_header CStyle GPLv2plus;
+
+  pr "\
+/* These CLEANUP_* macros automatically free the struct or struct list
+ * pointed to by the local variable at the end of the current scope.
+ */
+
+#ifndef GUESTFS_DAEMON_STRUCTS_CLEANUPS_H_
+#define GUESTFS_DAEMON_STRUCTS_CLEANUPS_H_
+
+#ifdef HAVE_ATTRIBUTE_CLEANUP
+";
+
+  List.iter (
+    fun { s_name = name } ->
+      pr "#define CLEANUP_FREE_%s \\\n" (String.uppercase_ascii name);
+      pr "  __attribute__((cleanup(cleanup_free_int_%s)))\n" name;
+      pr "#define CLEANUP_FREE_%s_LIST \\\n" (String.uppercase_ascii name);
+      pr "  __attribute__((cleanup(cleanup_free_int_%s_list)))\n" name
+  ) structs;
+
+  pr "#else /* !HAVE_ATTRIBUTE_CLEANUP */\n";
+
+  List.iter (
+    fun { s_name = name } ->
+      pr "#define CLEANUP_FREE_%s\n" (String.uppercase_ascii name);
+      pr "#define CLEANUP_FREE_%s_LIST\n" (String.uppercase_ascii name)
+  ) structs;
+
+  pr "\
+#endif /* !HAVE_ATTRIBUTE_CLEANUP */
+
+/* These functions are used internally by the CLEANUP_* macros.
+ * Don't call them directly.
+ */
+
+";
+
+  List.iter (
+    fun { s_name = name } ->
+      pr "extern void cleanup_free_int_%s (void *ptr);\n"
+        name;
+      pr "extern void cleanup_free_int_%s_list (void *ptr);\n"
+        name
+  ) structs;
+
+  pr "\n";
+  pr "#endif /* GUESTFS_INTERNAL_FRONTEND_CLEANUPS_H_ */\n"
diff --git a/generator/daemon.mli b/generator/daemon.mli
index b7966c9..ff008bf 100644
--- a/generator/daemon.mli
+++ b/generator/daemon.mli
@@ -24,3 +24,5 @@ val generate_daemon_lvm_tokenization : unit -> unit
 val generate_daemon_names : unit -> unit
 val generate_daemon_optgroups_c : unit -> unit
 val generate_daemon_optgroups_h : unit -> unit
+val generate_daemon_structs_cleanups_c : unit -> unit
+val generate_daemon_structs_cleanups_h : unit -> unit
diff --git a/generator/main.ml b/generator/main.ml
index febede5..fe5da5a 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -137,6 +137,10 @@ Run it from the top source directory using the command
             Daemon.generate_daemon_optgroups_h;
   output_to "daemon/lvm-tokenization.c"
             Daemon.generate_daemon_lvm_tokenization;
+  output_to "daemon/structs-cleanups.c"
+            Daemon.generate_daemon_structs_cleanups_c;
+  output_to "daemon/structs-cleanups.h"
+            Daemon.generate_daemon_structs_cleanups_h;
 
   output_to "fish/cmds-gperf.gperf"
             Fish.generate_fish_cmds_gperf;
-- 
2.9.3




More information about the Libguestfs mailing list