/* This function is async signal-safe, meaning that it's safe to call from * inside a signal handler _unless_ execution was inside uv_tty_set_mode()'s * critical section when the signal was raised. */ int uv_tty_reset_mode(void) { int err; if (!uv_spinlock_trylock(&termios_spinlock)) return -EBUSY; /* In uv_tty_set_mode(). */ err = 0; if (orig_termios_fd != -1) if (tcsetattr(orig_termios_fd, TCSANOW, &orig_termios)) err = -errno; uv_spinlock_unlock(&termios_spinlock); return err; }
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; }
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; }
/* This function is async signal-safe, meaning that it's safe to call from * inside a signal handler _unless_ execution was inside uv_tty_set_mode()'s * critical section when the signal was raised. */ int uv_tty_reset_mode(void) { int saved_errno; int err; saved_errno = errno; if (!uv_spinlock_trylock(&termios_spinlock)) return UV_EBUSY; /* In uv_tty_set_mode(). */ err = 0; if (orig_termios_fd != -1) if (tcsetattr(orig_termios_fd, TCSANOW, &orig_termios)) err = UV__ERR(errno); uv_spinlock_unlock(&termios_spinlock); errno = saved_errno; return err; }