Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

READ from terminal stdin blocks until end of file

56 views
Skip to first unread message

David Banks

unread,
Apr 30, 2011, 9:15:20 AM4/30/11
to mosh-develo...@googlegroups.com
Hi all,

Using the following program 'reader.scm':

#!r6rs

(import (rnrs))

(let loop ()
(let ((datum (read)))
(write datum)
(newline)
(loop)))

I type in some numbers, followed by a newline each time.

amoe@glimworm $ mosh reader.scm
1
2
3
4
[I send EOF with ^D]
1
[^D]
2
[^D]
3
[^D]
4
[^D]
#<eof-object>
...etc.

As you can see the (read) call is blocking until it sees an EOF,
whereas I think it should return and write the result immediately,
like this:

amoe@glimworm $ mosh reader.scm
1
1 [from mosh]
2
2 [from mosh]
.... etc ...

Indeed that's the behaviour that I get from Ikarus and Ypsilon. I'm
not sure if this is a bug as it's probably technically unspecified.
But this behaviour seems quite surprising.

It seems this behaviour only happens at the terminal as it works fine
if I redirect stdin. (If it really had to receive 4 EOFs before
writing output it would presumably hang.)

Cheers,
--
David Banks  <amo...@gmail.com>

okuoku

unread,
Apr 30, 2011, 11:25:25 AM4/30/11
to mosh-develo...@googlegroups.com
2011/4/30 David Banks <amo...@gmail.com>:
> Hi all,
- snip -

> As you can see the (read) call is blocking until it sees an EOF,
> whereas I think it should return and write the result immediately,
> like this:

Reading from terminal is quite un-portable thingy.. and mosh's READ is
optimized aggressively.

If your script requires (REPL like) input prompt, please avoid to use
READ directly and try followings:

1) - Use get-line and buffer input.

(import (rnrs))

(define (string->datum str)
(call-with-port (open-string-input-port str) read))

(define (readline)
(string->datum (get-line (current-input-port))))

(let loop ()
(let ((datum (readline)))
(write datum)
(newline)
(loop)))


2) - POSIX systems and Nmosh only
Recent Nmosh has terminal control functions, so you can enable
char-by-char input like this:

WARNING: you cannot stop this script by CTRL+C

(import (rnrs) (nmosh stubs terminal))

(when (terminal_isatty 0) ;; 0 means stdin
(display "IT'S A TTY!\n")
(terminal_acquire))

(let loop ()
(let ((datum (get-char (current-input-port))))
(write datum)
(newline)
(loop)))
(terminal_release)


I recommend 1) because it's portable (includes other R6RS
implementation) and work as excepted.

David Banks

unread,
Apr 30, 2011, 11:42:58 AM4/30/11
to mosh-develo...@googlegroups.com
On 30 April 2011 16:25, okuoku <oku...@gmail.com> wrote:
> Reading from terminal is quite un-portable thingy.. and mosh's READ is
> optimized aggressively.
>
> If your script requires (REPL like) input prompt, please avoid to use
> READ directly and try followings:
>
> 1) - Use get-line and buffer input.
<snip>

> I recommend 1) because it's portable (includes other R6RS
> implementation) and work as excepted.

ACK, I will do so. Thanks Okuoko.

--
David Banks  <amo...@gmail.com>

Reply all
Reply to author
Forward
0 new messages