static int set_termios(struct tty_struct * tty, struct termios * termios, int channel) { int i, retsig; /* If we try to set the state of terminal and we're not in the foreground, send a SIGTTOU. If the signal is blocked or ignored, go ahead and perform the operation. POSIX 7.2) */ if ((current->tty == channel) && (tty->pgrp != current->pgrp)) { retsig = tty_signal(SIGTTOU, tty); if (retsig == -ERESTARTSYS || retsig == -EINTR) return retsig; } for (i=0 ; i< (sizeof (*termios)) ; i++) ((char *)&tty->termios)[i]=get_fs_byte(i+(char *)termios); change_speed(tty); return 0; }
/* * Catch TTY related signals and forward them * to the appropriate processes. */ static void exception_handler(int sig) { /* * Handle signals from tty input. */ switch (sig) { case SIGINT: case SIGQUIT: case SIGTSTP: case SIGTTIN: case SIGTTOU: case SIGINFO: case SIGWINCH: case SIGIO: if (ttydev != NODEV) tty_signal(sig); break; } exception_return(); }
/* * This only works as the 386 is low-byt-first */ static int set_termio(struct tty_struct * tty, struct termio * termio, int channel) { int i, retsig; struct termio tmp_termio; if ((current->tty == channel) && (tty->pgrp != current->pgrp)) { retsig = tty_signal(SIGTTOU, tty); if (retsig == -ERESTARTSYS || retsig == -EINTR) return retsig; } for (i=0 ; i< (sizeof (*termio)) ; i++) ((char *)&tmp_termio)[i]=get_fs_byte(i+(char *)termio); *(unsigned short *)&tty->termios.c_iflag = tmp_termio.c_iflag; *(unsigned short *)&tty->termios.c_oflag = tmp_termio.c_oflag; *(unsigned short *)&tty->termios.c_cflag = tmp_termio.c_cflag; *(unsigned short *)&tty->termios.c_lflag = tmp_termio.c_lflag; tty->termios.c_line = tmp_termio.c_line; for(i=0 ; i < NCC ; i++) tty->termios.c_cc[i] = tmp_termio.c_cc[i]; change_speed(tty); return 0; }
/** * @brief Handles a TTY interrupt. * * @details Handles a TTY interrupt, putting the received character @p ch in the * raw input buffer of the currently active TTY device. Addiitonally, * if echo is enable for such device, @p ch is output to the terminal. * * @param ch Received character. */ PUBLIC void tty_int(unsigned char ch) { /* Output echo character. */ if (active->term.c_lflag & ECHO) { /* Canonical mode. */ if (active->term.c_lflag & ICANON) { /* * Let these characters be handled * when the line is being parsed. */ if ((ch == ERASE_CHAR(*active)) || (ch == KILL_CHAR(*active)) || (ch == EOL_CHAR(*active)) || (ch == EOF_CHAR(*active))) goto out1; } /* Non-printable characters. */ if ((ch < 32) && (ch != '\n') && (ch != '\t')) { console_put('^', WHITE); console_put(ch + 64, WHITE); console_put('\n', WHITE); } /* Any character. */ else console_put(ch, WHITE); } /* * Handle signals. Note that if a signal is * received, no character is put in the raw * input buffer. Otherwise, we could mess it up. */ if (active->term.c_lflag & ISIG) { /* * Interrupt. Send signal to all * process in the same group. */ if (ch == INTR_CHAR(*active)) { tty_signal(SIGINT); goto out0; } /* Stop. */ else if (ch == STOP_CHAR(*active)) { active->flags |= TTY_STOPPED; return; } /* Start. */ else if (ch == START_CHAR(*active)) { active->flags &= ~TTY_STOPPED; wakeup(&active->output.chain); return; } /* Suspend. */ else if (ch == SUSP_CHAR(*active)) { tty_signal(SIGTSTP); goto out0; } /* Quit. */ else if (ch == QUIT_CHAR(*active)) { tty_signal(SIGQUIT); goto out0; } } out1: KBUFFER_PUT(active->rinput, ch); out0: wakeup(&active->rinput.chain); }