in src/unix-adapter/main.cc [73:139]
static SavedTermiosMode setRawTerminalMode(
bool allowNonTtys, bool setStdout, bool setStderr)
{
SavedTermiosMode ret;
const char *const kNames[3] = { "stdin", "stdout", "stderr" };
ret.valid[0] = true;
ret.valid[1] = setStdout;
ret.valid[2] = setStderr;
for (int i = 0; i < 3; ++i) {
if (!ret.valid[i]) {
continue;
}
if (!isatty(i)) {
ret.valid[i] = false;
if (!allowNonTtys) {
fprintf(stderr, "%s is not a tty\n", kNames[i]);
exit(1);
}
} else {
ret.valid[i] = true;
if (tcgetattr(i, &ret.mode[i]) < 0) {
perror("tcgetattr failed");
exit(1);
}
}
}
if (ret.valid[STDIN_FILENO]) {
termios buf;
if (tcgetattr(STDIN_FILENO, &buf) < 0) {
perror("tcgetattr failed");
exit(1);
}
buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
buf.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
buf.c_cflag &= ~(CSIZE | PARENB);
buf.c_cflag |= CS8;
buf.c_cc[VMIN] = 1; // blocking read
buf.c_cc[VTIME] = 0;
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &buf) < 0) {
fprintf(stderr, "tcsetattr failed\n");
exit(1);
}
}
for (int i = STDOUT_FILENO; i <= STDERR_FILENO; ++i) {
if (!ret.valid[i]) {
continue;
}
termios buf;
if (tcgetattr(i, &buf) < 0) {
perror("tcgetattr failed");
exit(1);
}
buf.c_cflag &= ~(CSIZE | PARENB);
buf.c_cflag |= CS8;
buf.c_oflag &= ~OPOST;
if (tcsetattr(i, TCSAFLUSH, &buf) < 0) {
fprintf(stderr, "tcsetattr failed\n");
exit(1);
}
}
return ret;
}