guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Nicolas Graves] [PATCH v6 01/10] rde: emacs: Start emacs in --daemo


From: Nicolas Graves
Subject: Re: [Nicolas Graves] [PATCH v6 01/10] rde: emacs: Start emacs in --daemon mode, with shepherd and pid-file
Date: Sat, 11 May 2024 22:15:27 +0200

On 2024-04-13 11:16, Stefan Monnier wrote:

>> Maybe some feedback on the Emacs side about this? There are indeed very
>> few places where systemd sd_* functions are called in emacs.c, should we
>> try and re-implement them instead of using the library as is? Would that
>> be a contribution Emacs devs would be interested in? That would
>> definitely be beneficial for Emacs on Guix as highlighted by Ludo'.
>
> It's hard to tell without seeing the actual patch.

Seems to work properly on my side with the following patch, on Guix with
the shepherd service I sent a few weeks ago. The patch is actually
pretty simple.

Some choices :

- I removed most of the code in former function sd_listen_fds' upstream
source code, because it didn't seem related to integration functionality
with emacs but rather to systemd inner workings. Some edge cases might
not be as well covered (strtol with defaults instead of systemd's
safe_atoi), but it works on my side. The functionality is directly
integrated in emacs.c rather than the function itself reproduced.

- I simplified the sd_is_socket function to instead use the upstream
untouched sd_is_socket_internal function. This is because the default
family argument was set in emacs.c.

- The sd_notify code is taken from
https://www.freedesktop.org/software/systemd/man/devel/sd_notify.html#Notes

Disclaimer : I'm not a seasoned C nor emacs developer, some things are
probably odd, but I would need for feedback to make things more emacsy /
rigorous in C.

>From c9f3af7dc4accc4da352ef8ffdb95478bcf2bd16 Mon Sep 17 00:00:00 2001
From: Nicolas Graves <ngraves@ngraves.fr>
Date: Sat, 13 Apr 2024 19:37:34 +0200
Subject: [PATCH] Implement systemd socket.

---
 configure.ac     |  19 +-----
 lib/Makefile.in  |   2 +-
 lib/gnulib.mk.in |   2 -
 lib/sd-socket.c  | 149 +++++++++++++++++++++++++++++++++++++++++++++++
 lib/sd-socket.h  | 127 ++++++++++++++++++++++++++++++++++++++++
 msdos/sed1v2.inp |   3 -
 src/Makefile.in  |   9 +--
 src/deps.mk      |   2 +-
 src/emacs.c      |  50 ++++++++--------
 9 files changed, 308 insertions(+), 55 deletions(-)
 create mode 100644 lib/sd-socket.c
 create mode 100644 lib/sd-socket.h

