Strange EOF behavior in REPL #1306

Closed
dcampbell24 opened this Issue Sep 22, 2012 · 5 comments

Comments

Projects
None yet
3 participants
Contributor

dcampbell24 commented Sep 22, 2012

If I start the REPL and enter the code below it works as one would expect the first time, breaking on ctrl-d, but the second time will return immediately.

while true
    line = readline(stdin_stream)
    if line == ""
        break
    end
    print(line)
end
Owner

StefanKarpinski commented Sep 22, 2012

I think that's the expected behavior — the first ^D closes stdin so it is already closed the second time you run that code so the loop exits immediately.

On Sep 22, 2012, at 4:36 PM, David Campbell notifications@github.com wrote:

If I start the REPL and enter the code below it works as one would expect the first time, breaking on ctrl-d, but the second time will return immediately.

while true
line = readline(stdin_stream)
if line == ""
break
end
print(line)
end


Reply to this email directly or view it on GitHub.

Contributor

dcampbell24 commented Sep 23, 2012

I can't find any documentation about EOF that states it means close whatever file it was read from. In general, files can grow (streams can get more data), so a read could be valid even after an EOF was read previously. Also, in at least Python stdin is not closed by reading an EOF in a readline loop. Furthermore, if the file is closed, reading from it should be an error.

Owner

StefanKarpinski commented Sep 28, 2012

I'm not sure about all of that, but it certainly is arguable. I wouldn't be surprised if Python does something particular to the TTY/terminal in interactive mode.

Member

vtjnash commented Nov 8, 2012

^D is not EOF, but rather causes EOF. The distinction is important. Typing VEOF means "end-of-transmission" and "close this tty" when at the raw command line. Readline disables this behavior when it has control (at the REPL) Turning off canonical mode (~ICANON) would also disables this behavior but it turns ^D, ^U, backspace, etc into normal / unprocessed characters. Setting the VEOF character to something else (ie \0) also works but then ^D loses all special meaning (which may be OK, but I suspect not)

In the libuv branch, there is a possibility this can be made to work fully with enough work (all of the line editing characters would need to be handled manually and the display updated according). I don't think that's as possible here.

Member

vtjnash commented Feb 1, 2013

behavior now is that the repl is also closed.

According to libuv, continuing to read a stream after receiving EOF is undefined. https://github.com/joyent/libuv/blob/master/include/uv.h#L306
However, we could special case STDIN (or TTY's in general) to work around this. It would also require some sort of escape to get readline to return. It would also require the basic repl to handle the EOF condition.

diff --git a/base/stream.jl b/base/stream.jl
index 74b3547..460e0ed 100644
--- a/base/stream.jl
+++ b/base/stream.jl
@@ -245,7 +245,7 @@ function _uv_hook_readcb(stream::AsyncStream, nread::Int, base::Ptr{Void}, len::
            close(stream)
            throw(error)
         end
-        close(stream)
+        if stream != STDIN close(stream) end
         tasknotify(stream.readnotify, stream)
         #EOF
     else

vtjnash was assigned Feb 1, 2013

@vtjnash vtjnash added a commit that referenced this issue Feb 27, 2014

@vtjnash vtjnash fix #1306 f2c9c87

vtjnash closed this in #5973 Feb 28, 2014

vtjnash referenced this issue Apr 15, 2014

Closed

STDIN problems #6523

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment