gdbus-codegen: emit GUnixFDLists if an arg has type 'h'

Previously, if a method was not annotated with org.gtk.GDBus.C.UnixFD
then the generated code would never contain GUnixFDList parameters, even
if the method has 'h' (file descriptor) parameters. However, in this
case, the generated code is essentially useless: the method cannot be
called or handled except in degenerate cases where the file descriptors
are missing or ignored.

Check the argument types for 'h', and if present, generate code as if
org.gtk.GDBus.C.UnixFD annotation were specified.

This change will break any existing code which refers to the (useless)
wrappers for such methods. The workaround for such code is to add the
org.gtk.GDBus.C.UnixFD annotation, which will cause the same generated
code to be emitted before and after this change.

If this is found to cause widespread problems, we can explore a
different approach (perhaps emitting a warning from the code generator,
or annotating the symbols as deprecated).

https://gitlab.gnome.org/GNOME/glib/issues/1726
This commit is contained in:
Will Thompson 2019-09-02 06:56:08 +01:00
parent 9b827e5674
commit 4aba03562b
3 changed files with 45 additions and 2 deletions

View File

@ -284,10 +284,14 @@ class Method:
for a in self.in_args:
a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count)
arg_count += 1
if 'h' in a.signature:
self.unix_fd = True
for a in self.out_args:
a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count)
arg_count += 1
if 'h' in a.signature:
self.unix_fd = True
if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
self.deprecated = True

View File

@ -2599,16 +2599,46 @@ handle_hello_fd (FooiGenFDPassing *object,
return TRUE;
}
/* Test that generated code for methods includes GUnixFDList arguments if
* the method is explicitly annotated as C.UnixFD.
static gboolean
handle_no_annotation (FooiGenFDPassing *object,
GDBusMethodInvocation *invocation,
GUnixFDList *fd_list,
GVariant *arg_greeting,
const gchar *arg_greeting_locale)
{
foo_igen_fdpassing_complete_no_annotation (object, invocation, fd_list, arg_greeting, arg_greeting_locale);
return TRUE;
}
static gboolean
handle_no_annotation_nested (FooiGenFDPassing *object,
GDBusMethodInvocation *invocation,
GUnixFDList *fd_list,
GVariant *arg_files)
{
foo_igen_fdpassing_complete_no_annotation_nested (object, invocation, fd_list);
return TRUE;
}
/* Test that generated code for methods includes GUnixFDList arguments if:
* - the method is explicitly annotated as C.UnixFD; or
* - the method signature contains the type 'h'
*/
static void
test_unix_fd_list (void)
{
FooiGenFDPassingIface iface;
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1726");
/* This method is explicitly annotated. */
iface.handle_hello_fd = handle_hello_fd;
/* This one is not, but it's got an in and out 'h' parameter so should
* automatically grow GUnixFDList arguments.
*/
iface.handle_no_annotation = handle_no_annotation;
/* This method has an 'h' inside a complex type. */
iface.handle_no_annotation_nested = handle_no_annotation_nested;
(void) iface;
}

View File

@ -481,6 +481,15 @@
<arg name="greeting" direction="in" type="s"/>
<arg name="response" direction="out" type="s"/>
</method>
<method name="NoAnnotation">
<arg name="greeting" direction="in" type="h"/>
<arg name="greeting_locale" direction="in" type="s"/>
<arg name="response" direction="out" type="h"/>
<arg name="response_locale" direction="out" type="s"/>
</method>
<method name="NoAnnotationNested">
<arg name="files" type="a{sh}" direction="in"/>
</method>
</interface>
<interface name="Naming">