diff --git a/src/common/io/io_unix.c b/src/common/io/io_unix.c index 501e23015..20eb3b3b0 100644 --- a/src/common/io/io_unix.c +++ b/src/common/io/io_unix.c @@ -136,29 +136,44 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...) if (instance.config.display.pipe) return "Not supported in --pipe mode"; + int fin = STDIN_FILENO, fout = STDOUT_FILENO; + FF_AUTO_CLOSE_FD int ftty = -1; + + if (!isatty(STDIN_FILENO)) + { + if (ftty < 0) + ftty = open("/dev/tty", O_RDWR | O_CLOEXEC); + fin = ftty; + } + if (!isatty(STDOUT_FILENO)) + { + if (ftty < 0) + ftty = open("/dev/tty", O_RDWR | O_CLOEXEC); + fout = ftty; + } + struct termios oldTerm, newTerm; - if(tcgetattr(STDIN_FILENO, &oldTerm) == -1) + if(tcgetattr(fin, &oldTerm) == -1) return "tcgetattr(STDIN_FILENO, &oldTerm) failed"; newTerm = oldTerm; newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO); - if(tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) == -1) + if(tcsetattr(fin, TCSANOW, &newTerm) == -1) return "tcsetattr(STDIN_FILENO, TCSANOW, &newTerm)"; - fputs(request, stdout); - fflush(stdout); + ffWriteFDData(fout, strlen(request), request); //Give the terminal 35ms to respond - if(poll(&(struct pollfd) { .fd = STDIN_FILENO, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0) + if(poll(&(struct pollfd) { .fd = fin, .events = POLLIN }, 1, FF_IO_TERM_RESP_WAIT_MS) <= 0) { - tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm); + tcsetattr(fin, TCSANOW, &oldTerm); return "poll() timeout or failed"; } char buffer[512]; - ssize_t bytesRead = read(STDIN_FILENO, buffer, sizeof(buffer) - 1); + ssize_t bytesRead = read(fin, buffer, sizeof(buffer) - 1); - tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm); + tcsetattr(fin, TCSANOW, &oldTerm); if(bytesRead <= 0) return "read(STDIN_FILENO, buffer, sizeof(buffer) - 1) failed";