X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;ds=sidebyside;f=ocaml%2Fguestfs_c.c;h=600440c92966ef54c2999eb2c4bf652644e3a226;hb=13339826ea01f8dbd581b5d2544e7692171cf386;hp=dda338fade56b284f2bbe916b098a0d7230e94f5;hpb=4144e2106cc70ad8f1e081b57da09f9c1e276812;p=libguestfs.git diff --git a/ocaml/guestfs_c.c b/ocaml/guestfs_c.c index dda338f..600440c 100644 --- a/ocaml/guestfs_c.c +++ b/ocaml/guestfs_c.c @@ -18,24 +18,104 @@ #include #include +#include #include #include #include #include +#include #include #include #include #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); +}