guix-devel
[Top][All Lists]
Advanced

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

Sockets in Shepherd, and Emacs, oh my!


From: Liliana Marie Prikler
Subject: Sockets in Shepherd, and Emacs, oh my!
Date: Fri, 08 Apr 2022 20:40:30 +0200
User-agent: Evolution 3.42.1

Hi Guix,

given that Shepherd 0.9.0 adds support for systemd-style socket
activation and Emacs supports that (if linked against systemd!) I
wanted to try it out.  Here's my "generic" recipe for constructing
an Emacs service:

--8<---------------cut here---------------start------------->8---
(define* (emacs #:key (name 'server)
                (uid (getuid))
                (gid (getgid)))
  (make <service>
    #:provides (list
                (symbol-append 'emacs@ name))
    #:requires '()
    #:start
    (make-systemd-constructor
     (list "emacs" "--fg-daemon")
     (list (endpoint
            (make-socket-address AF_UNIX
                                 (format #f "/run/user/~d/emacs/~s"
                                         uid name))
            #:socket-owner uid
            #:socket-group gid)))
    #:stop (make-systemd-destructor)))
--8<---------------cut here---------------end--------------->8---

Note how this allows the creation of multiple sockets, that launch
Emacsen on demand.  For instance, I could hook up one Emacs to git
changelogs, one mail reading and one to writing prose without them
interfering with each other.  (This assumes that tools spawing Emacs
will correctly launch emacsclient, of course.)  If for some reason,
I am not writing that many changelogs one day, the git one doesn't
need to be spawned, and so on, and so forth.

Sadly, this doesn't work as intended currently.  You will have to
use a specially prepared emacs, that links against systemd (logind
works fine too, use the recipe below).  I plan to upstream these
changes soon™, given that we're also lagging behind on Emacs 28.

--8<---------------cut here---------------start------------->8---
(define emacs-with-systemd
  (package (inherit emacs)
           (arguments
            (substitute-keyword-arguments
             (package-arguments emacs)
             ((#:phases phases)
              #~(modify-phases #$phases
                  (add-after 'unpack 'enable-logind
                    (lambda _
                      (substitute* (list "configure.ac")
                        (("libsystemd") "libelogind"))
                      (delete-file "configure")))))))
           (inputs (modify-inputs (package-inputs emacs)
                                  (prepend elogind)))
           (native-inputs (modify-inputs (package-native-inputs emacs)
                                         (prepend autoconf)))))
--8<---------------cut here---------------end--------------->8---

There appear to be some bugs, though.  If shepherd launches a process
via systemd-constructor and it dies before claiming the socket, it
will become a zombie.  Further, if the process dies after having
claimed the socket, shepherd will not reset service's entry points and
running value.  Both should be fixable in my opinion.

So, what's for the future?  If someone wants to do so, they could
adapt my shepherd service for Guix Home.  It'd be very nice to one
day be able to spawn an Emacs service fine-tuned to desired editing
purposes.  Think of using `guix shell --container' building packages
that you'd otherwise rarely need on demand, for example.

With that in mind, happy hacking!



reply via email to

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