diff --git a/include/uv-private/uv-unix.h b/include/uv-private/uv-unix.h index 72709c8a..0db14e9c 100644 --- a/include/uv-private/uv-unix.h +++ b/include/uv-private/uv-unix.h @@ -99,7 +99,8 @@ typedef int uv_file; ngx_queue_t write_completed_queue; \ int delayed_error; \ uv_connection_cb connection_cb; \ - int accepted_fd; + int accepted_fd; \ + int blocking; /* UV_TCP */ diff --git a/include/uv.h b/include/uv.h index e938fe55..8082afaf 100644 --- a/include/uv.h +++ b/include/uv.h @@ -626,7 +626,18 @@ struct uv_tty_s { UV_TTY_PRIVATE_FIELDS }; -int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd); +/* + * Initialize a new TTY stream with the given file descriptor. Usually the + * file descriptor will be + * 0 = stdin + * 1 = stdout + * 2 = stderr + * The last argument, readable, specifies if you plan on calling + * uv_read_start with this stream. stdin is readable, stdout is not. + * + * TTY streams which are not readable have blocking writes. + */ +int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable); /* * Set mode. 0 for normal, 1 for raw. diff --git a/src/unix/stream.c b/src/unix/stream.c index 7de318e2..9f2f0ecf 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -53,6 +53,7 @@ void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream, uv_handle_type type) { uv__handle_init(loop, (uv_handle_t*)stream, type); + loop->counters.stream_init++; stream->alloc_cb = NULL; stream->close_cb = NULL; @@ -83,7 +84,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) { assert(fd >= 0); stream->fd = fd; - ((uv_handle_t*)stream)->flags |= flags; + stream->flags |= flags; /* Reuse the port address if applicable. */ yes = 1; diff --git a/src/unix/tty.c b/src/unix/tty.c index 3d074bf4..32ac2c71 100644 --- a/src/unix/tty.c +++ b/src/unix/tty.c @@ -33,10 +33,19 @@ static int orig_termios_fd = -1; static struct termios orig_termios; -int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd) { - uv__nonblock(fd, 1); +int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) { uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY); - uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE | UV_WRITABLE); + + if (readable) { + uv__nonblock(fd, 1); + uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE); + } else { + /* Note: writable tty we set to blocking mode. */ + uv__nonblock(fd, 0); + uv__stream_open((uv_stream_t*)tty, fd, UV_WRITABLE); + tty->blocking = 1; + } + loop->counters.tty_init++; tty->mode = 0; return 0; diff --git a/src/win/tty.c b/src/win/tty.c index b989bebe..16064eed 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -86,7 +86,7 @@ void uv_console_init() { } -int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd) { +int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) { HANDLE win_handle; CONSOLE_SCREEN_BUFFER_INFO info; diff --git a/test/test-tty.c b/test/test-tty.c index 5dbd4aff..60aedf39 100644 --- a/test/test-tty.c +++ b/test/test-tty.c @@ -33,7 +33,7 @@ TEST_IMPL(tty) { */ ASSERT(UV_TTY == uv_guess_handle(0)); - r = uv_tty_init(uv_default_loop(), &tty, 0); + r = uv_tty_init(uv_default_loop(), &tty, 0, 1); ASSERT(r == 0); r = uv_tty_get_winsize(&tty, &width, &height);