diff options
Diffstat (limited to 'src/dbusbind.c')
| -rw-r--r-- | src/dbusbind.c | 103 |
1 files changed, 66 insertions, 37 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c index 4828f4e968d..ad1a3f3cbe8 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Elisp bindings for D-Bus. | 1 | /* Elisp bindings for D-Bus. |
| 2 | Copyright (C) 2007-2011 Free Software Foundation, Inc. | 2 | Copyright (C) 2007-2012 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -184,7 +184,7 @@ static int xd_in_read_queued_messages = 0; | |||
| 184 | #endif | 184 | #endif |
| 185 | 185 | ||
| 186 | /* This was a macro. On Solaris 2.11 it was said to compile for | 186 | /* This was a macro. On Solaris 2.11 it was said to compile for |
| 187 | hours, when optimzation is enabled. So we have transferred it into | 187 | hours, when optimization is enabled. So we have transferred it into |
| 188 | a function. */ | 188 | a function. */ |
| 189 | /* Determine the DBusType of a given Lisp symbol. OBJECT must be one | 189 | /* Determine the DBusType of a given Lisp symbol. OBJECT must be one |
| 190 | of the predefined D-Bus type symbols. */ | 190 | of the predefined D-Bus type symbols. */ |
| @@ -259,6 +259,18 @@ xd_symbol_to_dbus_type (Lisp_Object object) | |||
| 259 | } \ | 259 | } \ |
| 260 | while (0) | 260 | while (0) |
| 261 | 261 | ||
| 262 | /* Append to SIGNATURE a copy of X, making sure SIGNATURE does | ||
| 263 | not become too long. */ | ||
| 264 | static void | ||
| 265 | xd_signature_cat (char *signature, char const *x) | ||
| 266 | { | ||
| 267 | ptrdiff_t siglen = strlen (signature); | ||
| 268 | ptrdiff_t xlen = strlen (x); | ||
| 269 | if (DBUS_MAXIMUM_SIGNATURE_LENGTH - xlen <= siglen) | ||
| 270 | string_overflow (); | ||
| 271 | strcat (signature, x); | ||
| 272 | } | ||
| 273 | |||
| 262 | /* Compute SIGNATURE of OBJECT. It must have a form that it can be | 274 | /* Compute SIGNATURE of OBJECT. It must have a form that it can be |
| 263 | used in dbus_message_iter_open_container. DTYPE is the DBusType | 275 | used in dbus_message_iter_open_container. DTYPE is the DBusType |
| 264 | the object is related to. It is passed as argument, because it | 276 | the object is related to. It is passed as argument, because it |
| @@ -271,6 +283,8 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 271 | { | 283 | { |
| 272 | unsigned int subtype; | 284 | unsigned int subtype; |
| 273 | Lisp_Object elt; | 285 | Lisp_Object elt; |
| 286 | char const *subsig; | ||
| 287 | int subsiglen; | ||
| 274 | char x[DBUS_MAXIMUM_SIGNATURE_LENGTH]; | 288 | char x[DBUS_MAXIMUM_SIGNATURE_LENGTH]; |
| 275 | 289 | ||
| 276 | elt = object; | 290 | elt = object; |
| @@ -328,12 +342,13 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 328 | if (NILP (elt)) | 342 | if (NILP (elt)) |
| 329 | { | 343 | { |
| 330 | subtype = DBUS_TYPE_STRING; | 344 | subtype = DBUS_TYPE_STRING; |
| 331 | strcpy (x, DBUS_TYPE_STRING_AS_STRING); | 345 | subsig = DBUS_TYPE_STRING_AS_STRING; |
| 332 | } | 346 | } |
| 333 | else | 347 | else |
| 334 | { | 348 | { |
| 335 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); | 349 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); |
| 336 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); | 350 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 351 | subsig = x; | ||
| 337 | } | 352 | } |
| 338 | 353 | ||
| 339 | /* If the element type is DBUS_TYPE_SIGNATURE, and this is the | 354 | /* If the element type is DBUS_TYPE_SIGNATURE, and this is the |
| @@ -342,7 +357,7 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 342 | if ((subtype == DBUS_TYPE_SIGNATURE) | 357 | if ((subtype == DBUS_TYPE_SIGNATURE) |
| 343 | && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt))) | 358 | && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt))) |
| 344 | && NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) | 359 | && NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) |
| 345 | strcpy (x, SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt)))); | 360 | subsig = SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 346 | 361 | ||
| 347 | while (!NILP (elt)) | 362 | while (!NILP (elt)) |
| 348 | { | 363 | { |
| @@ -351,7 +366,10 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 351 | elt = CDR_SAFE (XD_NEXT_VALUE (elt)); | 366 | elt = CDR_SAFE (XD_NEXT_VALUE (elt)); |
| 352 | } | 367 | } |
| 353 | 368 | ||
| 354 | sprintf (signature, "%c%s", dtype, x); | 369 | subsiglen = snprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH, |
| 370 | "%c%s", dtype, subsig); | ||
| 371 | if (! (0 <= subsiglen && subsiglen < DBUS_MAXIMUM_SIGNATURE_LENGTH)) | ||
| 372 | string_overflow (); | ||
| 355 | break; | 373 | break; |
| 356 | 374 | ||
| 357 | case DBUS_TYPE_VARIANT: | 375 | case DBUS_TYPE_VARIANT: |
| @@ -383,10 +401,10 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 383 | { | 401 | { |
| 384 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); | 402 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); |
| 385 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); | 403 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 386 | strcat (signature, x); | 404 | xd_signature_cat (signature, x); |
| 387 | elt = CDR_SAFE (XD_NEXT_VALUE (elt)); | 405 | elt = CDR_SAFE (XD_NEXT_VALUE (elt)); |
| 388 | } | 406 | } |
| 389 | strcat (signature, DBUS_STRUCT_END_CHAR_AS_STRING); | 407 | xd_signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING); |
| 390 | break; | 408 | break; |
| 391 | 409 | ||
| 392 | case DBUS_TYPE_DICT_ENTRY: | 410 | case DBUS_TYPE_DICT_ENTRY: |
| @@ -407,7 +425,7 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 407 | elt = XD_NEXT_VALUE (elt); | 425 | elt = XD_NEXT_VALUE (elt); |
| 408 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); | 426 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); |
| 409 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); | 427 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 410 | strcat (signature, x); | 428 | xd_signature_cat (signature, x); |
| 411 | 429 | ||
| 412 | if (!XD_BASIC_DBUS_TYPE (subtype)) | 430 | if (!XD_BASIC_DBUS_TYPE (subtype)) |
| 413 | wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt))); | 431 | wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt))); |
| @@ -416,14 +434,14 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis | |||
| 416 | elt = CDR_SAFE (XD_NEXT_VALUE (elt)); | 434 | elt = CDR_SAFE (XD_NEXT_VALUE (elt)); |
| 417 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); | 435 | subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); |
| 418 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); | 436 | xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); |
| 419 | strcat (signature, x); | 437 | xd_signature_cat (signature, x); |
| 420 | 438 | ||
| 421 | if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) | 439 | if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) |
| 422 | wrong_type_argument (intern ("D-Bus"), | 440 | wrong_type_argument (intern ("D-Bus"), |
| 423 | CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt)))); | 441 | CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt)))); |
| 424 | 442 | ||
| 425 | /* Closing signature. */ | 443 | /* Closing signature. */ |
| 426 | strcat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING); | 444 | xd_signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING); |
| 427 | break; | 445 | break; |
| 428 | 446 | ||
| 429 | default: | 447 | default: |
| @@ -950,7 +968,7 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0, | |||
| 950 | connection = xd_initialize (bus, TRUE); | 968 | connection = xd_initialize (bus, TRUE); |
| 951 | 969 | ||
| 952 | /* Add the watch functions. We pass also the bus as data, in order | 970 | /* Add the watch functions. We pass also the bus as data, in order |
| 953 | to distinguish between the busses in xd_remove_watch. */ | 971 | to distinguish between the buses in xd_remove_watch. */ |
| 954 | if (!dbus_connection_set_watch_functions (connection, | 972 | if (!dbus_connection_set_watch_functions (connection, |
| 955 | xd_add_watch, | 973 | xd_add_watch, |
| 956 | xd_remove_watch, | 974 | xd_remove_watch, |
| @@ -1862,7 +1880,7 @@ xd_read_queued_messages (int fd, void *data, int for_read) | |||
| 1862 | busp = CDR_SAFE (busp); | 1880 | busp = CDR_SAFE (busp); |
| 1863 | } | 1881 | } |
| 1864 | 1882 | ||
| 1865 | if (NILP(bus)) | 1883 | if (NILP (bus)) |
| 1866 | return; | 1884 | return; |
| 1867 | 1885 | ||
| 1868 | /* We ignore all Lisp errors during the call. */ | 1886 | /* We ignore all Lisp errors during the call. */ |
| @@ -2026,7 +2044,7 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG | |||
| 2026 | DBusConnection *connection; | 2044 | DBusConnection *connection; |
| 2027 | ptrdiff_t i; | 2045 | ptrdiff_t i; |
| 2028 | char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; | 2046 | char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; |
| 2029 | char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; | 2047 | int rulelen; |
| 2030 | DBusError derror; | 2048 | DBusError derror; |
| 2031 | 2049 | ||
| 2032 | /* Check parameters. */ | 2050 | /* Check parameters. */ |
| @@ -2053,13 +2071,7 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG | |||
| 2053 | && (SBYTES (service) > 0) | 2071 | && (SBYTES (service) > 0) |
| 2054 | && (strcmp (SSDATA (service), DBUS_SERVICE_DBUS) != 0) | 2072 | && (strcmp (SSDATA (service), DBUS_SERVICE_DBUS) != 0) |
| 2055 | && (strncmp (SSDATA (service), ":", 1) != 0)) | 2073 | && (strncmp (SSDATA (service), ":", 1) != 0)) |
| 2056 | { | 2074 | uname = call2 (intern ("dbus-get-name-owner"), bus, service); |
| 2057 | uname = call2 (intern ("dbus-get-name-owner"), bus, service); | ||
| 2058 | /* When there is no unique name, we mark it with an empty | ||
| 2059 | string. */ | ||
| 2060 | if (NILP (uname)) | ||
| 2061 | uname = empty_unibyte_string; | ||
| 2062 | } | ||
| 2063 | else | 2075 | else |
| 2064 | uname = service; | 2076 | uname = service; |
| 2065 | 2077 | ||
| @@ -2071,32 +2083,43 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG | |||
| 2071 | connection = xd_initialize (bus, TRUE); | 2083 | connection = xd_initialize (bus, TRUE); |
| 2072 | 2084 | ||
| 2073 | /* Create a rule to receive related signals. */ | 2085 | /* Create a rule to receive related signals. */ |
| 2074 | sprintf (rule, | 2086 | rulelen = snprintf (rule, sizeof rule, |
| 2075 | "type='signal',interface='%s',member='%s'", | 2087 | "type='signal',interface='%s',member='%s'", |
| 2076 | SDATA (interface), | 2088 | SDATA (interface), |
| 2077 | SDATA (signal)); | 2089 | SDATA (signal)); |
| 2090 | if (! (0 <= rulelen && rulelen < sizeof rule)) | ||
| 2091 | string_overflow (); | ||
| 2078 | 2092 | ||
| 2079 | /* Add unique name and path to the rule if they are non-nil. */ | 2093 | /* Add unique name and path to the rule if they are non-nil. */ |
| 2080 | if (!NILP (uname)) | 2094 | if (!NILP (uname)) |
| 2081 | { | 2095 | { |
| 2082 | sprintf (x, ",sender='%s'", SDATA (uname)); | 2096 | int len = snprintf (rule + rulelen, sizeof rule - rulelen, |
| 2083 | strcat (rule, x); | 2097 | ",sender='%s'", SDATA (uname)); |
| 2098 | if (! (0 <= len && len < sizeof rule - rulelen)) | ||
| 2099 | string_overflow (); | ||
| 2100 | rulelen += len; | ||
| 2084 | } | 2101 | } |
| 2085 | 2102 | ||
| 2086 | if (!NILP (path)) | 2103 | if (!NILP (path)) |
| 2087 | { | 2104 | { |
| 2088 | sprintf (x, ",path='%s'", SDATA (path)); | 2105 | int len = snprintf (rule + rulelen, sizeof rule - rulelen, |
| 2089 | strcat (rule, x); | 2106 | ",path='%s'", SDATA (path)); |
| 2107 | if (! (0 <= len && len < sizeof rule - rulelen)) | ||
| 2108 | string_overflow (); | ||
| 2109 | rulelen += len; | ||
| 2090 | } | 2110 | } |
| 2091 | 2111 | ||
| 2092 | /* Add arguments to the rule if they are non-nil. */ | 2112 | /* Add arguments to the rule if they are non-nil. */ |
| 2093 | for (i = 6; i < nargs; ++i) | 2113 | for (i = 6; i < nargs; ++i) |
| 2094 | if (!NILP (args[i])) | 2114 | if (!NILP (args[i])) |
| 2095 | { | 2115 | { |
| 2116 | int len; | ||
| 2096 | CHECK_STRING (args[i]); | 2117 | CHECK_STRING (args[i]); |
| 2097 | sprintf (x, ",arg%"pD"d='%s'", i - 6, | 2118 | len = snprintf (rule + rulelen, sizeof rule - rulelen, |
| 2098 | SDATA (args[i])); | 2119 | ",arg%"pD"d='%s'", i - 6, SDATA (args[i])); |
| 2099 | strcat (rule, x); | 2120 | if (! (0 <= len && len < sizeof rule - rulelen)) |
| 2121 | string_overflow (); | ||
| 2122 | rulelen += len; | ||
| 2100 | } | 2123 | } |
| 2101 | 2124 | ||
| 2102 | /* Add the rule to the bus. */ | 2125 | /* Add the rule to the bus. */ |
| @@ -2116,7 +2139,7 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG | |||
| 2116 | 2139 | ||
| 2117 | /* Create a hash table entry. */ | 2140 | /* Create a hash table entry. */ |
| 2118 | key = list3 (bus, interface, signal); | 2141 | key = list3 (bus, interface, signal); |
| 2119 | key1 = list4 (uname, service, path, handler); | 2142 | key1 = list5 (uname, service, path, handler, build_string (rule)); |
| 2120 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); | 2143 | value = Fgethash (key, Vdbus_registered_objects_table, Qnil); |
| 2121 | 2144 | ||
| 2122 | if (NILP (Fmember (key1, value))) | 2145 | if (NILP (Fmember (key1, value))) |
| @@ -2139,16 +2162,19 @@ DONT-REGISTER-SERVICE below). | |||
| 2139 | 2162 | ||
| 2140 | PATH is the D-Bus object path SERVICE is registered (See discussion of | 2163 | PATH is the D-Bus object path SERVICE is registered (See discussion of |
| 2141 | DONT-REGISTER-SERVICE below). INTERFACE is the interface offered by | 2164 | DONT-REGISTER-SERVICE below). INTERFACE is the interface offered by |
| 2142 | SERVICE. It must provide METHOD. HANDLER is a Lisp function to be | 2165 | SERVICE. It must provide METHOD. |
| 2143 | called when a method call is received. It must accept the input | 2166 | |
| 2144 | arguments of METHOD. The return value of HANDLER is used for | 2167 | HANDLER is a Lisp function to be called when a method call is |
| 2145 | composing the returning D-Bus message. | 2168 | received. It must accept the input arguments of METHOD. The return |
| 2169 | value of HANDLER is used for composing the returning D-Bus message. | ||
| 2170 | In case HANDLER shall return a reply message with an empty argument | ||
| 2171 | list, HANDLER must return the symbol `:ignore'. | ||
| 2146 | 2172 | ||
| 2147 | When DONT-REGISTER-SERVICE is non-nil, the known name SERVICE is not | 2173 | When DONT-REGISTER-SERVICE is non-nil, the known name SERVICE is not |
| 2148 | registered. This means that other D-Bus clients have no way of | 2174 | registered. This means that other D-Bus clients have no way of |
| 2149 | noticing the newly registered method. When interfaces are constructed | 2175 | noticing the newly registered method. When interfaces are constructed |
| 2150 | incrementally by adding single methods or properties at a time, | 2176 | incrementally by adding single methods or properties at a time, |
| 2151 | DONT-REGISTER-SERVICE can be use to prevent other clients from | 2177 | DONT-REGISTER-SERVICE can be used to prevent other clients from |
| 2152 | discovering the still incomplete interface.*/) | 2178 | discovering the still incomplete interface.*/) |
| 2153 | (Lisp_Object bus, Lisp_Object service, Lisp_Object path, | 2179 | (Lisp_Object bus, Lisp_Object service, Lisp_Object path, |
| 2154 | Lisp_Object interface, Lisp_Object method, Lisp_Object handler, | 2180 | Lisp_Object interface, Lisp_Object method, Lisp_Object handler, |
| @@ -2290,6 +2316,9 @@ be called when a D-Bus message, which matches the key criteria, | |||
| 2290 | arrives (methods and signals), or a cons cell containing the value of | 2316 | arrives (methods and signals), or a cons cell containing the value of |
| 2291 | the property. | 2317 | the property. |
| 2292 | 2318 | ||
| 2319 | For signals, there is also a fifth element RULE, which keeps the match | ||
| 2320 | string the signal is registered with. | ||
| 2321 | |||
| 2293 | In the second case, the key in the hash table is the list (BUS | 2322 | In the second case, the key in the hash table is the list (BUS |
| 2294 | SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a | 2323 | SERIAL). BUS is either a Lisp symbol, `:system' or `:session', or a |
| 2295 | string denoting the bus address. SERIAL is the serial number of the | 2324 | string denoting the bus address. SERIAL is the serial number of the |