diff options
author | Richard Jones <rjones@redhat.com> | 2009-04-08 22:52:11 +0100 |
---|---|---|
committer | Richard Jones <rjones@redhat.com> | 2009-04-08 22:52:11 +0100 |
commit | 13339826ea01f8dbd581b5d2544e7692171cf386 (patch) | |
tree | d231c776846060f93293d6ee1352d912a2f5d237 /ocaml/guestfs_c.c | |
parent | 94050e0344685b6916e21581e618ad3e85795008 (diff) | |
download | libguestfs-13339826ea01f8dbd581b5d2544e7692171cf386.tar.gz libguestfs-13339826ea01f8dbd581b5d2544e7692171cf386.tar.xz libguestfs-13339826ea01f8dbd581b5d2544e7692171cf386.zip |
OCaml bindings compile.
Diffstat (limited to 'ocaml/guestfs_c.c')
-rw-r--r-- | ocaml/guestfs_c.c | 90 |
1 files changed, 85 insertions, 5 deletions
diff --git a/ocaml/guestfs_c.c b/ocaml/guestfs_c.c index dda338fa..600440c9 100644 --- a/ocaml/guestfs_c.c +++ b/ocaml/guestfs_c.c @@ -18,24 +18,104 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <guestfs.h> #include <caml/config.h> #include <caml/alloc.h> #include <caml/callback.h> +#include <caml/custom.h> #include <caml/fail.h> #include <caml/memory.h> #include <caml/mlvalues.h> #include "guestfs_c.h" +/* Allocate handles and deal with finalization. */ +static void +guestfs_finalize (value gv) +{ + guestfs_h *g = Guestfs_val (gv); + if (g) guestfs_close (g); +} + +static struct custom_operations guestfs_custom_operations = { + "guestfs_custom_operations", + guestfs_finalize, + custom_compare_default, + custom_hash_default, + custom_serialize_default, + custom_deserialize_default +}; + +static value +Val_guestfs (guestfs_h *g) +{ + CAMLparam0 (); + CAMLlocal1 (rv); + + rv = caml_alloc_custom (&guestfs_custom_operations, + sizeof (guestfs_h *), 0, 1); + Guestfs_val (rv) = g; + + CAMLreturn (rv); +} + +/* Handle errors. */ +/* XXX Like the current Perl bindings, this is unsafe in a multi- + * threaded environment. + */ +static char *last_error = NULL; + +static void +error_handler (guestfs_h *g, + void *data, + const char *msg) +{ + if (last_error != NULL) free (last_error); + last_error = strdup (msg); +} + +void +ocaml_guestfs_raise_error (guestfs_h *g, const char *func) +{ + CAMLparam0 (); + CAMLlocal1 (v); + + v = caml_copy_string (last_error); + caml_raise_with_arg (*caml_named_value ("ocaml_guestfs_error"), v); + CAMLnoreturn; +} + +/* Guestfs.create */ CAMLprim value -ocaml_guestfs_create (value hv /* XXX */) +ocaml_guestfs_create (void) { - CAMLparam1 (hv); /* XXX */ -/* XXX write something here */ - CAMLreturn (Val_unit); /* XXX */ + CAMLparam0 (); + CAMLlocal1 (gv); + guestfs_h *g; + + g = guestfs_create (); + if (g == NULL) + caml_failwith ("failed to create guestfs handle"); + + guestfs_set_error_handler (g, error_handler, NULL); + + gv = Val_guestfs (g); + CAMLreturn (gv); } -/* etc */ +/* Guestfs.close */ +CAMLprim value +ocaml_guestfs_close (value gv) +{ + CAMLparam1 (gv); + + guestfs_finalize (gv); + + /* So we don't double-free in the finalizer. */ + Guestfs_val (gv) = NULL; + + CAMLreturn (Val_unit); +} |