[Libguestfs] [PATCH 2/2] [EXAMPLE ONLY] Add extra field(s) to guestfs_application struct.

Richard W.M. Jones rjones at redhat.com
Mon Oct 22 09:45:07 UTC 2012


From: "Richard W.M. Jones" <rjones at redhat.com>

This breaks the ABI, but by using symbol versioning existing callers
will not be affected.  Also this change is source compatible, so
existing code does not need to be modified.
---
 generator/actions.ml |  1 +
 generator/structs.ml |  5 ++++
 src/compat.c         | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/inspect-apps.c   |  5 ++++
 4 files changed, 80 insertions(+)

diff --git a/generator/actions.ml b/generator/actions.ml
index e1db3db..3b0806a 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -1522,6 +1522,7 @@ Please read L<guestfs(3)/INSPECTION> for more details." };
   { defaults with
     name = "inspect_list_applications";
     style = RStructList ("applications", "application"), [Device "root"], [];
+    symbol_version = Some "GUESTFS_1.20";
     shortdesc = "get list of applications installed in the operating system";
     longdesc = "\
 Return the list of applications installed in the operating system.
diff --git a/generator/structs.ml b/generator/structs.ml
index d62fcc5..c6158af 100644
--- a/generator/structs.ml
+++ b/generator/structs.ml
@@ -183,6 +183,7 @@ let structs = [
     "app_epoch", FInt32;
     "app_version", FString;
     "app_release", FString;
+    "app_arch", FString;
     "app_install_path", FString;
     "app_trans_path", FString;
     "app_publisher", FString;
@@ -190,6 +191,10 @@ let structs = [
     "app_source_package", FString;
     "app_summary", FString;
     "app_description", FString;
+    "app_spare1", FString;
+    "app_spare2", FString;
+    "app_spare3", FString;
+    "app_spare4", FString;
   ];
 
   (* ISO primary volume descriptor. *)
diff --git a/src/compat.c b/src/compat.c
index 119eb7c..c9cde2b 100644
--- a/src/compat.c
+++ b/src/compat.c
@@ -23,3 +23,72 @@
  * #included directly into src/actions.c, instead of being compiled as
  * a separate unit.
  */
+
+/* guestfs_inspect_list_applications did not return the C<app_arch>
+ * field in libguestfs < 1.20.  We cannot add fields to structs
+ * without breaking compatibility.
+ */
+struct compat118_guestfs_application {
+  char *app_name;
+  char *app_display_name;
+  int32_t app_epoch;
+  char *app_version;
+  char *app_release;
+  char *app_install_path;
+  char *app_trans_path;
+  char *app_publisher;
+  char *app_url;
+  char *app_source_package;
+  char *app_summary;
+  char *app_description;
+};
+
+struct compat118_guestfs_application_list {
+  uint32_t len;
+  struct compat118_guestfs_application *val;
+};
+
+/* Declare a prototype to make GCC happy. */
+struct compat118_guestfs_application_list *compat118_guestfs_inspect_list_applications (guestfs_h *g, const char *root);
+
+struct compat118_guestfs_application_list *
+compat118_guestfs_inspect_list_applications (guestfs_h *g, const char *root)
+{
+  struct compat118_guestfs_application_list *ret;
+  struct guestfs_application_list *r;
+  size_t i;
+
+  debug (g, "%s: compatibility wrapper invoked", __func__);
+
+  /* Call the new function. */
+  r = guestfs_inspect_list_applications (g, root);
+  if (!r)
+    return NULL;
+
+  /* Translate the structures from the new format to the old format. */
+  ret = safe_malloc (g, sizeof (struct compat118_guestfs_application_list));
+  ret->len = r->len;
+  ret->val =
+    safe_malloc (g, sizeof (struct compat118_guestfs_application) * r->len);
+  for (i = 0; i < r->len; ++i) {
+    ret->val[i].app_name = r->val[i].app_name;
+    ret->val[i].app_display_name = r->val[i].app_display_name;
+    ret->val[i].app_epoch = r->val[i].app_epoch;
+    ret->val[i].app_version = r->val[i].app_version;
+    ret->val[i].app_release = r->val[i].app_release;
+    ret->val[i].app_install_path = r->val[i].app_install_path;
+    ret->val[i].app_trans_path = r->val[i].app_trans_path;
+    ret->val[i].app_publisher = r->val[i].app_publisher;
+    ret->val[i].app_url = r->val[i].app_url;
+    ret->val[i].app_source_package = r->val[i].app_source_package;
+    ret->val[i].app_summary = r->val[i].app_summary;
+    ret->val[i].app_description = r->val[i].app_description;
+  }
+  free (r->val);                /* Must not free the strings. */
+  free (r);
+
+  return ret;
+}
+
+__asm__(".symver compat118_guestfs_inspect_list_applications,guestfs_inspect_list_applications@");
+__asm__(".symver latest_guestfs_inspect_list_applications,guestfs_inspect_list_applications@@GUESTFS_1.20");
diff --git a/src/inspect-apps.c b/src/inspect-apps.c
index f65c70a..54c10f4 100644
--- a/src/inspect-apps.c
+++ b/src/inspect-apps.c
@@ -555,6 +555,7 @@ add_application (guestfs_h *g, struct guestfs_application_list *apps,
   apps->val[apps->len-1].app_epoch = epoch;
   apps->val[apps->len-1].app_version = safe_strdup (g, version);
   apps->val[apps->len-1].app_release = safe_strdup (g, release);
+  apps->val[apps->len-1].app_arch = safe_strdup (g, "");
   apps->val[apps->len-1].app_install_path = safe_strdup (g, install_path);
   /* XXX Translated path is not implemented yet. */
   apps->val[apps->len-1].app_trans_path = safe_strdup (g, "");
@@ -566,6 +567,10 @@ add_application (guestfs_h *g, struct guestfs_application_list *apps,
   apps->val[apps->len-1].app_source_package = safe_strdup (g, "");
   apps->val[apps->len-1].app_summary = safe_strdup (g, "");
   apps->val[apps->len-1].app_description = safe_strdup (g, description);
+  apps->val[apps->len-1].app_spare1 = safe_strdup (g, "");
+  apps->val[apps->len-1].app_spare2 = safe_strdup (g, "");
+  apps->val[apps->len-1].app_spare3 = safe_strdup (g, "");
+  apps->val[apps->len-1].app_spare4 = safe_strdup (g, "");
 }
 
 /* Sort applications by name before returning the list. */
-- 
1.7.11.4




More information about the Libguestfs mailing list