While the following works:
(let* ((i (make-string-input-stream "foo bar baz"))
(p (sb-ext:run-program "/bin/cat" '()
:input i :output *trace-output* :wait t)))
(sb-ext:process-close p))
the code below does not - it will stop after writing "001":
(let* ((_1 (format t "001~%"))
(p (sb-ext:run-program "/bin/cat" '()
:input :stream :output *trace-output* :wait t))
(_2 (format t "010~s~%" p))
(s (sb-ext:process-input p)))
(declare (ignore _1 _2))
(format s "foo bar baz~%")
(finish-output s)
(sb-ext:process-close p))
So it seems to silently leave execution in sb-ext:run-program.
This is with SBCL 1.3.6 on Ubuntu 16.04.1.
Any ideas? Thanks in advance, Frank
As I mentioned in the comments, the problem is the
:WAIT Targument. It causes the call toSB-EXT:RUN-PROGRAMto not return until the child process exits.In the first example you passed a string input stream to the child process.
catwill read input from the stream, and when the input ends there will be a End of File, socatexits. In the second example there is no input available for the program, so it's effectively an infinite loop (just like if you runcaton the command line, and don't give any input to it; it will never exit).The solution is to use
:WAIT NIL. You will also have to close the input stream withCLOSE, because otherwise there will be no EOF andcatkeeps listening for more input. You'll also want to useSB-EXT:PROCESS-WAITafter closing the stream to wait forcatto exit itself.I'm not sure why you used
*TRACE-OUTPUT*for the child output, so I changed it to*STANDARD-OUTPUT*.Also, using
FORMATfor debugging like that is kind of ugly. Common Lisp provides actual debugging tools. In this case you could useSTEP:This will put you in the debugger, showing the call being evaluated next. You can invoke the
STEP-NEXT-restart to continue to the next call.