From: "Richard W.M. Jones" <rjones@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 | 11 ++++-- src/compat.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/inspect-apps.c | 5 +++ 4 files changed, 118 insertions(+), 3 deletions(-) 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 499f825..fd77654 100644 --- a/generator/structs.ml +++ b/generator/structs.ml @@ -213,14 +213,14 @@ let structs = [ s_camel_name = "Partition" }; (* Application. *) - { defaults with - s_name = "application"; + { s_name = "application"; s_cols = [ "app_name", FString; "app_display_name", FString; "app_epoch", FInt32; "app_version", FString; "app_release", FString; + "app_arch", FString; "app_install_path", FString; "app_trans_path", FString; "app_publisher", FString; @@ -228,8 +228,13 @@ let structs = [ "app_source_package", FString; "app_summary", FString; "app_description", FString; + "app_spare1", FString; + "app_spare2", FString; + "app_spare3", FString; + "app_spare4", FString; ]; - s_camel_name = "Application" }; + s_camel_name = "Application"; + s_symbol_version = Some "GUESTFS_1.20" }; (* ISO primary volume descriptor. *) { defaults with diff --git a/src/compat.c b/src/compat.c index 27ffd05..520400b 100644 --- a/src/compat.c +++ b/src/compat.c @@ -24,3 +24,107 @@ * instead of being compiled as a separate unit. The cpp symbols * COMPAT_ACTIONS or COMPAT_STRUCTS are defined as appropriate. */ + +#define DEBUG_COMPAT debug (g, "%s: compatibility wrapper invoked", __func__) + +/* 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 guestfs_application__v1 { + 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 guestfs_application_list__v1 { + uint32_t len; + struct guestfs_application__v1 *val; +}; + +#if COMPAT_ACTIONS + +/* Declare a prototype to make GCC happy. */ +GUESTFS_DLL_PUBLIC struct guestfs_application_list__v1 *guestfs_inspect_list_applications__v1 (guestfs_h *g, const char *root); + +GUESTFS_DLL_PUBLIC +struct guestfs_application_list__v1 * +guestfs_inspect_list_applications__v1 (guestfs_h *g, const char *root) +{ + struct guestfs_application_list__v1 *ret; + struct guestfs_application_list *r; + size_t i; + + DEBUG_COMPAT; + + /* 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 guestfs_application_list__v1)); + ret->len = r->len; + ret->val = + safe_malloc (g, sizeof (struct guestfs_application__v1) * 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 guestfs_inspect_list_applications__v1,guestfs_inspect_list_applications@"); +__asm__(".symver guestfs_inspect_list_applications__GUESTFS_1_20,guestfs_inspect_list_applications@@GUESTFS_1.20"); + +#endif /* COMPAT_ACTIONS */ + +#if COMPAT_STRUCTS + +GUESTFS_DLL_PUBLIC void guestfs_free_application__v1 (struct guestfs_application__v1 *x); + +GUESTFS_DLL_PUBLIC void +guestfs_free_application__v1 (struct guestfs_application__v1 *x) +{ + /* XXX */ + free (x); +} + +__asm__(".symver guestfs_free_application__v1,guestfs_free_application@"); +__asm__(".symver guestfs_free_application__GUESTFS_1_20,guestfs_free_application@@GUESTFS_1.20"); + +GUESTFS_DLL_PUBLIC void guestfs_free_application_list__v1 (struct guestfs_application_list__v1 *x); + +GUESTFS_DLL_PUBLIC void +guestfs_free_application_list__v1 (struct guestfs_application_list__v1 *x) +{ + /* XXX */ + free (x); +} + +__asm__(".symver guestfs_free_application_list__v1,guestfs_free_application_list@"); +__asm__(".symver guestfs_free_application_list__GUESTFS_1_20,guestfs_free_application_list@@GUESTFS_1.20"); + +#endif /* COMPAT_STRUCTS */ diff --git a/src/inspect-apps.c b/src/inspect-apps.c index 23e68e4..e5db4b3 100644 --- a/src/inspect-apps.c +++ b/src/inspect-apps.c @@ -580,6 +580,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, ""); @@ -591,6 +592,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