]> code.delx.au - gnu-emacs/blobdiff - src/dbusbind.c
* window.c (Fdelete_window_internal): Invalidate the mouse highlight.
[gnu-emacs] / src / dbusbind.c
index 005d521c1db6386cff0cbcf1978e4edac89312a9..ad1a3f3cbe856f1157ea6ad960cae759748f71ea 100644 (file)
@@ -1,5 +1,5 @@
 /* Elisp bindings for D-Bus.
-   Copyright (C) 2007-2011 Free Software Foundation, Inc.
+   Copyright (C) 2007-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -184,7 +184,7 @@ static int xd_in_read_queued_messages = 0;
 #endif
 
 /* This was a macro.  On Solaris 2.11 it was said to compile for
-   hours, when optimzation is enabled.  So we have transferred it into
+   hours, when optimization is enabled.  So we have transferred it into
    a function.  */
 /* Determine the DBusType of a given Lisp symbol.  OBJECT must be one
    of the predefined D-Bus type symbols.  */
@@ -259,6 +259,18 @@ xd_symbol_to_dbus_type (Lisp_Object object)
     }                                                                  \
   while (0)
 
+/* Append to SIGNATURE a copy of X, making sure SIGNATURE does
+   not become too long.  */
+static void
+xd_signature_cat (char *signature, char const *x)
+{
+  ptrdiff_t siglen = strlen (signature);
+  ptrdiff_t xlen = strlen (x);
+  if (DBUS_MAXIMUM_SIGNATURE_LENGTH - xlen <= siglen)
+    string_overflow ();
+  strcat (signature, x);
+}
+
 /* Compute SIGNATURE of OBJECT.  It must have a form that it can be
    used in dbus_message_iter_open_container.  DTYPE is the DBusType
    the object is related to.  It is passed as argument, because it
@@ -272,6 +284,7 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
   unsigned int subtype;
   Lisp_Object elt;
   char const *subsig;
+  int subsiglen;
   char x[DBUS_MAXIMUM_SIGNATURE_LENGTH];
 
   elt = object;
@@ -353,9 +366,9 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
          elt = CDR_SAFE (XD_NEXT_VALUE (elt));
        }
 
-      if (esnprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH,
-                    "%c%s", dtype, subsig)
-         == DBUS_MAXIMUM_SIGNATURE_LENGTH - 1)
+      subsiglen = snprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH,
+                           "%c%s", dtype, subsig);
+      if (! (0 <= subsiglen && subsiglen < DBUS_MAXIMUM_SIGNATURE_LENGTH))
        string_overflow ();
       break;
 
@@ -388,10 +401,10 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
        {
          subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
          xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
-         strcat (signature, x);
+         xd_signature_cat (signature, x);
          elt = CDR_SAFE (XD_NEXT_VALUE (elt));
        }
-      strcat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
+      xd_signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING);
       break;
 
     case DBUS_TYPE_DICT_ENTRY:
@@ -412,7 +425,7 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
       elt = XD_NEXT_VALUE (elt);
       subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
       xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
-      strcat (signature, x);
+      xd_signature_cat (signature, x);
 
       if (!XD_BASIC_DBUS_TYPE (subtype))
        wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt)));
@@ -421,14 +434,14 @@ xd_signature (char *signature, unsigned int dtype, unsigned int parent_type, Lis
       elt = CDR_SAFE (XD_NEXT_VALUE (elt));
       subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt));
       xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt)));
-      strcat (signature, x);
+      xd_signature_cat (signature, x);
 
       if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt))))
        wrong_type_argument (intern ("D-Bus"),
                             CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt))));
 
       /* Closing signature.  */
-      strcat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
+      xd_signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING);
       break;
 
     default:
