2

I have a running emacs daemon, and somehow lost the ability to connect to it.

Here are some relevant command output:

$ pgrep -a emacs 12664 emacs --daemon $ lsof -c emacs -a -u $USER -a -U -w COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME emacs 12664 me 3u unix 0xffff928d28f77000 0t0 113323181 type=STREAM # find /tmp -iname "*emacs*" # # find /tmp -inum 113323181 #

I also tried manually searching through /tmp for the socket file.

The lsof result shows a unix socket exists, but it looks like I lost the 'filename' for it. Is that correct? Is there a way to recover it, so that I might re-connect to the running daemon?

I tried the following, to no effect (the socket file was blinking red on my terminal window):

$ ls /proc/12664/fd/3
/proc/12664/fd/3@
$ cp /proc/12664/fd/3 /tmp/user/1007/emacs-daemon_recovered_socket_file
cp: cannot open '/proc/12664/fd/3' for reading: No such device or address

Using 'cp -a' did perform a copy, but just of the broken link, so attempting to use it failed:

\emacsclient -nw -s /tmp/user/1007/emacs-daemon_recovered_socket_file 
emacsclient: can't find socket; have you started the server?                                                                                                                                     
To start the server in Emacs, type "M-x server-start".
emacsclient: error accessing socket "/tmp/user/1007/emacs-daemon_recovered_socket_file"
2
  • Have you tried emacsclient --socket-name=/proc/12664/fd/3 ?
    – izkon
    Dec 4, 2018 at 11:39
  • @izkon --- yes. Dec 4, 2018 at 12:29

1 Answer 1

1

This doesn't answer your present question, but if you added something along these lines to your config, it would be useful in the future if the same thing happened. (Also useful if you had neglected to run Emacs as a server at all, and only later realised that you wanted to connect to it remotely.)

;; If SIGUSR1 is received, start a server.
(define-key special-event-map [sigusr1] 'sigusr1-handler)
(defun sigusr1-handler ()
  "Handler for SIGUSR1 signal.

    Can be tested with (signal-process (emacs-pid) 'sigusr1)"
  (interactive)
  (let ((newname (format "server-%d" (emacs-pid))))
    (unless (equal server-name newname)
      (message "Changed `server-name' from %s to %s"
               server-name
               (setq server-name newname))))
  (server-force-delete)
  (server-start))

e.g.:

$ kill -USR1 <emacs-pid>
$ emacsclient --socket-name=server-<emacs-pid> -c
4
  • Useful for the future, thanks. Now that I'm looking for 'emacs server signals', I see that emacswiki has a alternative using the same technique. Didn't (should've) known that emacs would have its own extensible signal handler! Dec 4, 2018 at 12:44
  • The emacswiki page emacswiki.org/emacs/EmacsAsDaemon includes an idea to connect to the process with gdb and then call some function to execute lisp code to restart the server. However, it lacks detail, and I've already given up and manually killed and restarted the process. Dec 5, 2018 at 14:38
  • I've just tested and verified a version of your script, without the let... stuff, ie. only server-force-delete and server-start. With that modification, there's no need to specify --socket-name=server-<emacs-pid> when running emacsclient. Dec 5, 2018 at 15:23
  • Absolutely; if you want the signal to clobber the original socket name, then you can do that -- the change here was to ensure that couldn't happen, but of course it depends on your use-cases.
    – phils
    Dec 5, 2018 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.