aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/src/tty.rst4
-rw-r--r--src/unix/tty.c11
-rw-r--r--test/test-list.h2
-rw-r--r--test/test-tty.c42
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;
+}