@@ -955,7 +968,7 @@ DEFUN ("dbus-init-bus", Fdbus_init_bus, Sdbus_init_bus, 1, 1, 0,
   connection = xd_initialize (bus, TRUE);
 
   /* Add the watch functions.  We pass also the bus as data, in order
-     to distinguish between the busses in xd_remove_watch.  */
+     to distinguish between the buses in xd_remove_watch.  */
   if (!dbus_connection_set_watch_functions (connection,
                                            xd_add_watch,
                                            xd_remove_watch,
@@ -1867,7 +1880,7 @@ xd_read_queued_messages (int fd, void *data, int for_read)
        busp = CDR_SAFE (busp);
       }
 
-  if (NILP(bus))
+  if (NILP (bus))
     return;
 
   /* We ignore all Lisp errors during the call.  */
@@ -2058,13 +2071,7 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG
       && (SBYTES (service) > 0)
       && (strcmp (SSDATA (service), DBUS_SERVICE_DBUS) != 0)
       && (strncmp (SSDATA (service), ":", 1) != 0))
-    {
-      uname = call2 (intern ("dbus-get-name-owner"), bus, service);
-      /* When there is no unique name, we mark it with an empty
-        string.  */
-      if (NILP (uname))
-       uname = empty_unibyte_string;
-    }
+    uname = call2 (intern ("dbus-get-name-owner"), bus, service);
   else
     uname = service;
 
@@ -2076,32 +2083,45 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG
       connection = xd_initialize (bus, TRUE);
 
       /* Create a rule to receive related signals.  */
-      rulelen = esnprintf (rule, sizeof rule,
-                          "type='signal',interface='%s',member='%s'",
-                          SDATA (interface),
-                          SDATA (signal));
+      rulelen = snprintf (rule, sizeof rule,
+                         "type='signal',interface='%s',member='%s'",
+                         SDATA (interface),
+                         SDATA (signal));
+      if (! (0 <= rulelen && rulelen < sizeof rule))
+       string_overflow ();
 
       /* Add unique name and path to the rule if they are non-nil.  */
       if (!NILP (uname))
-       rulelen += esnprintf (rule + rulelen, sizeof rule - rulelen,
+       {
+         int len = snprintf (rule + rulelen, sizeof rule - rulelen,
                              ",sender='%s'", SDATA (uname));
+         if (! (0 <= len && len < sizeof rule - rulelen))
+           string_overflow ();
+         rulelen += len;
+       }
 
       if (!NILP (path))
-       rulelen += esnprintf (rule + rulelen, sizeof rule - rulelen,
+       {
+         int len = snprintf (rule + rulelen, sizeof rule - rulelen,
                              ",path='%s'", SDATA (path));
+         if (! (0 <= len && len < sizeof rule - rulelen))
+           string_overflow ();
+         rulelen += len;
+       }
 
       /* Add arguments to the rule if they are non-nil.  */
       for (i = 6; i < nargs; ++i)
        if (!NILP (args[i]))
          {
+           int len;
            CHECK_STRING (args[i]);
-           rulelen += esnprintf (rule + rulelen, sizeof rule - rulelen,
-                                 ",arg%"pD"d='%s'", i - 6, SDATA (args[i]));
+           len = snprintf (rule + rulelen, sizeof rule - rulelen,
+                           ",arg%"pD"d='%s'", i - 6, SDATA (args[i]));
+           if (! (0 <= len && len < sizeof rule - rulelen))
+             string_overflow ();
+           rulelen += len;
          }
 
-      if (rulelen == sizeof rule - 1)
-       string_overflow ();
-
       /* Add the rule to the bus.  */
       dbus_error_init (&derror);
       dbus_bus_add_match (connection, rule, &derror);
@@ -2119,7 +2139,7 @@ usage: (dbus-register-signal BUS SERVICE PATH INTERFACE SIGNAL HANDLER &rest ARG
 
   /* Create a hash table entry.  */
   key = list3 (bus, interface, signal);
-  key1 = list4 (uname, service, path, handler);
+  key1 = list5 (uname, service, path, handler, build_string (rule));
   value = Fgethash (key, Vdbus_registered_objects_table, Qnil);
 
   if (NILP (Fmember (key1, value)))
@@ -2142,16 +2162,19 @@ DONT-REGISTER-SERVICE below).
 
 PATH is the D-Bus object path SERVICE is registered (See discussion of
 DONT-REGISTER-SERVICE below).  INTERFACE is the interface offered by
-SERVICE.  It must provide METHOD.  HANDLER is a Lisp function to be
-called when a method call is received.  It must accept the input
-arguments of METHOD.  The return value of HANDLER is used for
-composing the returning D-Bus message.
+SERVICE.  It must provide METHOD.
+
+HANDLER is a Lisp function to be called when a method call is
+received.  It must accept the input arguments of METHOD.  The return
+value of HANDLER is used for composing the returning D-Bus message.
+In case HANDLER shall return a reply message with an empty argument
+list, HANDLER must return the symbol `:ignore'.
 
 When DONT-REGISTER-SERVICE is non-nil, the known name SERVICE is not
 registered.  This means that other D-Bus clients have no way of
 noticing the newly registered method.  When interfaces are constructed
 incrementally by adding single methods or properties at a time,
-DONT-REGISTER-SERVICE can be use to prevent other clients from
+DONT-REGISTER-SERVICE can be used to prevent other clients from
 discovering the still incomplete interface.*/)
   (Lisp_Object bus, Lisp_Object service, Lisp_Object path,
    Lisp_Object interface, Lisp_Object method, Lisp_Object handler,
@@ -2293,6 +2316,9 @@ be called when a D-Bus message, which matches the key criteria,
 arrives (methods and signals), or a cons cell containing the value of
 the property.
 
+For signals, there is also a fifth element RULE, which keeps the match
+string the signal is registered with.
+
 In the second case, the key in the hash table is the list (BUS
 SERIAL).  BUS is either a Lisp symbol, `:system' or `:session', or a
 string denoting the bus address.  SERIAL is the serial number of the