[Openmcl-devel] remote repl

Gary Byers gb at clozure.com
Wed Mar 11 14:11:31 PDT 2009

CCL::LISTENER-FUNCTION ordinarily prints the "Welcome!" greeting, then
calls CCL::TOPLEVEL-LOOP, which runs the REPL.

When a thread starts up, most of the standard CL stream variables
are synonym streams to *TERMINAL-IO*; *TERMINAL-IO* is bound to
its static value (which is basically a TWO-WAY-STREAM connected
to the process-wide standard input/output. So, the general idea
would be something like:

(defun run-listener (tcp-stream)
   (let* ((*terminal-io* tcp-stream))

(let* ((tcp-stream (accept-connection listener-socket)))
   (process-run-function "remote-listener" #'run-listener tcp-stream))

Unless I'm forgetting something (which is certainly possible), that'd
give you at least some basic functionality.  There may be some additional
issues: the telnet client may want to negotiate options, it'd be good
to have some way of sending and handling keyboard interrupts, etc.
If the client closes the telnet connection, the server thread should
probably clean up after itself and quietly die (and not just keep
writing messages to *ERROR-OUTPUT*, complaining that the stream
to which *ERROR-OUTPUT* is a synonym-stream closed unexpecedly ...)

CCL::ECHOING-TWO-WAY-STREAM is a (misleadingly-named) subclass
of TWO-WAY-STREAM that's apropriate to use when input is echoed
(as it ordinarily is in a shell or Emacs buffer.)  E,g, if you
read "(fact 100)<newline>", the newline is generally echoed, so
a subsequent FRESH-LINE should realize that output will be written
at the beginning of a line.

The rest is left as an excercise ...

On Wed, 11 Mar 2009, Chris Dean wrote:

> I'm new to Clozure and trying to port some code to it.  I would like to
> write my own repl that a user can telnet into for debugging purposes.
> I think I can handle all the socket bookkeeping, but I was wondering if
> there is an existing repl function I can hook into?  I could of course
> right my own (or use swank), but I'm looking for something that already
> exists and handles the debugger properly.
> Thanks!  I have some sample code below to give an idea of what I'm using
> now.
> We're using Version 1.3-RC1-r11804M (DarwinX8632).
> Cheers,
> Chris Dean
> (defun run-listener (stream id)
>   "Run a top-level listener"
>   (unwind-protect
>        (let ((*terminal-io* stream)
>              ;; ...
>              (*standard-output* stream)
>              (*standard-input* stream))
>          (format t "~&Welcome to ~a ~a~%"
>                  (lisp-implementation-type)
>                  (lisp-implementation-version))
>         (format t "This is remote read-eval-print loop ~d, " id)
>     (format *terminal-io* "~&End of top level listener ~d, " id)
>     (format *terminal-io* "closing stream, ending process.~%")
>     (close stream)))
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list