aboutsummaryrefslogtreecommitdiffstats
path: root/src/dbusbind.c
diff options
context:
space:
mode:
authorMichael Albinus2026-01-17 11:40:31 +0100
committerMichael Albinus2026-01-17 11:40:31 +0100
commitab77b4b60ca1837e2da5147e6604cd2020567b80 (patch)
tree2904dc0a52c8c96bc44efca75dec15b2d250a114 /src/dbusbind.c
parent6287637ccd9f66a219844231380ab9873d049c6e (diff)
downloademacs-ab77b4b60ca1837e2da5147e6604cd2020567b80.tar.gz
emacs-ab77b4b60ca1837e2da5147e6604cd2020567b80.zip
New D-Bus functions to support systemd inhibitor locks
* doc/misc/dbus.texi (Top): Add "Inhibitor Locks" submenu. Remove trailing period from chapter and section titles. (Inhibitor Locks): New node. * etc/NEWS: New D-Bus functions to support systemd inhibitor locks. Presentational fixes and improvements. * src/dbusbind.c (xd_registered_inhibitor_locks): New variable. (Fdbus_make_inhibitor_lock, Fdbus_close_inhibitor_lock) (Fdbus_registered_inhibitor_locks): New DEFUNs. (Bug#79963) (syms_of_dbusbind_for_pdumper): Initialize `xd_registered_inhibitor_locks'. (syms_of_dbusbind): Declare subroutines `Sdbus_make_inhibitor_lock', `Sdbus_close_inhibitor_lock' and `Sdbus_registered_inhibitor_locks'. Declare symbol `Qdbus_call_method'. staticpro `xd_registered_inhibitor_locks'. * test/lisp/net/dbus-tests.el (dbus--test-systemd-service) (dbus--test-systemd-path, dbus--test-systemd-manager-interface): New defconsts. (dbus-test10-inhibitor-locks): New test.
Diffstat (limited to 'src/dbusbind.c')
-rw-r--r--src/dbusbind.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/dbusbind.c b/src/dbusbind.c
index a2936011610..a416e6c918a 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -1617,6 +1617,109 @@ usage: (dbus-message-internal &rest REST) */)
1617 return result; 1617 return result;
1618} 1618}
1619 1619
1620/* Alist of registered inhibitor locks for D-Bus.
1621 An entry in this list is a list (FD WHAT WHY BLOCK).
1622 The car of the list is a file descriptor retrieved from a
1623 'dbus-make-inhibitor-lock` call. The cdr of the list represents the
1624 three arguments 'dbus-make-inhibitor-lock` was called with. */
1625static Lisp_Object xd_registered_inhibitor_locks;
1626
1627DEFUN ("dbus-make-inhibitor-lock", Fdbus_make_inhibitor_lock,
1628 Sdbus_make_inhibitor_lock,
1629 2, 3, 0,
1630 doc: /* Inhibit system shutdowns and sleep states.
1631
1632WHAT is a colon-separated string of lock types, i.e. "shutdown",
1633"sleep", "idle", "handle-power-key", "handle-suspend-key",
1634"handle-hibernate-key", "handle-lid-switch". Example: "shutdown:idle".
1635
1636WHY is a descriptive string of why the lock is taken. Example: "Package
1637Update in Progress".
1638
1639The optional BLOCK is the mode of the inhibitor lock, either "block"
1640(BLOCK is non-nil), or "delay".
1641
1642It returns a file descriptor or nil, if the lock cannot be acquired. If
1643there is already an inhibitor lock for the triple (WHAT WHY BLOCK), this
1644lock is returned.
1645
1646For details of the arguments, see Info node `(dbus)Inhibitor Locks'. */)
1647 (Lisp_Object what, Lisp_Object why, Lisp_Object block)
1648{
1649 CHECK_STRING (what);
1650 CHECK_STRING (why);
1651 if (!NILP (block))
1652 block = Qt;
1653 Lisp_Object who = build_string ("Emacs");
1654 Lisp_Object mode =
1655 (NILP (block)) ? build_string ("delay") : build_string ("block");
1656
1657 /* Check, whether it is registered already. */
1658 Lisp_Object triple = list3 (what, why, block);
1659 Lisp_Object registered = Frassoc (triple, xd_registered_inhibitor_locks);
1660 if (!NILP (registered))
1661 return CAR_SAFE (registered);
1662
1663 /* Register lock. */
1664 Lisp_Object lock =
1665 calln (Qdbus_call_method, QCsystem,
1666 build_string ("org.freedesktop.login1"),
1667 build_string ("/org/freedesktop/login1"),
1668 build_string ("org.freedesktop.login1.Manager"),
1669 build_string ("Inhibit"), what, who, why, mode);
1670
1671 xd_registered_inhibitor_locks =
1672 Fcons (Fcons (lock, triple), xd_registered_inhibitor_locks);
1673 return lock;
1674}
1675
1676DEFUN ("dbus-close-inhibitor-lock", Fdbus_close_inhibitor_lock,
1677 Sdbus_close_inhibitor_lock,
1678 1, 1, 0,
1679 doc: /* Close inhibitor lock file descriptor.
1680
1681LOCK, a file descriptor, must be the result of a `dbus-make-inhibitor-lock'
1682call. It returns t in case of success, or nil if it isn't be possible
1683to close the lock, or if the lock is closed already.
1684
1685For details, see Info node `(dbus)Inhibitor Locks'. */)
1686 (Lisp_Object lock)
1687{
1688 CHECK_FIXNUM (lock);
1689
1690 /* Check, whether it is registered. */
1691 Lisp_Object registered = assoc_no_quit (lock, xd_registered_inhibitor_locks);
1692 if (NILP (registered))
1693 return Qnil;
1694 else
1695 {
1696 xd_registered_inhibitor_locks =
1697 Fdelete (registered, xd_registered_inhibitor_locks);
1698 return (emacs_close (XFIXNAT (lock)) == 0) ? Qt : Qnil;
1699 }
1700}
1701
1702DEFUN ("dbus-registered-inhibitor-locks", Fdbus_registered_inhibitor_locks,
1703 Sdbus_registered_inhibitor_locks,
1704 0, 0, 0,
1705 doc: /* Return registered inhibitor locks, an alist.
1706This allows to check, whether other packages of the running Emacs
1707instance have acquired an inhibitor lock as well.
1708An entry in this list is a list (FD WHAT WHY BLOCK).
1709The car of the list is the file descriptor retrieved from a
1710'dbus-make-inhibitor-lock` call. The cdr of the list represents the
1711three arguments 'dbus-make-inhibitor-lock` was called with. */)
1712 ()
1713{
1714 /* We return a copy of xd_registered_inhibitor_locks, in order to
1715 protect it against malicious manipulation. */
1716 Lisp_Object registered = xd_registered_inhibitor_locks;
1717 Lisp_Object result = Qnil;
1718 for (; !NILP (registered); registered = CDR_SAFE (registered))
1719 result = Fcons (Fcopy_sequence (CAR_SAFE (registered)), result);
1720 return Fnreverse (result);
1721}
1722
1620/* Construct a D-Bus event, and store it into the input event queue. */ 1723/* Construct a D-Bus event, and store it into the input event queue. */
1621static void 1724static void
1622xd_store_event (Lisp_Object handler, Lisp_Object handler_args, 1725xd_store_event (Lisp_Object handler, Lisp_Object handler_args,
@@ -1869,6 +1972,7 @@ static void
1869syms_of_dbusbind_for_pdumper (void) 1972syms_of_dbusbind_for_pdumper (void)
1870{ 1973{
1871 xd_registered_buses = Qnil; 1974 xd_registered_buses = Qnil;
1975 xd_registered_inhibitor_locks = Qnil;
1872} 1976}
1873 1977
1874void 1978void
@@ -1876,6 +1980,9 @@ syms_of_dbusbind (void)
1876{ 1980{
1877 defsubr (&Sdbus__init_bus); 1981 defsubr (&Sdbus__init_bus);
1878 defsubr (&Sdbus_get_unique_name); 1982 defsubr (&Sdbus_get_unique_name);
1983 defsubr (&Sdbus_make_inhibitor_lock);
1984 defsubr (&Sdbus_close_inhibitor_lock);
1985 defsubr (&Sdbus_registered_inhibitor_locks);
1879 1986
1880 DEFSYM (Qdbus_message_internal, "dbus-message-internal"); 1987 DEFSYM (Qdbus_message_internal, "dbus-message-internal");
1881 defsubr (&Sdbus_message_internal); 1988 defsubr (&Sdbus_message_internal);
@@ -1930,6 +2037,7 @@ syms_of_dbusbind (void)
1930 2037
1931 /* Miscellaneous Lisp symbols. */ 2038 /* Miscellaneous Lisp symbols. */
1932 DEFSYM (Qdbus_get_name_owner, "dbus-get-name-owner"); 2039 DEFSYM (Qdbus_get_name_owner, "dbus-get-name-owner");
2040 DEFSYM (Qdbus_call_method, "dbus-call-method");
1933 2041
1934 DEFVAR_LISP ("dbus-compiled-version", 2042 DEFVAR_LISP ("dbus-compiled-version",
1935 Vdbus_compiled_version, 2043 Vdbus_compiled_version,
@@ -2035,6 +2143,7 @@ be called when the D-Bus reply message arrives. */);
2035 /* Initialize internal objects. */ 2143 /* Initialize internal objects. */
2036 pdumper_do_now_and_after_load (syms_of_dbusbind_for_pdumper); 2144 pdumper_do_now_and_after_load (syms_of_dbusbind_for_pdumper);
2037 staticpro (&xd_registered_buses); 2145 staticpro (&xd_registered_buses);
2146 staticpro (&xd_registered_inhibitor_locks);
2038 2147
2039 Fprovide (intern_c_string ("dbusbind"), Qnil); 2148 Fprovide (intern_c_string ("dbusbind"), Qnil);
2040} 2149}