armedbear / abcl

Armed Bear Common Lisp <git+https://github.com/armedbear/abcl/> <--> <svn+https://abcl.org/svn> Bridge
https://abcl.org#rdfs:seeAlso<https://gitlab.common-lisp.net/abcl/abcl>
Other
288 stars 29 forks source link

READ-CHAR-NO-HANG never returns an EOF-VALUE on a SYSTEM:PROCESS's output or error streams #676

Open kreuter opened 1 month ago

kreuter commented 1 month ago

On ABCL 1.9.2, OpenJDK 21.0.3, MacOS Sonoma x86_64, it seems that this form always returns NIL, where I would have expected :EOF (modulo timing, perhaps):

(let ((proc (system:run-program "/bin/sh" '("-c" "exit") :input nil :output :stream))) 
    (unwind-protect (read-char-no-hang (system:process-output proc) nil :eof) 
        (system:process-wait proc)))

And likewise for READ-CHAR-NO-HANG on the process's error stream. The analogous construct (i.e., READ-CHAR-NO-HANG on a stream associated with a pipe whose other end is the subprocess's stdout or stderr) returns :EOF on CCL, Clisp, ECL, LispWorks, SBCL, and I think also Allegro.

This seems to comes down to a quirk in Java: InputStreamReader's ready() method returns a false negative at eof on a stream that came from a Process's getInputStream(). I don't know if there's a straightforward workaround, unfortunately.

(FWIW, the reason I want this is to be able to accumulate both the output and error from an external process. I'm interested in reading and writing to pipes "manually" for a case where the external process's inputs or outputs involve secrets, making it inappropriate to buffer any of the input, output, or error streams to temporary files. This rules out UIOP's RUN-PROGRAM*; it also disinclines me from trying to use open stream arguments to the RUN-PROGRAM primitive anyplace, since some Lisps will implicitly buffer to temporary files. Anyhow, a slightly tricky loop writing small batches of data to the external process then using READ-CHAR-NO-HANG for non-blocking reads from the process's output and error seems to be implementable and to work reliably enough on Allegro, CCL, ECL, LispWorks, and SBCL; so I'd like to be able to get the equivalent working on ABCL, if possible.)

Thanks in advance for any consideration of this bug report. Please let me know if you'd like further information.