diff options
-rw-r--r-- | docs/src/tty.rst | 4 | ||||
-rw-r--r-- | src/unix/tty.c | 11 | ||||
-rw-r--r-- | test/test-list.h | 2 | ||||
-rw-r--r-- | test/test-tty.c | 42 |
4 files changed, 58 insertions, 1 deletions
diff --git a/docs/src/tty.rst b/docs/src/tty.rst index c7845429..18f34ef4 100644 --- a/docs/src/tty.rst +++ b/docs/src/tty.rst @@ -66,6 +66,10 @@ API If opening ``/dev/tty`` fails, libuv falls back to blocking writes for non-readable TTY streams. + .. versionchanged:: 1.5.0: trying to initialize a TTY stream with a file + descriptor that refers to a file returns `UV_EINVAL` + on UNIX. + .. c:function:: int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode) .. versionchanged:: 1.2.0: the mode is specified as a diff --git a/src/unix/tty.c b/src/unix/tty.c index 9038d85a..7783548a 100644 --- a/src/unix/tty.c +++ b/src/unix/tty.c @@ -35,10 +35,19 @@ static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER; int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) { + uv_handle_type type; int flags; int newfd; int r; + /* File descriptors that refer to files cannot be monitored with epoll. + * That restriction also applies to character devices like /dev/random + * (but obviously not /dev/tty.) + */ + type = uv_guess_handle(fd); + if (type == UV_FILE || type == UV_UNKNOWN_HANDLE) + return -EINVAL; + flags = 0; newfd = -1; @@ -54,7 +63,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) { * different struct file, hence changing its properties doesn't affect * other processes. */ - if (isatty(fd)) { + if (type == UV_TTY) { r = uv__open_cloexec("/dev/tty", O_RDWR); if (r < 0) { diff --git a/test/test-list.h b/test/test-list.h index aac15e0d..a021319f 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -43,6 +43,7 @@ TEST_DECLARE (semaphore_1) TEST_DECLARE (semaphore_2) TEST_DECLARE (semaphore_3) TEST_DECLARE (tty) +TEST_DECLARE (tty_file) TEST_DECLARE (stdio_over_pipes) TEST_DECLARE (ip6_pton) TEST_DECLARE (ipc_listen_before_write) @@ -343,6 +344,7 @@ TASK_LIST_START #endif TEST_ENTRY (pipe_set_non_blocking) TEST_ENTRY (tty) + TEST_ENTRY (tty_file) TEST_ENTRY (stdio_over_pipes) TEST_ENTRY (ip6_pton) TEST_ENTRY (ipc_listen_before_write) diff --git a/test/test-tty.c b/test/test-tty.c index cb742fe1..c4203334 100644 --- a/test/test-tty.c +++ b/test/test-tty.c @@ -135,3 +135,45 @@ TEST_IMPL(tty) { MAKE_VALGRIND_HAPPY(); return 0; } + + +TEST_IMPL(tty_file) { +#ifndef _WIN32 + uv_loop_t loop; + uv_tty_t tty; + int fd; + + ASSERT(0 == uv_loop_init(&loop)); + + fd = open("test/fixtures/empty_file", O_RDONLY); + if (fd != -1) { + ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); + ASSERT(0 == close(fd)); + } + + fd = open("/dev/random", O_RDONLY); + if (fd != -1) { + ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); + ASSERT(0 == close(fd)); + } + + fd = open("/dev/zero", O_RDONLY); + if (fd != -1) { + ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); + ASSERT(0 == close(fd)); + } + + fd = open("/dev/tty", O_RDONLY); + if (fd != -1) { + ASSERT(0 == uv_tty_init(&loop, &tty, fd, 1)); + ASSERT(0 == close(fd)); + } + + uv_close((uv_handle_t*) &tty, NULL); + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + ASSERT(0 == uv_loop_close(&loop)); + + MAKE_VALGRIND_HAPPY(); +#endif + return 0; +} |