pydbus icon indicating copy to clipboard operation
pydbus copied to clipboard

Unix file descriptors not supported

Open jawsper opened this issue 8 years ago • 5 comments

When I try to inhibit the power key on org.freedesktop.login1, pydbus doesn't seem to return the file descriptor, nor does it give me an error.

Sample code:

import pydbus
bus = pydbus.SystemBus()
login1 = bus.get('.login1')['.Manager']
fd = login1.Inhibit('handle-power-key', 'AppName', 'Reason', 'block')

Expected result is a valid file descriptor. Actual result is 0.

This does work fine in python-dbus:

import dbus
bus = dbus.SystemBus()
proxy = bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1')
login1 = dbus.Interface(proxy, 'org.freedesktop.login1.Manager')
fd = login1.Inhibit('handle-power-key', 'test_logind', 'test_logind handling power button', 'block').take()

This is on python 3.6.0 with pydbus version 0.6.0

jawsper avatar Jan 19 '17 15:01 jawsper

I haven't written any code for fd passing yet, and looks like GDBus does not support them transparently, but requires using g_dbus_message_get_unix_fd_list - like in https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-unix-fd-client.c#n27

I guess it's necessary to modify https://github.com/LEW21/pydbus/blob/master/pydbus/proxy_method.py#L72 to use the GDBusMessage API for calling methods.

LEW21 avatar Jan 19 '17 18:01 LEW21

While digging around I found the method call_with_unix_fd_list_sync, which seems to be the right function for this job. Documentation: http://lazka.github.io/pgi-docs/#Gio-2.0/classes/DBusConnection.html#Gio.DBusConnection.call_with_unix_fd_list_sync Example usage: https://git.centos.org/blob/rpms!gnome-tweak-tool/aaa06e94d4f5ac34090c5b33a91b8ab2dfdcd74f/SOURCES!0001-Add-a-tweak-to-ignore-systemd-s-default-lid-switch-a.patch#L98

I've made a nasty hack to test if this is right, and so far it seems to be successful.

jawsper avatar Jan 19 '17 22:01 jawsper

I did some more checks, and it appears it doesn't matter if you call call_sync or call_with_unix_fd_list_sync, since they both call g_dbus_connection_call_sync_internal anyway. (https://git.gnome.org/browse/glib/tree/gio/gdbusconnection.c?h=2.50.0#n6162 vs https://git.gnome.org/browse/glib/tree/gio/gdbusconnection.c?h=2.50.0#n6281)

The question now is how to solve this in the cleanest way. I would propose to use call_with_unix_fd_list_sync either way, since it works the same for either case. Only matter now is deciding how to deal with the return value in the best way. I think the best result would be to copy the result of dbus-python, and replace the return values with the file descriptor as an integer.

One issue I do still see is that call_with_unix_fd_list_sync only works on UNIX, but is that actually an issue? Is there dbus for non-UNIX systems?

jawsper avatar Jan 20 '17 20:01 jawsper

I just wanted to add that I've seen issues with Unix file descriptors not being represented correctly in pydbus also. It has taken me a while to track this down and I wanted to share some of my findings in the hope that it helps.

I have been rewriting the BlueZ test-profile script to use pydbus. The fd argument for NewConnection is of type h. When using python-dbus this arrives as type 'dbus.UnixFd' and when using pydbus it turns up as class int. Looking at https://developer.gnome.org/glib/stable/gvariant-format-strings.html suggests that pydbus is correct while https://dbus.freedesktop.org/doc/dbus-specification.html#basic-types suggests python-dbus is correct. However it is only possible to read the file with the information given by python-dbus.

Is there a simple work around that would allow me to get something working for test-profile with pydbus? Or is this a show-stopping issue?

Thanks in advance, Barry

ukBaz avatar Apr 26 '17 23:04 ukBaz

Relevant: https://github.com/LEW21/pydbus/issues/54#issuecomment-471199168

molobrakos avatar Mar 09 '19 16:03 molobrakos