Re: GVariant support for Unix fds (Was Re: GDBus/GVariant plans for next GLib release)



On Thu, 2009-10-15 at 14:02 -0400, Ryan Lortie wrote:
> On Thu, 2009-10-15 at 12:38 -0400, David Zeuthen wrote:
> > Yeah, I think we need to support this from the get-go. 
> > 
> > Anyway, at the end of the day, UNIX fds are just integers so if you
> > require that users (such as GDBus itself and apps using GDBus) keep the
> > fds alive until the method/signal has been sent/received you should be
> > able to treat them as such. Anyway, it's probably more complicated than
> > this.
> 
> I talked to Lennart on IRC and the 'h' type, as serialised, isn't a file
> descriptor so much as it is an index into a table of file descriptors
> that are stored separately (in a separate part of the DBusMessage).
> 
> Keeping this in mind, we could support this by doing the same thing with
> GDBus -- support 'file descriptor array offset' as a special type of
> integer in GVariant (much like 'o'bject path is a special type of
> string) and have a GDBus call for send_with_file_descriptors() or such.
> 
> Lennart mentioned that he thinks that it's a bad idea that the
> dbus_message_marshal stuff was ever added to libdbus, and that the
> fd-passing stuff in libdbus will break if you try to use those
> functions.  If we ever want to make a more efficient GVariant-to-DBus
> conversion process we'll have to turn it off for the case where fd's are
> present -- that's another reason for having a separate call, maybe.
> 
> I don't think we would want to have any more 'deeply integrated' support
> than that, for a lot of reasons: Lennart mentioned that this only really
> works on Linux (and of course, only works if you connect to the bus
> using Unix sockets).  There's also the concern of what it would mean to
> serialise a GVariant that contains an fd (to dconf, to the registry, to
> text format, to XML, or to anything else).

Yeah, the 'h' type really is for _handles_ - see the discussion on the
dbus list when this was introduced (well, initially Lenny wanted 'f' -
but some D-Bus implementations use that for gfloat and we didn't want to
screw them).

So only in Unix (mind you, not only Linux but any Unix that can pass fds
- including Solaris and OS X) 'h' used for sending file descriptors but
in Win32 it could probably be used for a HANDLE (e.g. the Win32 concept
of file descriptors) - I actually think you can pass HANDLE to other
Win32 processes.

So how about something like 1. and 2. below? We'd put

 g_dbus_connection_get_handle_for_unix_fd()
 g_dbus_connection_set_handle_for_unix_fd()

in the gio-unix-2.0 headers. Presumably we could add

 g_dbus_connection_get_handle_for_win32_handle()
 g_dbus_connection_set_handle_for_win32_handle()

and put that in gio-win32-2.0 if such a thing was to surface.

In the future we could also have

 g_dbus_connection_get_handle_for_iostream()
 g_dbus_connection_set_handle_for_iostream()

that takes a GIOStream (this might not be a good idea, I don't know).

For this to work, however, I'd need something like

 g_object_set_data_full()
 g_object_get_data()

on the GVariant type since we'd want to clean up stuff when the passed
GVariant is destroyed. It might be nice to have that on GVariant
*anyway*, see

http://bugzilla.gnome.org/show_bug.cgi?id=581106

for why associations are useful in general.

Thanks,
David

---

1. user code for sending variants:

 GVariant *parameters;

 parameters = g_variant_new ("(ih"),
               some_int,
               g_dbus_connection_get_handle_for_unix_fd (connection,
                                                         variant,
                                                         some_fd));
 g_dbus_proxy_invoke_method (proxy,
                             "SomeMethodTakingAnIntAndUnixFd",
                             parameters,
                             -1, NULL, callback, user_data);

2. user code for receiving a variant

 gint some_int;
 gint handle;
 gint fd;

 handle = g_variant_get (result_parameters, "(ih)", &some_int, &handle);
 fd = g_dbus_connection_get_unix_fd_for_handle (connection, handle);
 g_variant_unref (result_parameters);

 /* use fd */

 close (fd);




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