On Fri, Mar 22, 2019 at 04:33:42PM +0100, Pino Toscano wrote: > Allow to specify a file descriptor for the machine readable output. > > Sadly, the OCaml C glue for the channels is not public API, so enable > the internals for this... > --- > common/mltools/tools_utils-c.c | 17 +++++++++++++++++ > common/mltools/tools_utils.ml | 10 +++++++++- > lib/guestfs.pod | 5 +++++ > 3 files changed, 31 insertions(+), 1 deletion(-) > > diff --git a/common/mltools/tools_utils-c.c b/common/mltools/tools_utils-c.c > index c88c95082..553aa6631 100644 > --- a/common/mltools/tools_utils-c.c > +++ b/common/mltools/tools_utils-c.c > @@ -29,6 +29,9 @@ > #include <caml/memory.h> > #include <caml/mlvalues.h> > #include <caml/unixsupport.h> > +/* Evil ... */ > +#define CAML_INTERNALS > +#include <caml/io.h>
I think this is not necessary. On Unix-like platforms, Unix.file_descr is really just an int, so you can cast between the two using Val_int/Int_val (from C) or Obj.magic (from OCaml). Note we already rely on this in libguestfs, in v2v/qemuopts-c.c:guestfs_int_qemuopts_to_chan So I think this should work: | Fd of Unix.file_descr ... | Fd fd -> Some (Unix.out_channel_of_descr fd) ... | "fd" -> machine_readable_output := Fd (Obj.magic (int_of_string outname)) If you don't want to use Obj.magic, then something using /dev/fd/<N> is another possibility. Rich. > > #include <guestfs.h> > > @@ -37,6 +40,7 @@ > extern value guestfs_int_mllib_inspect_decrypt (value gv, value gpv, value > keysv); > extern value guestfs_int_mllib_set_echo_keys (value unitv); > extern value guestfs_int_mllib_set_keys_from_stdin (value unitv); > +extern value guestfs_int_mllib_open_out_channel_from_fd (value fdv); > > /* Interface with the guestfish inspection and decryption code. */ > int echo_keys = 0; > @@ -103,3 +107,16 @@ guestfs_int_mllib_set_keys_from_stdin (value unitv) > keys_from_stdin = 1; > return Val_unit; > } > + > +value > +guestfs_int_mllib_open_out_channel_from_fd (value fdv) > +{ > + CAMLparam1 (fdv); > + struct channel *chan; > + > + chan = caml_open_descriptor_out (Int_val (fdv)); > + if (!chan) > + caml_raise_out_of_memory (); > + > + CAMLreturn (caml_alloc_channel (chan)); > +} > diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml > index ade4cb37f..3c54cd4a0 100644 > --- a/common/mltools/tools_utils.ml > +++ b/common/mltools/tools_utils.ml > @@ -32,6 +32,7 @@ and key_store_key = > external c_inspect_decrypt : Guestfs.t -> int64 -> (string * key_store_key) > list -> unit = "guestfs_int_mllib_inspect_decrypt" > external c_set_echo_keys : unit -> unit = "guestfs_int_mllib_set_echo_keys" > "noalloc" > external c_set_keys_from_stdin : unit -> unit = > "guestfs_int_mllib_set_keys_from_stdin" "noalloc" > +external c_out_channel_from_fd : int -> out_channel = > "guestfs_int_mllib_open_out_channel_from_fd" > > type machine_readable_fn = { > pr : 'a. ('a, unit, string, unit) format4 -> 'a; > @@ -41,6 +42,7 @@ type machine_readable_output_type = > | NoOutput > | Channel of out_channel > | File of string > + | Fd of int > let machine_readable_output = ref NoOutput > let machine_readable_channel = ref None > let machine_readable () = > @@ -50,7 +52,8 @@ let machine_readable () = > match !machine_readable_output with > | NoOutput -> None > | Channel chan -> Some chan > - | File f -> Some (open_out f) in > + | File f -> Some (open_out f) > + | Fd fd -> Some (c_out_channel_from_fd fd) in > machine_readable_channel := chan > ); > !machine_readable_channel > @@ -296,6 +299,11 @@ let create_standard_options argspec ?anon_fun ?(key_opts > = false) ?(machine_read > | n -> > error (f_"invalid output stream for --machine-readable: %s") fmt > in > machine_readable_output := Channel chan > + | "fd" -> > + (try > + machine_readable_output := Fd (int_of_string outname) > + with Failure _ -> > + error (f_"invalid output fd for --machine-readable: %s") fmt) > | n -> > error (f_"invalid output for --machine-readable: %s") fmt > ) > diff --git a/lib/guestfs.pod b/lib/guestfs.pod > index 53cece2da..f11028466 100644 > --- a/lib/guestfs.pod > +++ b/lib/guestfs.pod > @@ -3287,6 +3287,11 @@ The possible values are: > > =over 4 > > +=item B<fd:>I<fd> > + > +The output goes to the specified I<fd>, which is a file descriptor > +already opened for writing. > + > =item B<file:>F<filename> > > The output goes to the specified F<filename>. > -- > 2.20.1 > > _______________________________________________ > Libguestfs mailing list > Libguestfs@redhat.com > https://www.redhat.com/mailman/listinfo/libguestfs -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/ _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs