About two weeks ago I asked on IRC whether there was support for using SLIME via unix domains sockets.
Someone answererd in the negative, citing lack of unix domain socket support on Emacs as the reason.
I later realized that this doesn't really matter, because we should be able to use an arbitrary process object with a suitable external command. I tried it, and it's working very nicely so far, using
unixclient path-to-socket ucspi-proxy
as a command in a process object on the Emacs side ("unixclient" and "ucspi-proxy" are available in Debian in the ucspi-unix and ucspi-proxy packages.)
(A side effect is that we can easily add other components into the communications pipeline. Things I tried successfully:
recordio 2>/tmp/slime-io unixclient path-to-socket ucspi-proxy
to record communications, and
ssh remote-host unixclient path-to-socket ucspi-proxy
to use it from a remote machine.)
Below is what I hacked into swank.lisp in order to make unix domain sockets work. Instead of adding specific code to create unix domain sockets, I changed setup-server to accept a pre-established socket object. This is a simple change that should allow anyone on a Lisp that supports it to use unix domain sockets without much change to the swank proper.
For the Emacs side, I don't have anything resembling useable patches (being a total slime newbie, really). Something along the lines of the above would probably be simplest, i.e. passing an established process object for slime to use. Some necessary changes identified so far seem to be:
* changing (eq (process-status conn) 'open) to (memq (process-status conn) '(run open)) in a few places
* Avoid trying to get the "port" of a non-network process object.
I need to set (setf swank:*use-dedicated-output-stream* nil) to make things work properly. Interaction looks to be fast enough, though.
Marcus
diff -u slime-1.0-original/swank.lisp slime-1.0/swank.lisp --- slime-1.0-original/swank.lisp Sat Sep 4 18:19:52 2004 +++ slime-1.0/swank.lisp Sat Dec 18 14:09:36 2004 @@ -277,8 +277,10 @@ dont-close) "Start the server and write the listen port number to PORT-FILE. This is the entry point for Emacs." - (setup-server 0 (lambda (port) (announce-server-port port-file port)) - style dont-close)) + (create-swank-server 0 style + (lambda (port) + (announce-server-port port-file port)) + dont-close))
(defun create-server (&key (port default-server-port) (style *communication-style*) @@ -286,37 +288,37 @@ "Start a SWANK server on PORT running in STYLE. If DONT-CLOSE is true then the listen socket will accept multiple connections, otherwise it will be closed after the first." - (setup-server port #'simple-announce-function style dont-close)) + (create-swank-server port style #'simple-announce-function dont-close))
(defun create-swank-server (&optional (port default-server-port) (style *communication-style*) (announce-fn #'simple-announce-function) dont-close) - (setup-server port announce-fn style dont-close)) - -(defparameter *loopback-interface* "127.0.0.1") - -(defun setup-server (port announce-fn style dont-close) - (declare (type function announce-fn)) (let* ((socket (create-socket *loopback-interface* port)) (port (local-port socket))) (funcall announce-fn port) - (ecase style - (:spawn - (spawn (lambda () - (loop do (serve-connection socket :spawn dont-close) - while dont-close)) - :name "Swank")) - ((:fd-handler :sigio) - (add-fd-handler socket - (lambda () - (serve-connection socket style dont-close)))) - ((nil) - (unwind-protect - (loop do (serve-connection socket style dont-close) - while dont-close) - (close-socket socket)))) + (setup-server socket style dont-close) port)) + +(defparameter *loopback-interface* "127.0.0.1") + +(defun setup-server (socket style dont-close) + (declare (type function announce-fn)) + (ecase style + (:spawn + (spawn (lambda () + (loop do (serve-connection socket :spawn dont-close) + while dont-close)) + :name "Swank")) + ((:fd-handler :sigio) + (add-fd-handler socket + (lambda () + (serve-connection socket style dont-close)))) + ((nil) + (unwind-protect + (loop do (serve-connection socket style dont-close) + while dont-close) + (close-socket socket)))))
(defun serve-connection (socket style dont-close) (let ((client (accept-connection socket)))