Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Calling uv_read_stop on stdin tty causes EOF to never be read #982

Closed
alexcrichton opened this issue Nov 3, 2013 · 4 comments
Closed

Calling uv_read_stop on stdin tty causes EOF to never be read #982

alexcrichton opened this issue Nov 3, 2013 · 4 comments

Comments

@alexcrichton
Copy link

#include <assert.h>
#include <uv.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

uv_loop_t *loop;
uv_tty_t tty;
uv_timer_t timer;

void myread(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);

void alloc(uv_handle_t *handle, size_t suggested, uv_buf_t *buf) {
    buf->len = 1;
    buf->base = malloc(1);
}

void mytimer(uv_timer_t *timer, int status) {
    printf("going back for a read\n");
    assert(uv_read_start((uv_stream_t*) &tty, alloc, myread) == 0);
}

void myread(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
    printf("read %d bytes\n", (int) nread);
    assert(uv_read_stop(stream) == 0);
    if (nread > 0)      
        uv_timer_start(&timer, mytimer, 1, 0);
}

int main() {
    loop = uv_default_loop();

    uv_tty_init(loop, &tty, 0, 1);
    uv_timer_init(loop, &timer);
    uv_read_start((uv_stream_t*) &tty, alloc, myread);
    return uv_run(loop, UV_RUN_DEFAULT);
}

When I compile that program, and then run it via echo a | ./foo, the program will never exit (it never sees EOF for stdin). If the call to uv_read_stop is omitted, however, then the program will successfully exit.

I also found out that running ./foo and then hitting ctrl+D does indeed see the EOF (and the program exits). This program was initially tested on linux (where it didn't work), but it turns out that on osx this does work (both echo a | ./foo and ./foo + ctrl-d).

I also found out that the reading one byte at a time is important, If I read a larger buffer then this works as expected (at least in the small cases).

@alexcrichton
Copy link
Author

Hm it appears that I haven't investigated this enough. I seem to have prematurely opened this (I think the code is right). Closing for now until I figure out what's going on. Sorry for the noise!

@alexcrichton
Copy link
Author

Investigated a bit more, updated the program, and it looks like this may actually be a bug.

@alexcrichton alexcrichton reopened this Nov 3, 2013
@bnoordhuis
Copy link
Contributor

Confirmed, thanks. Possibly related to #971.

bnoordhuis added a commit that referenced this issue Nov 8, 2013
Work around an epoll quirk where it sometimes reports just the EPOLLERR
or EPOLLHUP event.  In order to force the event loop to move forward,
we merge in the read/write events that the watcher is interested in;
uv__read() and uv__write() will then deal with the error or hangup in
the usual fashion.

Fixes #982.

This is a back-port of commit 24bfef2 from the master branch.
@alexcrichton
Copy link
Author

Thanks for looking into this!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants