Argument array of strings
Peter Clifton
pcjc2 at cam.ac.uk
Thu Oct 12 20:14:41 PDT 2006
Hi,
I've started the task of "porting" my glib dbus code to raw libdbus (for
sake of mainloop independance), and have run into difficulties with a
method:
<interface name="org.seul.geda.pcb.actions">
<method name="ExecAction">
<arg direction="in" type="s" name="action" />
<arg direction="in" type="as" name="args" />
<arg direction="out" type="u" />
</method>
</interface>
I can get the "action" argument, I pick up the "args" argument as a
DBUS_TYPE_ARRAY, I can verify that it is an array of strings.
However:
What I can't seem to do is get the size of that array without the
program crashing.
I really want to know the size of the array before iterating over it, so
I can allocate memory for storing the strings.
When iterating over the "args" array of strings, I get the right strings
out, I just can't seem to determine how many are there before-hand.
Regards
Peter Clifton
static DBusHandlerResult
handle_exec_action( DBusConnection *connection, DBusMessage *message,
void *data)
{
DBusMessage *reply;
DBusMessageIter args;
DBusMessageIter iter;
DBusMessageIter subiter;
DBusHandlerResult result;
dbus_uint32_t retval;
char *action_name;
char **argv;
int argc;
int i;
result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (!dbus_message_iter_init(message, &args))
{
fprintf(stderr, "Message has no arguments!\n");
return result;
}
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
{
fprintf(stderr, "Argument is not string!\n");
return result;
}
else
dbus_message_iter_get_basic(&args, &action_name);
printf("pcb_dbus: DEBUG: ExecAction called with action '%s'\n",
action_name);
if (!dbus_message_iter_next(&args))
{
fprintf(stderr, "DBUS Method has no argument array!\n");
return result;
}
else if (DBUS_TYPE_ARRAY != dbus_message_iter_get_arg_type(&args))
{
fprintf(stderr, "Argument is not array!\n");
return result;
}
else if (DBUS_TYPE_STRING !=
dbus_message_iter_get_element_type(&args))
{
fprintf(stderr, "Argument array not strings\n");
return result;
}
{
char *signature;
signature = dbus_message_iter_get_signature( &args );
fprintf( stderr, "pcb_dbus: DEBUG: Signature of args = '%s'\n",
signature );
}
dbus_message_iter_recurse( &args, &subiter );
{
char *signature;
signature = dbus_message_iter_get_signature( &subiter );
fprintf( stderr, "pcb_dbus: DEBUG: Signature of subiter = '%s'\n",
signature );
}
argc = 2;
/* THIS LINE CRASHES */
argc = dbus_message_iter_get_array_len( &args );
fprintf( stderr, "pcb_dbus: DEBUG: Argument count is %i\n", argc );
argv = malloc( argc * sizeof( char * ) );
if ( argv == NULL )
{
fprintf(stderr, "malloc for argument array failed\n");
return result;
}
i = 0;
while ( i < argc )
{
dbus_message_iter_get_basic( &subiter, &argv[i] );
dbus_message_iter_next( &subiter );
printf( " Got argument #%i = '%s'\n", i, argv[i] );
i++;
}
fprintf( stderr, "pcb_dbus: DEBUG: about to execute action\n" );
// TODO: Proper return value from actions
hid_actionv( action_name, argc, argv );
retval = 0;
free( argv );
reply = dbus_message_new_method_return(message);
if (reply == NULL)
{
fprintf( stderr, "pcb_dbus: DEBUG: Couldn't create reply message
\n" );
return result;
}
dbus_message_iter_init_append(reply, &iter);
if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &retval))
{
fprintf(stderr, "pcb_dbus: DEBUG: Couldn't sent message, Out Of
Memory!\n");
goto out;
}
if (!dbus_connection_send(connection, reply, NULL))
{
fprintf(stderr, "pcb_dbus: DEBUG: Couldn't send message, Out Of
Memory!\n");
goto out;
}
result = DBUS_HANDLER_RESULT_HANDLED;
out:
dbus_message_unref( reply );
return result;
}
The crash is:
pcb_dbus: DEBUG: Method name was 'Introspect'
pcb_dbus: DEBUG: Method interface was
'org.freedesktop.DBus.Introspectable'
pcb_dbus: DEBUG: Method call message
pcb_dbus: DEBUG: Method name was 'GetFilename'
pcb_dbus: DEBUG: Method interface was 'org.seul.geda.pcb'
pcb_dbus: DEBUG: Method call message
pcb_dbus: DEBUG: Method name was 'ExecAction'
pcb_dbus: DEBUG: Method interface was 'org.seul.geda.pcb.actions'
pcb_dbus: DEBUG: ExecAction called with action 'SaveTo'
pcb_dbus: DEBUG: Signature of args = 'as'
pcb_dbus: DEBUG: Signature of subiter = 's'
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1219139920 (LWP 8754)]
0xb7eec7d6 in dbus_error_has_name () from /usr/lib/libdbus-1.so.3
(gdb) bt
#0 0xb7eec7d6 in dbus_error_has_name () from /usr/lib/libdbus-1.so.3
#1 0x080bda1b in handle_dbus_message (connection=0x830abf8,
message=0x8305770, data=0x0) at dbus.c:164
#2 0xb7ef4a3b in dbus_message_new_method_return ()
from /usr/lib/libdbus-1.so.3
#3 0xb7ee793a in dbus_connection_dispatch ()
from /usr/lib/libdbus-1.so.3
#4 0xb7ee7d38 in dbus_connection_borrow_message ()
from /usr/lib/libdbus-1.so.3
#5 0x080bd2d5 in pcb_dbus_setup () at dbus.c:407
#6 0x08090722 in main (argc=Cannot access memory at address 0x0
) at main.c:774
(gdb)
However... this stack doesn't look right to me.. Still.. it is 4AM, and
I'm _very_ tired now!
Peter C.
More information about the dbus
mailing list