How can *standard-input* and *standard-output* be redirected to another PTY, FIFO or socket?

902 views Asked by At

I was wondering if it's possible to redirect ECL's Linux stdio so that it does not share streams with the application that it's embedded in.

My problem is that the host application takes over stdin, stdout and stderr for its own purposes. So, I'd like to have a separate console for lisp noise and for recovering when SLIME/SWANK crashes back to the top level. Presently SWANK hiccups put CL-USER> prompts into the applications debug log, the fail with C opperation (read) signalled an error an stdout is redirected and stdin is most-likely closed or used by a parent process.

I know that you can setf *standand-output*, etc to a new stream but I haven't found a way to attach a terminal, such as screen or xterm or socket to it. I would need the underlying Linux/C file descriptors and then I could make a PTY.

Even better would be if there's some way to attach them the standard streams to a socket server that I could connect to using telnet.

Update

Following a suggestion in the comments, I tried this code:

(loop for filename in '("stdin-fifo" "stdout-fifo" "stderr-fifo") do
  (let (
        (truename (probe-file filename)))
    (if truename  nil
                       (ext:run-program "/usr/bin/mkfifo" (list filename)))))

(setf *standard-output*
      (open (probe-file "stdout-fifo") :direction :output :if-exists :overwrite))
(setf *error-output*
      (open (probe-file "stderr-fifo") :direction :output :if-exists :overwrite))
(setf *standard-input*
      (open (probe-file "stdin-fifo") :direction :input))

It doesn't quite do the job. The problem is that while some of the IO is redirected SWANK, still seems to have a way to get at the real streams. I guess it will take some research to figure out how SWANK does that. Oh, the high price of convenience!

Update 2

My mistake. There is no *standard-error*, only *error-output*. Can you tell I'm very new to Lisp?

Now, everything is redirected. However, SLIME won't talk to SWANK now, defeating the purpose somewhat ...

Update 3

Victory! Before you connect SLIME, you need to run something like this shell script in a terminal to create your top-level shell:

tail -f stdout-fifo &
tail -f stderr-fifo &
cat - >> stdin-fifo

The reason, I can't guess. But luckily it works anyway.

BTW, not to discourage anyone who wants to post a better answer

I'm sure someone can make a socket server or screen-detached PTY that keeps the streams happy whether-or-not someone is watching them. That would be a much classier solution.

0

There are 0 answers