diff options
| author | Michael Albinus | 2026-01-17 11:40:31 +0100 |
|---|---|---|
| committer | Michael Albinus | 2026-01-17 11:40:31 +0100 |
| commit | ab77b4b60ca1837e2da5147e6604cd2020567b80 (patch) | |
| tree | 2904dc0a52c8c96bc44efca75dec15b2d250a114 /src | |
| parent | 6287637ccd9f66a219844231380ab9873d049c6e (diff) | |
| download | emacs-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')
| -rw-r--r-- | src/dbusbind.c | 109 |
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. */ | ||
| 1625 | static Lisp_Object xd_registered_inhibitor_locks; | ||
| 1626 | |||
| 1627 | DEFUN ("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 | |||
| 1632 | WHAT 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 | |||
| 1636 | WHY is a descriptive string of why the lock is taken. Example: "Package | ||
| 1637 | Update in Progress". | ||
| 1638 | |||
| 1639 | The optional BLOCK is the mode of the inhibitor lock, either "block" | ||
| 1640 | (BLOCK is non-nil), or "delay". | ||
| 1641 | |||
| 1642 | It returns a file descriptor or nil, if the lock cannot be acquired. If | ||
| 1643 | there is already an inhibitor lock for the triple (WHAT WHY BLOCK), this | ||
| 1644 | lock is returned. | ||
| 1645 | |||
| 1646 | For 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 | |||
| 1676 | DEFUN ("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 | |||
| 1681 | LOCK, a file descriptor, must be the result of a `dbus-make-inhibitor-lock' | ||
| 1682 | call. It returns t in case of success, or nil if it isn't be possible | ||
| 1683 | to close the lock, or if the lock is closed already. | ||
| 1684 | |||
| 1685 | For 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 | |||
| 1702 | DEFUN ("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. | ||
| 1706 | This allows to check, whether other packages of the running Emacs | ||
| 1707 | instance have acquired an inhibitor lock as well. | ||
| 1708 | An entry in this list is a list (FD WHAT WHY BLOCK). | ||
| 1709 | The car of the list is the file descriptor retrieved from a | ||
| 1710 | 'dbus-make-inhibitor-lock` call. The cdr of the list represents the | ||
| 1711 | three 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. */ |
| 1621 | static void | 1724 | static void |
| 1622 | xd_store_event (Lisp_Object handler, Lisp_Object handler_args, | 1725 | xd_store_event (Lisp_Object handler, Lisp_Object handler_args, |
| @@ -1869,6 +1972,7 @@ static void | |||
| 1869 | syms_of_dbusbind_for_pdumper (void) | 1972 | syms_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 | ||
| 1874 | void | 1978 | void |
| @@ -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 | } |