Hello, I'm pretty new to this, so hopefully I'm doing something wrong, but when using a suspendable read-line with the following "minimal" program:
--8<---------------cut here---------------start------------->8--- (use-modules (ice-9 match) (ice-9 rdelim) (ice-9 suspendable-ports)) (install-suspendable-ports!) (define (read-line* port cont) ;; Return, as a pair, the line and the terminated delimiter or end-of-file ;; object. When a line cannot be read, return the '(suspended ;; . partial-continuation) pair, where partial-continuation can be ;; evaluated in the future when the port is ready to be read. (call-with-prompt 'continue (lambda () (parameterize ((current-read-waiter (lambda (_) (abort-to-prompt 'continue)))) (if cont (cont) (read-line port 'split)))) (lambda (partial-continuation) (cons 'suspended partial-continuation)))) (define (main) ;; Create a pipe, and set its read side to non-blocking mode. (define child->parent-pipe (pipe)) (let ((flags (fcntl (car child->parent-pipe) F_GETFL))) (fcntl (car child->parent-pipe) F_SETFL (logior O_NONBLOCK flags))) ;; Empty buffers to avoid duplicated output. (flush-all-ports) (match (primitive-fork) (0 ;child ;; Connect the stdout and stderr outputs of the child process to the ;; pipe established in the parent. (close (car child->parent-pipe)) ;unused input pipe (dup2 (port->fdes (cdr child->parent-pipe)) 1) (dup2 1 2) (set-current-output-port (cdr child->parent-pipe)) (set-current-error-port (cdr child->parent-pipe)) (while #t (format #t "Line 1\n") (format #t "Line 2\nLine 3\n") (display "Done!\n") (force-output) (sleep 5))) (child-pid ;parent (close (cdr child->parent-pipe)) ;disconnect the write end of the pipe (define port (car child->parent-pipe)) (let loop ((cont #f)) (match (select (list (port->fdes port)) '() '()) (((fdes ..1) () ()) (let next-line ((line+delim (read-line* port cont))) (match line+delim (('suspended . partial-continuation) (loop partial-continuation)) ((line . _) (format #t "~a~%" line) (next-line (read-line* port cont))))))))))) (main) --8<---------------cut here---------------end--------------->8--- The output looks like this (non-deterministic it seems): --8<---------------cut here---------------start------------->8--- $ guile repro.scm Line 1 Line 2 Line 3 Done! Line 1 Line 2 Line 3 Done! Line 1 Line 1 Line 1 [...] --8<---------------cut here---------------end--------------->8--- And strace shows that more than a single line is buffered on each read-line, but that it only returns the first line of such buffered input: --8<---------------cut here---------------start------------->8--- read(8, 0x7fcd06bfc020, 4096) = -1 EAGAIN (Resource temporarily unavailable) rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 select(9, [3 8], [], [], NULL) = 1 (in [8]) read(8, "Line 1\nLine 2\nLine 3\nDone!\n", 4096) = 27 write(1, "Line 1", 6Line 1) = 6 write(1, "\n", 1 ) = 1 read(8, 0x7fcd06bfc020, 4096) = -1 EAGAIN (Resource temporarily unavailable) rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 select(9, [3 8], [], [], NULL) = 1 (in [8]) read(8, "Line 1\nLine 2\nLine 3\nDone!\n", 4096) = 27 write(1, "Line 1", 6Line 1) = 6 write(1, "\n", 1 ) = 1 [...] --8<---------------cut here---------------end--------------->8--- Bug? PEBCAK? I'm interested to know :-). Thanks, Maxim