X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=ocaml%2Fguestfs_c.c;h=87139b487277ee1c25060eee16db8cea4dc49062;hp=dda338fade56b284f2bbe916b098a0d7230e94f5;hb=b03ee3675bed8d739ae722ed8c030ae02b3cb0ed;hpb=4144e2106cc70ad8f1e081b57da09f9c1e276812 diff --git a/ocaml/guestfs_c.c b/ocaml/guestfs_c.c index dda338f..87139b4 100644 --- a/ocaml/guestfs_c.c +++ b/ocaml/guestfs_c.c @@ -18,24 +18,121 @@ #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); +} + +void +ocaml_guestfs_raise_error (guestfs_h *g, const char *func) +{ + CAMLparam0 (); + CAMLlocal1 (v); + const char *msg; + + msg = guestfs_last_error (g); + + if (msg) + v = caml_copy_string (msg); + else + v = caml_copy_string (func); + 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, NULL, NULL); + + gv = Val_guestfs (g); + CAMLreturn (gv); +} + +/* 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); } -/* etc */ +/* Copy string array value. */ +char ** +ocaml_guestfs_strings_val (value sv) +{ + CAMLparam1 (sv); + char **r; + int i; + + r = malloc (sizeof (char *) * (Wosize_val (sv) + 1)); + for (i = 0; i < Wosize_val (sv); ++i) + r[i] = String_val (Field (sv, i)); + r[i] = NULL; + + CAMLreturnT (char **, r); +} + +/* Free array of strings. */ +void +ocaml_guestfs_free_strings (char **argv) +{ + /* Don't free the actual strings - they are String_vals on + * the OCaml heap. + */ + free (argv); +}