summaryrefslogtreecommitdiff
path: root/deps/uv/src/unix/tty.c
diff options
context:
space:
mode:
authorTimothy J Fontaine <tjfontaine@gmail.com>2014-03-10 17:01:21 -0700
committerTimothy J Fontaine <tjfontaine@gmail.com>2014-03-10 17:01:21 -0700
commite92d35d80be6e193cb547e94c6fbf3654542dbaa (patch)
treebede6f090b8cca1397728634b03b31cfa7a4334c /deps/uv/src/unix/tty.c
parentb444392a98e66b49dfee8c7e36c59d4e7c6ea1ac (diff)
downloadandroid-node-v8-e92d35d80be6e193cb547e94c6fbf3654542dbaa.tar.gz
android-node-v8-e92d35d80be6e193cb547e94c6fbf3654542dbaa.tar.bz2
android-node-v8-e92d35d80be6e193cb547e94c6fbf3654542dbaa.zip
uv: Upgrade to v0.11.22
Diffstat (limited to 'deps/uv/src/unix/tty.c')
-rw-r--r--deps/uv/src/unix/tty.c65
1 files changed, 50 insertions, 15 deletions
diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c
index ca9459dd0d..c7ed101a75 100644
--- a/deps/uv/src/unix/tty.c
+++ b/deps/uv/src/unix/tty.c
@@ -35,26 +35,61 @@ 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__stream_init(loop, (uv_stream_t*)tty, UV_TTY);
+ int flags;
+ int newfd;
+ int r;
+
+ newfd = -1;
+
+ uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY);
+
+ /* Reopen the file descriptor when it refers to a tty. This lets us put the
+ * tty in non-blocking mode without affecting other processes that share it
+ * with us.
+ *
+ * Example: `node | cat` - if we put our fd 0 in non-blocking mode, it also
+ * affects fd 1 of `cat` because both file descriptors refer to the same
+ * struct file in the kernel. When we reopen our fd 0, it points to a
+ * different struct file, hence changing its properties doesn't affect
+ * other processes.
+ */
+ if (isatty(fd)) {
+ newfd = uv__open_cloexec("/dev/tty", O_RDWR);
+
+ if (newfd == -1)
+ return -errno;
-#if defined(__APPLE__)
- {
- int err = uv__stream_try_select((uv_stream_t*) tty, &fd);
- if (err)
- return err;
+ r = uv__dup2_cloexec(newfd, fd);
+ if (r < 0 && r != -EINVAL) {
+ /* EINVAL means newfd == fd which could conceivably happen if another
+ * thread called close(fd) between our calls to isatty() and open().
+ * That's a rather unlikely event but let's handle it anyway.
+ */
+ uv__close(newfd);
+ return r;
+ }
+
+ fd = newfd;
}
-#endif /* defined(__APPLE__) */
-
- if (readable) {
- uv__nonblock(fd, 1);
- uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_READABLE);
- } else {
- /* Note: writable tty we set to blocking mode. */
- uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_WRITABLE);
- tty->flags |= UV_STREAM_BLOCKING;
+
+#if defined(__APPLE__)
+ r = uv__stream_try_select((uv_stream_t*) tty, &fd);
+ if (r) {
+ if (newfd != -1)
+ uv__close(newfd);
+ return r;
}
+#endif
+ if (readable)
+ flags = UV_STREAM_READABLE;
+ else
+ flags = UV_STREAM_WRITABLE;
+
+ uv__nonblock(fd, 1);
+ uv__stream_open((uv_stream_t*) tty, fd, flags);
tty->mode = 0;
+
return 0;
}