summaryrefslogtreecommitdiff
path: root/deps/uv/src/unix/tty.c
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2012-10-30 23:06:03 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2012-11-01 01:22:16 +0100
commitab1e66d93f4eddf23f62fd69094690124357e3e9 (patch)
tree7c5cc31b101f713fc23e828751b9eef8be573f5e /deps/uv/src/unix/tty.c
parenta12c42ca2f8d5ce71c75cab334a53bd71bdaea09 (diff)
downloadandroid-node-v8-ab1e66d93f4eddf23f62fd69094690124357e3e9.tar.gz
android-node-v8-ab1e66d93f4eddf23f62fd69094690124357e3e9.tar.bz2
android-node-v8-ab1e66d93f4eddf23f62fd69094690124357e3e9.zip
deps: upgrade libuv to 97c527a
Diffstat (limited to 'deps/uv/src/unix/tty.c')
-rw-r--r--deps/uv/src/unix/tty.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c
index 3ef9064a10..aa42c20532 100644
--- a/deps/uv/src/unix/tty.c
+++ b/deps/uv/src/unix/tty.c
@@ -34,18 +34,53 @@ static struct termios orig_termios;
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
+ int flags;
+ int newfd;
+ int r;
+
uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);
- 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;
+ /* 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 = open("/dev/tty", O_RDWR);
+
+ if (newfd == -1)
+ return uv__set_sys_error(loop, errno);
+
+ do
+ r = dup2(newfd, fd);
+ while (r == -1 && (errno == EINTR || errno == EBUSY));
+
+ /* 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.
+ */
+ if (r == -1 && errno != EINVAL) {
+ close(newfd);
+ return uv__set_sys_error(loop, errno);
+ }
+
+ fd = newfd;
}
+ 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;
}