Subject: bug#76870: 31.0.50; server-start with non-nil arg LEAVE-DEAD can write confusing warnings

From: Jens Schmidt <[email-masked]>
Date: Sat, 08 Mar 2025 16:45:27 +0100

* Original Reproducer

Start an Emacs session A with emacs -Q, start an Emacs server in that
with M-x server-start RET.

Now start another Emacs session B with emacs -Q and evaluate the
following with C-j in its *scratch* buffer:

  (require 'server)
  server

  (unload-feature 'server)
  nil

The call to `unload-feature' results in warnings:

  ⛔ Warning (server): Unable to start the Emacs server.
  There is an existing Emacs server, named "server"
  To start the server in this Emacs process, stop the existing server or call M-x server-force-delete to forcibly disconnect it.

* Simplified Reproducer

Start an Emacs session A with emacs -Q, start an Emacs server in that
with M-x server-start RET.

Now start another Emacs session B with emacs -Q and evaluate the
following with C-j in its *scratch* buffer:

  (require 'server)
  server

  (server-start t)
  nil

You get the same warnings as shown in the original reproducer.

* Analysis

According to the doc string and the implementation of `server-start', a
call

  (server-start t)

with non-nil argument LEAVE-DEAD should just stop a running server.  And
this also works perfectly well when the server is running locally in the
same Emacs session where `(server-start t)' gets executed.

However, if there is an external Emacs server running in an Emacs
session A, then `(server-start t)' from another session B obviously
cannot just stop that server.  However, the warning issued in session B
as quoted above mentions that the server cannot be *started*.

1. So I think in case of non-nil LEAVE-DEAD and a running external
   server, a more appropriate warning would be:

     ⛔ Warning (server): Unable to stop an external Emacs server.
     There is an existing Emacs server, named "server"
     Stop it either in its Emacs session or call M-x server-force-delete to forcibly disconnect it.

2. However, one could also argue that, if there is no local server
   running, a call to `(server-start t)' should be completely silent.
   That is at least what `(server-start t)' does if there is no server
   (neither local nor external) running at all.

3. Or at least it should be silent if called from a non-interactive
   context as shown in the original reproducer.

4. Or at the very least it should be silent if called from
   `server-unload-function'.

Not sure what the "ideal" fix would be here, but I would be happy to
provide patches for any of the scenarios above.

Thanks!

In GNU Emacs 31.0.50 (build 22, x86_64-pc-linux-gnu, GTK+ Version
 3.24.38, cairo version 1.16.0) of 2025-03-05 built on sappc2
Repository revision: e978737f57ef8447bba5796dd945ac185fcadffa
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12201009
System Description: Debian GNU/Linux 12 (bookworm)

Configured using:
 'configure --with-native-compilation --with-mailutils'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NATIVE_COMP
NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND THREADS TIFF
TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINERAMA XINPUT2 XPM XRANDR GTK3
ZLIB

Important settings:
  value of $LC_COLLATE: POSIX
  value of $LC_TIME: POSIX
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr comp-run bytecomp byte-compile comp-common rx
emacsbug lisp-mnt message mailcap yank-media puny dired dired-loaddefs
rfc822 mml mml-sec password-cache epa derived epg rfc6068 epg-config
gnus-util text-property-search time-date subr-x mm-decode mm-bodies
mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-loaddefs
cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils
rmc iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook
vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd touch-screen tool-bar dnd fontset image regexp-opt
fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode
register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting cairo gtk x-toolkit xinput2 x multi-tty move-toolbar
make-network-process tty-child-frames native-compile emacs)

Memory information:
((conses 16 58238 9283) (symbols 48 6194 0) (strings 32 15317 1578)
 (string-bytes 1 469817) (vectors 16 9913)
 (vector-slots 8 139320 7677) (floats 8 23 12) (intervals 56 238 0)
 (buffers 984 10))