IO (Linux): make sure stdin and stdout are tty when querying terminal

This commit is contained in:
李通洲
2024-06-25 09:06:21 +08:00
parent a210128592
commit b5e199d2b2
+23 -8
View File
@@ -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";