[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libguestfs] [PATCH v7 3/9] mllib: ocaml wrapper for lib/osinfo



Provide osinfo database parsing API in OCaml.
---
 lib/osinfo.c      |  39 +++++++++++++++++++++
 mllib/Makefile.am |  11 ++++--
 mllib/osinfo-c.c  | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 mllib/osinfo.ml   |  26 ++++++++++++++
 mllib/osinfo.mli  |  31 ++++++++++++++++
 5 files changed, 208 insertions(+), 2 deletions(-)
 create mode 100644 mllib/osinfo-c.c
 create mode 100644 mllib/osinfo.ml
 create mode 100644 mllib/osinfo.mli

diff --git a/lib/osinfo.c b/lib/osinfo.c
index 5ccb554be..9a411b28d 100644
--- a/lib/osinfo.c
+++ b/lib/osinfo.c
@@ -52,6 +52,45 @@
 
 #include "osinfo.h"
 
+#ifndef GUESTFS_PRIVATE
+#undef perrorf
+static void perrorf(guestfs_h *g, const char *fmt, ...)
+__attribute__((format (printf,2,3)));
+
+static void perrorf(guestfs_h *g, const char *fmt, ...)
+{
+  va_list args;
+  CLEANUP_FREE char *msg = NULL;
+  CLEANUP_FREE char *fs = NULL;
+
+  ignore_value (asprintf (&fs, "%s\n", fmt));
+
+  va_start (args, fmt);
+  /* Ignoring the result is fine since perror
+   * can take NULL input */
+  ignore_value (vasprintf (&msg, fs, args));
+  va_end (args);
+  perror (msg);
+}
+
+#undef debug
+static void debug(guestfs_h *g, const char *fmt, ...)
+__attribute__((format (printf,2,3)));
+
+static void
+debug(guestfs_h *g, const char *fmt, ...)
+{
+  va_list args;
+  CLEANUP_FREE char *fs = NULL;
+
+  ignore_value (asprintf (&fs, "%s\n", fmt));
+
+  va_start (args, fmt);
+  vfprintf (stderr, fs, args);
+  va_end (args);
+}
+#endif /* GUESTFS_PRIVATE */
+
 
 /* Read the libosinfo XML database files.  The lock is held while
  * this is called.
diff --git a/mllib/Makefile.am b/mllib/Makefile.am
index ee2f1a7a8..ee16fe7ef 100644
--- a/mllib/Makefile.am
+++ b/mllib/Makefile.am
@@ -36,6 +36,7 @@ SOURCES_MLI = \
 	curl.mli \
 	getopt.mli \
 	JSON.mli \
+	osinfo.mli \
 	planner.mli \
 	progress.mli \
 	regedit.mli \
@@ -63,7 +64,8 @@ SOURCES_ML = \
 	curl.ml \
 	checksums.ml \
 	xml.ml \
-	xpath_helpers.ml
+	xpath_helpers.ml \
+	osinfo.ml
 
 SOURCES_C = \
 	../common/visit/visit.c \
@@ -71,8 +73,12 @@ SOURCES_C = \
 	../common/options/keys.c \
 	../common/options/uri.c \
 	../common/progress/progress.c \
+	../lib/alloc.c \
+	../lib/osinfo.c \
+	../lib/osinfo.h \
 	common_utils-c.c \
 	getopt-c.c \
+	osinfo-c.c \
 	progress-c.c \
 	unix_utils-c.c \
 	uri-c.c \
@@ -106,7 +112,8 @@ libmllib_a_CPPFLAGS = \
 	-I$(top_srcdir)/lib \
 	-I$(top_srcdir)/common/visit \
 	-I$(top_srcdir)/common/options \
-	-I$(top_srcdir)/common/progress
+	-I$(top_srcdir)/common/progress \
+	-DLIBOSINFO_DB_PATH='"$(datadir)/libosinfo/db"'
 libmllib_a_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS) \
 	$(LIBVIRT_CFLAGS) $(LIBXML2_CFLAGS) \
diff --git a/mllib/osinfo-c.c b/mllib/osinfo-c.c
new file mode 100644
index 000000000..84760a85f
--- /dev/null
+++ b/mllib/osinfo-c.c
@@ -0,0 +1,103 @@
+/* Bindings for osinfo db reading function.
+ * Copyright (C) 2016 Red Hat Inc.
+ * Copyright (C) 2017 SUSE 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 <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <caml/alloc.h>
+#include <caml/callback.h>
+#include <caml/fail.h>
+#include <caml/memory.h>
+#include <caml/mlvalues.h>
+
+#include "guestfs.h"
+#include "guestfs-internal.h"
+#include "osinfo.h"
+
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+
+struct callback_wrapper_args {
+  /* In both case we are pointing to local roots, hence why these are
+   * value* not value.
+   */
+  value *exnp;                  /* Safe place to store any exception
+                                   raised by callback */
+  value *fvp;                   /* callback. */
+};
+
+static int read_osinfo_db_callback_wrapper (guestfs_h *g, const char *path, void *opaque);
+
+value
+guestfs_int_mllib_read_osinfo_db (value gv, value fv)
+{
+  CAMLparam2 (gv, fv);
+  guestfs_h *g = (guestfs_h *) Int64_val (gv);
+  struct callback_wrapper_args args;
+
+  /* This stack address is used to point to the exception, if one is
+   * raised in the visitor_function.  Note that the macro initializes
+   * this to Val_unit, which is how we know if an exception was set.
+   */
+  CAMLlocal1 (exn);
+
+  exn = Val_unit;
+
+  args.exnp = &exn;
+  args.fvp = &fv;
+
+  if (read_osinfo_db (g, read_osinfo_db_callback_wrapper, &args) == -1) {
+    if (exn != Val_unit) {
+      /* The failure was caused by the callback raising an
+       * exception.  Re-raise it here.
+       */
+      caml_raise (exn);
+    }
+
+    caml_failwith ("read_osinfo_db");
+}
+
+  CAMLreturn (Val_unit);
+}
+
+static int
+read_osinfo_db_callback_wrapper (guestfs_h *g, const char *path, void *opaque)
+{
+  CAMLparam0 ();
+  CAMLlocal2 (pathv, v);
+  struct callback_wrapper_args *args = opaque;
+
+  assert (path != NULL);
+  assert (args != NULL);
+
+  pathv = caml_copy_string (path);
+
+  v = caml_callback_exn (*args->fvp, pathv);
+
+  if (Is_exception_result (v)) {
+    *args->exnp = Extract_exception (v);
+    CAMLreturnT (int, -1);
+  }
+
+  /* No error, return normally. */
+  CAMLreturnT (int, 0);
+}
diff --git a/mllib/osinfo.ml b/mllib/osinfo.ml
new file mode 100644
index 000000000..f5afbd889
--- /dev/null
+++ b/mllib/osinfo.ml
@@ -0,0 +1,26 @@
+(* virt-builder
+ * Copyright (C) 2016 - SUSE 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.
+ *)
+open Common_utils
+
+type osinfo_db_callback = string -> unit
+
+external c_read_osinfo_db : int64 -> osinfo_db_callback -> unit =
+  "guestfs_int_mllib_read_osinfo_db"
+
+let read_osinfo_db g f =
+  c_read_osinfo_db (Guestfs.c_pointer g) f
diff --git a/mllib/osinfo.mli b/mllib/osinfo.mli
new file mode 100644
index 000000000..8a21eb215
--- /dev/null
+++ b/mllib/osinfo.mli
@@ -0,0 +1,31 @@
+(* virt-builder
+ * Copyright (C) 2016 - SUSE 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.
+ *)
+
+(** Bindings for the lib/osinfo.h os-info database reading API. *)
+
+type osinfo_db_callback = string -> unit
+(** The osinfo_db_callback is a callback called for each data file
+    in the os-info database. The argument of the function is
+    the absolute path of the data file.
+
+    The callback may raise an exception, which will cause the whole
+    database read to fail with an error (raising the same exception). *)
+
+val read_osinfo_db : Guestfs.t -> osinfo_db_callback -> unit
+(** [read_osinfo_db g callback] will find all the os-info database
+    files and call the callback on them. *)
-- 
2.12.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]