1

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"
  • Have you tried emacsclient --socket-name=/proc/12664/fd/3 ? – izkon Dec 4 '18 at 11:39
  • @izkon --- yes. – user1404316 Dec 4 '18 at 12:29
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
  • 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! – user1404316 Dec 4 '18 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. – user1404316 Dec 5 '18 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. – user1404316 Dec 5 '18 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 '18 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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