diff --git a/configure.ac b/configure.ac
index 29b71ea2730..a245a7b5ccc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -457,7 +457,6 @@ AC_DEFUN
 OPTION_DEFAULT_ON([webp],[don't compile with WebP image support])
 OPTION_DEFAULT_ON([sqlite3],[don't compile with sqlite3 support])
 OPTION_DEFAULT_ON([lcms2],[don't compile with Little CMS support])
-OPTION_DEFAULT_ON([libsystemd],[don't compile with libsystemd support])
 OPTION_DEFAULT_ON([cairo],[don't compile with Cairo drawing])
 OPTION_DEFAULT_OFF([cairo-xcb], [use XCB surfaces for Cairo support])
 OPTION_DEFAULT_ON([xml2],[don't compile with XML parsing support])
@@ -3203,21 +3202,6 @@ AC_DEFUN
 AC_SUBST([LIBGNUTLS_LIBS])
 AC_SUBST([LIBGNUTLS_CFLAGS])
 
-HAVE_LIBSYSTEMD=no
-if test "${with_libsystemd}" = "yes" ; then
-  dnl This code has been tested with libsystemd 222 and later.
-  dnl FIXME: Find the earliest version number for which Emacs should work,
-  dnl and change '222' to that number.
-  EMACS_CHECK_MODULES([LIBSYSTEMD], [libsystemd >= 222],
-    [HAVE_LIBSYSTEMD=yes], [HAVE_LIBSYSTEMD=no])
-  if test "${HAVE_LIBSYSTEMD}" = "yes"; then
-    AC_DEFINE([HAVE_LIBSYSTEMD], [1], [Define if using libsystemd.])
-  fi
-fi
-
-AC_SUBST([LIBSYSTEMD_LIBS])
-AC_SUBST([LIBSYSTEMD_CFLAGS])
-
 HAVE_JSON=no
 JSON_OBJ=
 
@@ -6652,7 +6636,7 @@ AC_DEFUN
 optsep=
 emacs_config_features=
 for opt in ACL BE_APP CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM 
GSETTINGS \
- HARFBUZZ IMAGEMAGICK JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 \
+ HARFBUZZ IMAGEMAGICK JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBXML2 \
  M17N_FLT MODULES NATIVE_COMP NOTIFY NS OLDXMENU PDUMPER PGTK PNG RSVG SECCOMP 
\
  SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER \
  UNEXEC WEBP X11 XAW3D XDBE XFT XIM XINPUT2 XPM XWIDGETS X_TOOLKIT \
@@ -6721,7 +6705,6 @@ AC_DEFUN
   Does Emacs use -lm17n-flt?                              ${HAVE_M17N_FLT}
   Does Emacs use -lotf?                                   ${HAVE_LIBOTF}
   Does Emacs use -lxft?                                   ${HAVE_XFT}
-  Does Emacs use -lsystemd?                               ${HAVE_LIBSYSTEMD}
   Does Emacs use -ljansson?                               ${HAVE_JSON}
   Does Emacs use -ltree-sitter?                           ${HAVE_TREE_SITTER}
   Does Emacs use the GMP library?                         ${HAVE_GMP}
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 71199c32277..d934a755e85 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -74,7 +74,7 @@ Makefile:
 not_emacs_OBJECTS = regex.o malloc/%.o free.o
 
 libgnu_a_OBJECTS = fingerprint.o $(gl_LIBOBJS) \
-  $(patsubst %.c,%.o,$(filter %.c,$(libgnu_a_SOURCES)))
+  $(patsubst %.c,%.o,$(filter %.c,$(libgnu_a_SOURCES))) sd-socket.o
 for_emacs_OBJECTS = $(filter-out $(not_emacs_OBJECTS),$(libgnu_a_OBJECTS))
 libegnu_a_OBJECTS = $(patsubst %.o,e-%.o,$(for_emacs_OBJECTS))
 
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 9ab4b741595..f9ed4a4cb23 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -912,8 +912,6 @@ LIBSECCOMP_CFLAGS = @LIBSECCOMP_CFLAGS@
 LIBSECCOMP_LIBS = @LIBSECCOMP_LIBS@
 LIBSELINUX_LIBS = @LIBSELINUX_LIBS@
 LIBSOUND = @LIBSOUND@
-LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@
-LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@
 LIBS_ECLIENT = @LIBS_ECLIENT@
 LIBS_GNUSTEP = @LIBS_GNUSTEP@
 LIBS_MAIL = @LIBS_MAIL@
diff --git a/lib/sd-socket.c b/lib/sd-socket.c
new file mode 100644
index 00000000000..6350882006d
--- /dev/null
+++ b/lib/sd-socket.c
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/* Copied and adapted from systemd source code. */
+
+#define _GNU_SOURCE 1
+
+#include <assert.h>
+#include <config.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <mqueue.h>
+#include <netinet/in.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "sd-socket.h"
+#define _cleanup_(f) __attribute__((cleanup(f)))
+
+int sd_is_socket(int fd, int type, int listening) {
+        struct stat st_fd;
+
+        assert(fd >= 0);
+        assert(type >= 0);
+
+        if (fstat(fd, &st_fd) < 0)
+                return -errno;
+
+        if (!S_ISSOCK(st_fd.st_mode))
+                return 0;
+
+        if (type != 0) {
+                int other_type = 0;
+                socklen_t l = sizeof(other_type);
+
+                if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0)
+                        return -errno;
+
+                if (l != sizeof(other_type))
+                        return -EINVAL;
+
+                if (other_type != type)
+                        return 0;
+        }
+
+        if (listening >= 0) {
+                int accepting = 0;
+                socklen_t l = sizeof(accepting);
+
+                if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) 
< 0)
+                        return -errno;
+
+                if (l != sizeof(accepting))
+                        return -EINVAL;
+
+                if (!accepting != !listening)
+                        return 0;
+        }
+
+        return 1;
+}
+
+/* SPDX-License-Identifier: MIT-0 */
+
+/* Implement the systemd notify protocol without external dependencies.
+ * Supports both readiness notification on startup and on reloading,
+ * according to the protocol defined at:
+ * https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html
+ * This protocol is guaranteed to be stable as per:
+ * https://systemd.io/PORTABILITY_AND_STABILITY/ */
+
+static void closep(int *fd) {
+  if (!fd || *fd < 0)
+    return;
+
+  close(*fd);
+  *fd = -1;
+}
+
+static int sd_notify(const char *message) {
+  union sockaddr_union {
+    struct sockaddr sa;
+    struct sockaddr_un sun;
+  } socket_addr = {
+    .sun.sun_family = AF_UNIX,
+  };
+  size_t path_length, message_length;
+  _cleanup_(closep) int fd = -1;
+  const char *socket_path;
+
+  /* Verify the argument first */
+  if (!message)
+    return -EINVAL;
+
+  message_length = strlen(message);
+  if (message_length == 0)
+    return -EINVAL;
+
+  /* If the variable is not set, the protocol is a noop */
+  socket_path = getenv("NOTIFY_SOCKET");
+  if (!socket_path)
+    return 0; /* Not set? Nothing to do */
+
+  /* Only AF_UNIX is supported, with path or abstract sockets */
+  if (socket_path[0] != '/' && socket_path[0] != '@')
+    return -EAFNOSUPPORT;
+
+  path_length = strlen(socket_path);
+  /* Ensure there is room for NUL byte */
+  if (path_length >= sizeof(socket_addr.sun.sun_path))
+    return -E2BIG;
+
+  memcpy(socket_addr.sun.sun_path, socket_path, path_length);
+
+  /* Support for abstract socket */
+  if (socket_addr.sun.sun_path[0] == '@')
+    socket_addr.sun.sun_path[0] = 0;
+
+  fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+  if (fd < 0)
+    return -errno;
+
+  if (connect(fd, &socket_addr.sa, offsetof(struct sockaddr_un, sun_path) + 
path_length) != 0)
+    return -errno;
+
+  ssize_t written = write(fd, message, message_length);
+  if (written != (ssize_t) message_length)
+    return written < 0 ? -errno : -EPROTO;
+
+  return 1; /* Notified! */
+}
+
+int sd_notify_ready(void) {
+  return sd_notify("READY=1");
+}
+
+int sd_notify_stopping(void) {
+  return sd_notify("STOPPING=1");
+}
diff --git a/lib/sd-socket.h b/lib/sd-socket.h
new file mode 100644
index 00000000000..31450c731e9
--- /dev/null
+++ b/lib/sd-socket.h
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/* Copied and adapted from systemd source code. */
+#ifndef _SD_SOCKET_H
+#define _SD_SOCKET_H 1
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/*
+  The following functionality is provided:
+
+  - Support for logging with log levels on stderr
+  - File descriptor passing for socket-based activation
+  - Daemon startup and status notification
+  - Detection of systemd boots
+
+  See sd-daemon(3) for more information.
+*/
+
+/* The first passed file descriptor is fd 3 */
+#define SD_LISTEN_FDS_START 3
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is a socket of type (SOCK_DGRAM, SOCK_STREAM,
+  ...), 0 otherwise. If type is 0 a socket type check will not be done
+  and the call only verifies if the file descriptor refers to a
+  socket. If listening is > 0 it is verified that the socket is in
+  listening mode. (i.e. listen() has been called) If listening is == 0
+  it is verified that the socket is not in listening mode. If
+  listening is < 0 no listening mode check is done. Returns a negative
+  errno style error code on failure.
+
+  See sd_is_socket(3) for more information.
+*/
+int sd_is_socket(int fd, int type, int listening);
+
+/*
+  Informs systemd about changed daemon state. This takes a number of
+  newline separated environment-style variable assignments in a
+  string. The following variables are known:
+
+     MAINPID=...  The main PID of a daemon, in case systemd did not
+                  fork off the process itself. Example: "MAINPID=4711"
+
+     READY=1      Tells systemd that daemon startup or daemon reload
+                  is finished (only relevant for services of Type=notify).
+                  The passed argument is a boolean "1" or "0". Since there
+                  is little value in signaling non-readiness the only
+                  value daemons should send is "READY=1".
+
+     RELOADING=1  Tell systemd that the daemon began reloading its
+                  configuration. When the configuration has been
+                  reloaded completely, READY=1 should be sent to inform
+                  systemd about this.
+
+     STOPPING=1   Tells systemd that the daemon is about to go down.
+
+     STATUS=...   Passes a single-line status string back to systemd
+                  that describes the daemon state. This is free-form
+                  and can be used for various purposes: general state
+                  feedback, fsck-like programs could pass completion
+                  percentages and failing programs could pass a human
+                  readable error message. Example: "STATUS=Completed
+                  66% of file system check..."
+
+     NOTIFYACCESS=...
+                  Reset the access to the service status notification socket.
+                  Example: "NOTIFYACCESS=main"
+
+     ERRNO=...    If a daemon fails, the errno-style error code,
+                  formatted as string. Example: "ERRNO=2" for ENOENT.
+
+     BUSERROR=... If a daemon fails, the D-Bus error-style error
+                  code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut"
+
+     WATCHDOG=1   Tells systemd to update the watchdog timestamp.
+                  Services using this feature should do this in
+                  regular intervals. A watchdog framework can use the
+                  timestamps to detect failed services. Also see
+                  sd_watchdog_enabled() below.
+
+     WATCHDOG_USEC=...
+                  Reset watchdog_usec value during runtime.
+                  To reset watchdog_usec value, start the service again.
+                  Example: "WATCHDOG_USEC=20000000"
+
+     FDSTORE=1    Store the file descriptors passed along with the
+                  message in the per-service file descriptor store,
+                  and pass them to the main process again on next
+                  invocation. This variable is only supported with
+                  sd_pid_notify_with_fds().
+
+     FDSTOREREMOVE=1
+                  Remove one or more file descriptors from the file
+                  descriptor store, identified by the name specified
+                  in FDNAME=, see below.
+
+     FDNAME=      A name to assign to new file descriptors stored in the
+                  file descriptor store, or the name of the file descriptors
+                  to remove in case of FDSTOREREMOVE=1.
+
+  Daemons can choose to send additional variables. However, it is
+  recommended to prefix variable names not listed above with X_.
+
+  Returns a negative errno-style error code on failure. Returns > 0
+  if systemd could be notified, 0 if it couldn't possibly because
+  systemd is not running.
+
+  Example: When a daemon finished starting up, it could issue this
+  call to notify systemd about it:
+
+     sd_notify(0, "READY=1");
+
+  See sd_notifyf() for more complete examples.
+
+  See sd_notify(3) for more information.
+*/
+
+/* This is actually a simplified version that you can find right there :
+   https://www.freedesktop.org/software/systemd/man/devel/sd_notify.html#Notes
+ */
+int sd_notify_ready(void);
+int sd_notify_stopping(void);
+
+#endif
diff --git a/msdos/sed1v2.inp b/msdos/sed1v2.inp
index 4d4c80a6b1a..d6d80ff809c 100644
--- a/msdos/sed1v2.inp
+++ b/msdos/sed1v2.inp
@@ -138,8 +138,6 @@ s/ *@WEBP_LIBS@//
 /^LIBMODULES *=/s/@LIBMODULES@//
 /^MODULES_OBJ *=/s/@MODULES_OBJ@//
 /^LIBSELINUX_LIBS *=/s/@LIBSELINUX_LIBS@//
-/^LIBSYSTEMD_LIBS *=/s/@LIBSYSTEMD_LIBS@//
-/^LIBSYSTEMD_CFLAGS *=/s/@LIBSYSTEMD_CFLAGS@//
 /^LIB_CLOCK_GETTIME *=/s/@[^@\n]*@//g
 /^LIB_TIMER_TIME *=/s/@[^@\n]*@//g
 /^LIB_EXECINFO *=/s/@[^@\n]*@//g
@@ -269,7 +267,6 @@ s/echo.*buildobj.lst/dj&/
 # Make the GCC command line fit one screen line
 /^[    ][      ]*\$(GNUSTEP_CFLAGS)/d
 /^[    ][      ]*\$(LIBGNUTLS_CFLAGS)/d
-/^[    ][      ]*\$(LIBSYSTEMD_CFLAGS)/d
 /^[    ][      ]*\$(XRANDR_CFLAGS)/d
 /^[    ][      ]*\$(WEBKIT_CFLAGS)/d
 /^[    ][      ]*\$(SETTINGS_CFLAGS)/d
diff --git a/src/Makefile.in b/src/Makefile.in
index 9bc53c072ea..d3a7f432ea8 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -336,9 +336,6 @@ LIBSELINUX_LIBS =
 LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@
 LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@
 
-LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@
-LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@
-
 JSON_LIBS = @JSON_LIBS@
 JSON_CFLAGS = @JSON_CFLAGS@
 JSON_OBJ = @JSON_OBJ@
@@ -405,11 +402,11 @@ EMACS_CFLAGS=
   $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \
   $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \
   $(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(LIBGCCJIT_CFLAGS) $(DBUS_CFLAGS) \
-  $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFLAGS) \
+  $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFAGS) \
   $(XINPUT_CFLAGS) $(WEBP_CFLAGS) $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \
   $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
   $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
-  $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(XSYNC_CFLAGS) $(TREE_SITTER_CFLAGS) \
+  $(JSON_CFLAGS) $(XSYNC_CFLAGS) $(TREE_SITTER_CFLAGS) \
   $(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
   $(WERROR_CFLAGS) $(HAIKU_CFLAGS) $(XCOMPOSITE_CFLAGS) $(XSHAPE_CFLAGS)
 ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
@@ -567,7 +564,7 @@ LIBES =
    $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
    $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) 
$(M17N_FLT_LIBS) \
    $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \
-   $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \
+   $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) \
    $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS) $(HAIKU_LIBS) \
    $(TREE_SITTER_LIBS) $(SQLITE3_LIBS) $(XCOMPOSITE_LIBS) $(XSHAPE_LIBS)
 
diff --git a/src/deps.mk b/src/deps.mk
index a7c8ae11f72..b932764f267 100644
--- a/src/deps.mk
+++ b/src/deps.mk
@@ -92,7 +92,7 @@ editfns.o:
 emacs.o: emacs.c commands.h systty.h syssignal.h blockinput.h process.h \
    termhooks.h buffer.h atimer.h systime.h $(INTERVALS_H) lisp.h $(config_h) \
    globals.h ../lib/unistd.h window.h dispextern.h keyboard.h keymap.h \
-   frame.h coding.h gnutls.h msdos.h dosfns.h unexec.h
+   frame.h coding.h gnutls.h msdos.h dosfns.h unexec.h ../lib/sd-socket.h
 fileio.o: fileio.c window.h buffer.h systime.h $(INTERVALS_H) character.h \
    coding.h msdos.h blockinput.h atimer.h lisp.h $(config_h) frame.h \
    commands.h globals.h ../lib/unistd.h
diff --git a/src/emacs.c b/src/emacs.c
index dde305edbc2..c0381c23c37 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -57,10 +57,8 @@ #define MAIN_PROGRAM
 #include "dosfns.h"
 #endif
 
-#ifdef HAVE_LIBSYSTEMD
-# include <systemd/sd-daemon.h>
-# include <sys/socket.h>
-#endif
+#include "sd-socket.h"
+#include <sys/socket.h>
 
 #if defined HAVE_LINUX_SECCOMP_H && defined HAVE_LINUX_FILTER_H \
   && HAVE_DECL_SECCOMP_SET_MODE_FILTER                          \
@@ -1719,20 +1717,19 @@ main (int argc, char **argv)
             }
         } /* daemon_type == 2 */
 
-#ifdef HAVE_LIBSYSTEMD
       /* Read the number of sockets passed through by systemd.  */
-      int systemd_socket = sd_listen_fds (1);
-
-      if (systemd_socket > 1)
-        fputs (("\n"
-               "Warning: systemd passed more than one socket to Emacs.\n"
-               "Try 'Accept=false' in the Emacs socket unit file.\n"),
-              stderr);
-      else if (systemd_socket == 1
-              && (0 < sd_is_socket (SD_LISTEN_FDS_START,
-                                    AF_UNSPEC, SOCK_STREAM, 1)))
-       sockfd = SD_LISTEN_FDS_START;
-#endif /* HAVE_LIBSYSTEMD */
+      const char *fds = getenv("LISTEN_FDS");
+      if (fds) {
+       int systemd_socket = strtol(fds, NULL, 0);
+       if (systemd_socket > 1)
+         fputs (("\n"
+                 "Warning: systemd passed more than one socket to Emacs.\n"
+                 "Try 'Accept=false' in the Emacs socket unit file.\n"),
+                stderr);
+       else if (systemd_socket == 1
+                && (0 < sd_is_socket (SD_LISTEN_FDS_START, SOCK_STREAM, 1)))
+         sockfd = SD_LISTEN_FDS_START;
+      }
 
       /* On X, the bug happens because we call abort to avoid GLib
         crashes upon a longjmp in our X error handler.
@@ -2857,12 +2854,15 @@ DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 2, 
"P",
     }
 #endif
 
-#ifdef HAVE_LIBSYSTEMD
   /* Notify systemd we are shutting down, but only if we have notified
      it about startup.  */
-  if (daemon_type == -1)
-    sd_notify(0, "STOPPING=1");
-#endif /* HAVE_LIBSYSTEMD */
+  if (daemon_type == -1){
+    int r = sd_notify_stopping();
+    if (r < 0) {
+      fprintf(stderr, "Failed to report termination to $NOTIFY_SOCKET: %s\n", 
strerror(-r));
+      exit (EXIT_FAILURE);
+    }
+  }
 
   /* Fsignal calls emacs_abort () if it sees that waiting_for_input is
      set.  */
@@ -3382,9 +3382,11 @@ DEFUN ("daemon-initialized", Fdaemon_initialized, 
Sdaemon_initialized, 0, 0, 0,
 
   if (daemon_type == 1)
     {
-#ifdef HAVE_LIBSYSTEMD
-      sd_notify(0, "READY=1");
-#endif /* HAVE_LIBSYSTEMD */
+      int r = sd_notify_ready();
+      if (r < 0) {
+       fprintf(stderr, "Failed to notify readiness to $NOTIFY_SOCKET: %s\n", 
strerror(-r));
+       exit (EXIT_FAILURE);
+      }
     }
 
   if (daemon_type == 2)
-- 
2.41.0

>
> But if the code is sufficiently simple, it implements a protocol that's
> well documented, and it allows us to eliminate the dependency on the
> systemd library, we might like it.
>
>
>         Stefan
>

-- 
Best regards,
Nicolas Graves

reply via email to

[Prev in Thread] Current Thread [Next in Thread]