int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) { struct termios tmp; int fd; if (tty->mode == (int) mode) return 0; fd = uv__stream_fd(tty); if (tty->mode == UV_TTY_MODE_NORMAL && mode != UV_TTY_MODE_NORMAL) { if (tcgetattr(fd, &tty->orig_termios)) return -errno; /* This is used for uv_tty_reset_mode() */ uv_spinlock_lock(&termios_spinlock); if (orig_termios_fd == -1) { orig_termios = tty->orig_termios; orig_termios_fd = fd; } uv_spinlock_unlock(&termios_spinlock); } tmp = tty->orig_termios; switch (mode) { case UV_TTY_MODE_NORMAL: break; case UV_TTY_MODE_RAW: tmp.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); tmp.c_oflag |= (ONLCR); tmp.c_cflag |= (CS8); tmp.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); tmp.c_cc[VMIN] = 1; tmp.c_cc[VTIME] = 0; break; case UV_TTY_MODE_IO: uv__tty_make_raw(&tmp); break; } /* Apply changes after draining */ if (tcsetattr(fd, TCSADRAIN, &tmp)) return -errno; tty->mode = mode; return 0; }
int uv_tty_set_mode(uv_tty_t* tty, int mode) { struct termios raw; int fd; fd = uv__stream_fd(tty); if (mode && tty->mode == 0) { /* on */ if (tcgetattr(fd, &tty->orig_termios)) return -errno; /* This is used for uv_tty_reset_mode() */ uv_spinlock_lock(&termios_spinlock); if (orig_termios_fd == -1) { orig_termios = tty->orig_termios; orig_termios_fd = fd; } uv_spinlock_unlock(&termios_spinlock); raw = tty->orig_termios; #ifdef _BSD_SOURCE cfmakeraw(&raw); #else raw.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); raw.c_oflag &= ~OPOST; raw.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); raw.c_cflag &= ~(CSIZE | PARENB); raw.c_cflag |= CS8; #endif raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* Put terminal in raw mode after draining */ if (tcsetattr(fd, TCSADRAIN, &raw)) return -errno; tty->mode = 1; } else if (mode == 0 && tty->mode) { /* off */ /* Put terminal in original mode after flushing */ if (tcsetattr(fd, TCSAFLUSH, &tty->orig_termios)) return -errno; tty->mode = 0; } return 0; }