Src/builtin.c | 2 +- Src/init.c | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Src/builtin.c b/Src/builtin.c index 9358e8b..ee14f91 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5674,7 +5674,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) if (!zleactive) { if (SHTTY == -1) { /* need to open /dev/tty specially */ - if ((SHTTY = open("/dev/tty", O_RDWR|O_NOCTTY)) != -1) { + if ((SHTTY = block_open("/dev/tty", O_RDWR|O_NOCTTY)) != -1) { haso = 1; oshout = shout; init_shout(); diff --git a/Src/init.c b/Src/init.c index 102276a..238f6ed 100644 --- a/Src/init.c +++ b/Src/init.c @@ -545,7 +545,7 @@ init_io(void) if (isatty(0)) { zsfree(ttystrname); if ((ttystrname = ztrdup(ttyname(0)))) { - SHTTY = movefd(open(ttystrname, O_RDWR | O_NOCTTY)); + SHTTY = movefd(block_open(ttystrname, O_RDWR | O_NOCTTY)); #ifdef TIOCNXCL /* * See if the terminal claims to be busy. If so, and fd 0 @@ -586,7 +586,7 @@ init_io(void) ttystrname = ztrdup(ttyname(1)); } if (SHTTY == -1 && - (SHTTY = movefd(open("/dev/tty", O_RDWR | O_NOCTTY))) != -1) { + (SHTTY = movefd(block_open("/dev/tty", O_RDWR | O_NOCTTY))) != -1) { zsfree(ttystrname); ttystrname = ztrdup(ttyname(SHTTY)); } @@ -1713,3 +1713,33 @@ zsh_main(UNUSED(int argc), char **argv) : "use 'logout' to logout."); } } + +/**/ +int +block_open (const char *tty, int flags) +{ + int saved_errno; + int fd; + + if ((flags & O_NONBLOCK) == 0) { + fd = open (tty, flags | O_NONBLOCK); + if (fd == -1) + return fd; + flags = fcntl(fd, F_GETFL); + if (flags == -1) + goto bad; + flags &= ~O_NONBLOCK; + if (fcntl(fd, F_SETFL, flags) == -1) + goto bad; + } + else + fd = open (tty, flags); + + return fd; + +bad: + saved_errno = errno; + close (fd); + errno = saved_errno; + return -1; +}