aboutsummaryrefslogtreecommitdiffstats
path: root/src/dbusbind.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dbusbind.c')
-rw-r--r--src/dbusbind.c188
1 files changed, 105 insertions, 83 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c
index cb705e9e92a..60ac38b5479 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -129,6 +129,8 @@ static bool xd_in_read_queued_messages = 0;
129#endif 129#endif
130 130
131/* Check whether TYPE is a basic DBusType. */ 131/* Check whether TYPE is a basic DBusType. */
132/* TODO: Shouldn't we assume, that recent D-Bus implementations carry
133 HAVE_DBUS_TYPE_IS_VALID and DBUS_TYPE_UNIX_FD? See configure.ac. */
132#ifdef HAVE_DBUS_TYPE_IS_VALID 134#ifdef HAVE_DBUS_TYPE_IS_VALID
133#define XD_BASIC_DBUS_TYPE(type) \ 135#define XD_BASIC_DBUS_TYPE(type) \
134 (dbus_type_is_valid (type) && dbus_type_is_basic (type)) 136 (dbus_type_is_valid (type) && dbus_type_is_basic (type))
@@ -310,6 +312,8 @@ XD_OBJECT_TO_STRING (Lisp_Object object)
310 } \ 312 } \
311 } while (0) 313 } while (0)
312 314
315/* TODO: Shouldn't we assume, that recent D-Bus implementations carry
316 HAVE_DBUS_VALIDATE_*? See configure.ac. */
313#if (HAVE_DBUS_VALIDATE_BUS_NAME || HAVE_DBUS_VALIDATE_PATH \ 317#if (HAVE_DBUS_VALIDATE_BUS_NAME || HAVE_DBUS_VALIDATE_PATH \
314 || HAVE_DBUS_VALIDATE_INTERFACE || HAVE_DBUS_VALIDATE_MEMBER) 318 || HAVE_DBUS_VALIDATE_INTERFACE || HAVE_DBUS_VALIDATE_MEMBER)
315#define XD_DBUS_VALIDATE_OBJECT(object, func) \ 319#define XD_DBUS_VALIDATE_OBJECT(object, func) \
@@ -1044,6 +1048,8 @@ xd_get_connection_address (Lisp_Object bus)
1044} 1048}
1045 1049
1046/* Return the file descriptor for WATCH, -1 if not found. */ 1050/* Return the file descriptor for WATCH, -1 if not found. */
1051/* TODO: Shouldn't we assume, that recent D-Bus implementations carry
1052 HAVE_DBUS_WATCH_GET_UNIX_FD? See configure.ac. */
1047static int 1053static int
1048xd_find_watch_fd (DBusWatch *watch) 1054xd_find_watch_fd (DBusWatch *watch)
1049{ 1055{
@@ -1372,6 +1378,7 @@ usage: (dbus-message-internal &rest REST) */)
1372 dbus_uint32_t serial = 0; 1378 dbus_uint32_t serial = 0;
1373 unsigned int ui_serial; 1379 unsigned int ui_serial;
1374 int timeout = -1; 1380 int timeout = -1;
1381 dbus_bool_t keepfd = FALSE;
1375 ptrdiff_t count, count0; 1382 ptrdiff_t count, count0;
1376 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH]; 1383 char signature[DBUS_MAXIMUM_SIGNATURE_LENGTH];
1377 1384
@@ -1548,6 +1555,7 @@ usage: (dbus-message-internal &rest REST) */)
1548 timeout = min (XFIXNAT (args[count+1]), INT_MAX); 1555 timeout = min (XFIXNAT (args[count+1]), INT_MAX);
1549 count = count + 2; 1556 count = count + 2;
1550 } 1557 }
1558
1551 /* Check for authorizable parameter. */ 1559 /* Check for authorizable parameter. */
1552 else if (EQ (args[count], QCauthorizable)) 1560 else if (EQ (args[count], QCauthorizable))
1553 { 1561 {
@@ -1565,6 +1573,24 @@ usage: (dbus-message-internal &rest REST) */)
1565 1573
1566 count = count + 2; 1574 count = count + 2;
1567 } 1575 }
1576
1577 /* Check for keepfd parameter. */
1578 else if (EQ (args[count], QCkeep_fd))
1579 {
1580 if (mtype != DBUS_MESSAGE_TYPE_METHOD_CALL)
1581 XD_SIGNAL1
1582 (build_string (":keep-fd is only supported on method calls"));
1583
1584 /* Ignore this keyword if unsupported. */
1585#ifdef DBUS_TYPE_UNIX_FD
1586 keepfd = TRUE;
1587#else
1588 XD_DEBUG_MESSAGE (":keep-fd not supported");
1589#endif
1590
1591 ++count;
1592 }
1593
1568 else break; 1594 else break;
1569 1595
1570 } 1596 }
@@ -1618,7 +1644,8 @@ usage: (dbus-message-internal &rest REST) */)
1618 result = list3 (QCserial, bus, INT_TO_INTEGER (serial)); 1644 result = list3 (QCserial, bus, INT_TO_INTEGER (serial));
1619 1645
1620 /* Create a hash table entry. */ 1646 /* Create a hash table entry. */
1621 Fputhash (result, handler, Vdbus_registered_objects_table); 1647 Fputhash (result, keepfd ? Fcons (handler, path) : handler,
1648 Vdbus_registered_objects_table);
1622 } 1649 }
1623 else 1650 else
1624 { 1651 {
@@ -1640,106 +1667,81 @@ usage: (dbus-message-internal &rest REST) */)
1640 return result; 1667 return result;
1641} 1668}
1642 1669
1643/* Alist of registered inhibitor locks for D-Bus. 1670/* Alist of registered file descriptors for D-Bus.
1644 An entry in this list is a list (FD WHAT WHY BLOCK). 1671 The key is an open file descriptor, retrieved via `dbus-call-method'
1645 The car of the list is a file descriptor retrieved from a 1672 or `dbus--open-fd'. The value is a string OBJECT-PATH or FILENAME,
1646 'dbus-make-inhibitor-lock` call. The cdr of the list represents the 1673 which represents the arguments the function was called with. Those
1647 three arguments 'dbus-make-inhibitor-lock` was called with. */ 1674 values are not needed for further operations; they are just shown for
1648static Lisp_Object xd_registered_inhibitor_locks; 1675 information. */
1649 1676static Lisp_Object xd_registered_fds;
1650DEFUN ("dbus-make-inhibitor-lock", Fdbus_make_inhibitor_lock, 1677
1651 Sdbus_make_inhibitor_lock, 1678DEFUN ("dbus--fd-open", Fdbus__fd_open, Sdbus__fd_open, 1, 1, 0,
1652 2, 3, 0, 1679 doc: /* Open FILENAME and return the respective read-only file descriptor. */)
1653 doc: /* Inhibit system shutdowns and sleep states. 1680 (Lisp_Object filename)
1654
1655WHAT is a colon-separated string of lock types, i.e. "shutdown",
1656"sleep", "idle", "handle-power-key", "handle-suspend-key",
1657"handle-hibernate-key", "handle-lid-switch". Example: "shutdown:idle".
1658
1659WHY is a descriptive string of why the lock is taken. Example: "Package
1660Update in Progress".
1661
1662The optional BLOCK is the mode of the inhibitor lock, either "block"
1663(BLOCK is non-nil), or "delay".
1664
1665It returns a file descriptor or nil, if the lock cannot be acquired. If
1666there is already an inhibitor lock for the triple (WHAT WHY BLOCK), this
1667lock is returned.
1668
1669For details of the arguments, see Info node `(dbus)Inhibitor Locks'. */)
1670 (Lisp_Object what, Lisp_Object why, Lisp_Object block)
1671{ 1681{
1672 CHECK_STRING (what); 1682 CHECK_STRING (filename);
1673 CHECK_STRING (why); 1683 filename = Fexpand_file_name (filename, Qnil);
1674 if (!NILP (block)) 1684 filename = ENCODE_FILE (filename);
1675 block = Qt;
1676 Lisp_Object who = build_string ("Emacs");
1677 Lisp_Object mode =
1678 (NILP (block)) ? build_string ("delay") : build_string ("block");
1679 1685
1680 /* Check, whether it is registered already. */ 1686 /* Check, whether it is registered already. */
1681 Lisp_Object triple = list3 (what, why, block); 1687 Lisp_Object registered = Frassoc (filename, xd_registered_fds);
1682 Lisp_Object registered = Frassoc (triple, xd_registered_inhibitor_locks);
1683 if (!NILP (registered)) 1688 if (!NILP (registered))
1684 return CAR_SAFE (registered); 1689 return CAR_SAFE (registered);
1685 1690
1686 /* Register lock. */ 1691 /* Open file descriptor. */
1687 Lisp_Object lock = 1692 int fd = emacs_open (SSDATA (filename), O_RDONLY, 0);
1688 calln (Qdbus_call_method, QCsystem,
1689 build_string ("org.freedesktop.login1"),
1690 build_string ("/org/freedesktop/login1"),
1691 build_string ("org.freedesktop.login1.Manager"),
1692 build_string ("Inhibit"), what, who, why, mode);
1693
1694 xd_registered_inhibitor_locks =
1695 Fcons (Fcons (lock, triple), xd_registered_inhibitor_locks);
1696 return lock;
1697}
1698 1693
1699DEFUN ("dbus-close-inhibitor-lock", Fdbus_close_inhibitor_lock, 1694 if (fd <= 0)
1700 Sdbus_close_inhibitor_lock, 1695 XD_SIGNAL2 (build_string ("Cannot open file"), filename);
1701 1, 1, 0,
1702 doc: /* Close inhibitor lock file descriptor.
1703 1696
1704LOCK, a file descriptor, must be the result of a `dbus-make-inhibitor-lock' 1697 /* Register file descriptor. */
1705call. It returns t in case of success, or nil if it isn't be possible 1698 xd_registered_fds =
1706to close the lock, or if the lock is closed already. 1699 Fcons (Fcons (INT_TO_INTEGER (fd), filename), xd_registered_fds);
1700 return INT_TO_INTEGER (fd);
1701}
1707 1702
1708For details, see Info node `(dbus)Inhibitor Locks'. */) 1703DEFUN ("dbus--fd-close", Fdbus__fd_close, Sdbus__fd_close, 1, 1, 0,
1709 (Lisp_Object lock) 1704 doc: /* Close file descriptor FD.
1705FD must be the result of a `dbus-call-method' or `dbus--fd-open' call,
1706see `dbus--registered-fds'. It returns t in case of success, or nil if
1707it isn't be possible to close the file descriptor, or if the file
1708descriptor is closed already. */)
1709 (Lisp_Object fd)
1710{ 1710{
1711 CHECK_FIXNUM (lock); 1711 CHECK_FIXNUM (fd);
1712 1712
1713 /* Check, whether it is registered. */ 1713 /* Check, whether it is registered. */
1714 Lisp_Object registered = assoc_no_quit (lock, xd_registered_inhibitor_locks); 1714 Lisp_Object registered = assoc_no_quit (fd, xd_registered_fds);
1715 if (NILP (registered)) 1715 if (NILP (registered))
1716 return Qnil; 1716 return Qnil;
1717 else 1717 else
1718 { 1718 {
1719 xd_registered_inhibitor_locks = 1719 xd_registered_fds = Fdelete (registered, xd_registered_fds);
1720 Fdelete (registered, xd_registered_inhibitor_locks); 1720 return (emacs_close (XFIXNAT (fd)) == 0) ? Qt : Qnil;
1721 return (emacs_close (XFIXNAT (lock)) == 0) ? Qt : Qnil;
1722 } 1721 }
1723} 1722}
1724 1723
1725DEFUN ("dbus-registered-inhibitor-locks", Fdbus_registered_inhibitor_locks, 1724DEFUN ("dbus--registered-fds", Fdbus__registered_fds, Sdbus__registered_fds,
1726 Sdbus_registered_inhibitor_locks,
1727 0, 0, 0, 1725 0, 0, 0,
1728 doc: /* Return registered inhibitor locks, an alist. 1726 doc: /* Return registered file descriptors, an alist.
1729This allows to check, whether other packages of the running Emacs 1727The key is an open file descriptor, retrieved via `dbus-call-method' or
1730instance have acquired an inhibitor lock as well. 1728`dbus--open-fd'. The value is a string OBJECT-PATH or FILENAME, which
1731An entry in this list is a list (FD WHAT WHY BLOCK). 1729represents the arguments the function was called with. Those values are
1732The car of the list is the file descriptor retrieved from a 1730not needed for further operations; they are just shown for information.
1733'dbus-make-inhibitor-lock` call. The cdr of the list represents the 1731
1734three arguments 'dbus-make-inhibitor-lock` was called with. */) 1732This alist allows to check, whether other packages of the running Emacs
1733instance have acquired a file descriptor as well. */)
1735 (void) 1734 (void)
1736{ 1735{
1737 /* We return a copy of xd_registered_inhibitor_locks, in order to 1736 /* We return a copy of xd_registered_fds, in order to protect it
1738 protect it against malicious manipulation. */ 1737 against malicious manipulation. */
1739 Lisp_Object registered = xd_registered_inhibitor_locks; 1738 Lisp_Object registered = xd_registered_fds;
1740 Lisp_Object result = Qnil; 1739 Lisp_Object result = Qnil;
1741 for (; !NILP (registered); registered = CDR_SAFE (registered)) 1740 for (; !NILP (registered); registered = CDR_SAFE (registered))
1742 result = Fcons (Fcopy_sequence (CAR_SAFE (registered)), result); 1741 {
1742 Lisp_Object tem = CAR_SAFE (registered);
1743 result = Fcons (Fcons (CAR_SAFE (tem), CDR_SAFE (tem)), result);
1744 }
1743 return Fnreverse (result); 1745 return Fnreverse (result);
1744} 1746}
1745 1747
@@ -1859,7 +1861,22 @@ xd_read_message_1 (DBusConnection *connection, Lisp_Object bus)
1859 Fremhash (key, Vdbus_registered_objects_table); 1861 Fremhash (key, Vdbus_registered_objects_table);
1860 1862
1861 /* Store the event. */ 1863 /* Store the event. */
1862 xd_store_event (value, args, event_args); 1864 xd_store_event (CONSP (value) ? CAR_SAFE (value) : value, args, event_args);
1865
1866#ifdef DBUS_TYPE_UNIX_FD
1867 /* Check, whether there is a file descriptor to be kept.
1868 value is (handler . path)
1869 args is ((:unix-fd NN) ...) */
1870 if (CONSP (value)
1871 && CONSP (CAR_SAFE (args))
1872 && EQ (CAR_SAFE (CAR_SAFE (args)), QCunix_fd))
1873 {
1874 xd_registered_fds =
1875 Fcons (Fcons (CAR_SAFE (CDR_SAFE (CAR_SAFE (args))),
1876 CDR_SAFE (value)),
1877 xd_registered_fds);
1878 }
1879#endif
1863 } 1880 }
1864 1881
1865 else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */ 1882 else /* DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_SIGNAL. */
@@ -1995,7 +2012,7 @@ static void
1995syms_of_dbusbind_for_pdumper (void) 2012syms_of_dbusbind_for_pdumper (void)
1996{ 2013{
1997 xd_registered_buses = Qnil; 2014 xd_registered_buses = Qnil;
1998 xd_registered_inhibitor_locks = Qnil; 2015 xd_registered_fds = Qnil;
1999} 2016}
2000 2017
2001void 2018void
@@ -2003,9 +2020,9 @@ syms_of_dbusbind (void)
2003{ 2020{
2004 defsubr (&Sdbus__init_bus); 2021 defsubr (&Sdbus__init_bus);
2005 defsubr (&Sdbus_get_unique_name); 2022 defsubr (&Sdbus_get_unique_name);
2006 defsubr (&Sdbus_make_inhibitor_lock); 2023 defsubr (&Sdbus__fd_open);
2007 defsubr (&Sdbus_close_inhibitor_lock); 2024 defsubr (&Sdbus__fd_close);
2008 defsubr (&Sdbus_registered_inhibitor_locks); 2025 defsubr (&Sdbus__registered_fds);
2009 2026
2010 DEFSYM (Qdbus_message_internal, "dbus-message-internal"); 2027 DEFSYM (Qdbus_message_internal, "dbus-message-internal");
2011 defsubr (&Sdbus_message_internal); 2028 defsubr (&Sdbus_message_internal);
@@ -2030,6 +2047,11 @@ syms_of_dbusbind (void)
2030 /* Lisp symbol for method interactive authorization. */ 2047 /* Lisp symbol for method interactive authorization. */
2031 DEFSYM (QCauthorizable, ":authorizable"); 2048 DEFSYM (QCauthorizable, ":authorizable");
2032 2049
2050 /* Lisp symbol for file descriptor kept. */
2051#ifdef DBUS_TYPE_UNIX_FD
2052 DEFSYM (QCkeep_fd, ":keep-fd");
2053#endif
2054
2033 /* Lisp symbols of D-Bus types. */ 2055 /* Lisp symbols of D-Bus types. */
2034 DEFSYM (QCbyte, ":byte"); 2056 DEFSYM (QCbyte, ":byte");
2035 DEFSYM (QCboolean, ":boolean"); 2057 DEFSYM (QCboolean, ":boolean");
@@ -2166,7 +2188,7 @@ be called when the D-Bus reply message arrives. */);
2166 /* Initialize internal objects. */ 2188 /* Initialize internal objects. */
2167 pdumper_do_now_and_after_load (syms_of_dbusbind_for_pdumper); 2189 pdumper_do_now_and_after_load (syms_of_dbusbind_for_pdumper);
2168 staticpro (&xd_registered_buses); 2190 staticpro (&xd_registered_buses);
2169 staticpro (&xd_registered_inhibitor_locks); 2191 staticpro (&xd_registered_fds);
2170 2192
2171 Fprovide (intern_c_string ("dbusbind"), Qnil); 2193 Fprovide (intern_c_string ("dbusbind"), Qnil);
2172} 2194}