* Called when a signal is being sent due to terminal input.
* Called from the driver receive_buf path so serialized.
*
+ * Performs input and output flush if !NOFLSH. In this context, the echo
+ * buffer is 'output'. The signal is processed first to alert any current
+ * readers or writers to discontinue and exit their i/o loops.
+ *
* Locking: ctrl_lock
*/
static void isig(int sig, struct tty_struct *tty)
{
+ struct n_tty_data *ldata = tty->disc_data;
struct pid *tty_pgrp = tty_get_pgrp(tty);
if (tty_pgrp) {
kill_pgrp(tty_pgrp, sig, 1);
put_pid(tty_pgrp);
}
+
+ if (!L_NOFLSH(tty)) {
+ up_read(&tty->termios_rwsem);
+ down_write(&tty->termios_rwsem);
+
+ /* clear echo buffer */
+ mutex_lock(&ldata->output_lock);
+ ldata->echo_head = ldata->echo_tail = 0;
+ ldata->echo_mark = ldata->echo_commit = 0;
+ mutex_unlock(&ldata->output_lock);
+
+ /* clear output buffer */
+ tty_driver_flush_buffer(tty);
+
+ /* clear input buffer */
+ reset_buffer_flags(tty->disc_data);
+
+ /* notify pty master of flush */
+ if (tty->link)
+ n_tty_packet_mode_flush(tty);
+
+ up_write(&tty->termios_rwsem);
+ down_read(&tty->termios_rwsem);
+ }
}
/**
return;
if (I_BRKINT(tty)) {
isig(SIGINT, tty);
- if (!L_NOFLSH(tty)) {
- /* flushing needs exclusive termios_rwsem */
- up_read(&tty->termios_rwsem);
- n_tty_flush_buffer(tty);
- tty_driver_flush_buffer(tty);
- down_read(&tty->termios_rwsem);
- }
return;
}
if (I_PARMRK(tty)) {
static void
n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c)
{
- if (!L_NOFLSH(tty)) {
- /* flushing needs exclusive termios_rwsem */
- up_read(&tty->termios_rwsem);
- n_tty_flush_buffer(tty);
- tty_driver_flush_buffer(tty);
- down_read(&tty->termios_rwsem);
- }
+ isig(signal, tty);
if (I_IXON(tty))
start_tty(tty);
if (L_ECHO(tty)) {
commit_echoes(tty);
} else
process_echoes(tty);
- isig(signal, tty);
return;
}
*
* legacy_mutex - Nested tty locks are necessary for releasing pty pairs.
* The stable lock order is master pty first, then slave pty.
+ * termios_rwsem - The stable lock order is tty_buffer lock->termios_rwsem.
+ * Subclassing this lock enables the slave pty to hold its
+ * termios_rwsem when claiming the master tty_buffer lock.
* tty_buffer lock - slave ptys can claim nested buffer lock when handling
* signal chars. The stable lock order is slave pty, then
* master.