* redirect lock for undoing redirection
* file list lock for manipulating list of ttys
* tty_ldiscs_lock from called functions
- * termios_mutex resetting termios data
+ * termios_rwsem resetting termios data
* tasklist_lock to walk task list for hangup event
* ->siglock to protect ->signal/->sighand
*/
tty_lock(tty);
+ if (test_bit(TTY_HUPPED, &tty->flags)) {
+ tty_unlock(tty);
+ return;
+ }
+
/* some functions below drop BTM, so we need this bit */
set_bit(TTY_HUPPING, &tty->flags);
spin_lock_irq(&tty->ctrl_lock);
clear_bit(TTY_THROTTLED, &tty->flags);
- clear_bit(TTY_PUSH, &tty->flags);
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
put_pid(tty->session);
put_pid(tty->pgrp);
struct pid *tty_pgrp = tty_get_pgrp(tty);
if (tty_pgrp) {
kill_pgrp(tty_pgrp, SIGHUP, on_exit);
- kill_pgrp(tty_pgrp, SIGCONT, on_exit);
+ if (!on_exit)
+ kill_pgrp(tty_pgrp, SIGCONT, on_exit);
put_pid(tty_pgrp);
}
}
*
* Copies the kernel idea of the window size into the user buffer.
*
- * Locking: tty->termios_mutex is taken to ensure the winsize data
+ * Locking: tty->winsize_mutex is taken to ensure the winsize data
* is consistent.
*/
{
int err;
- mutex_lock(&tty->termios_mutex);
+ mutex_lock(&tty->winsize_mutex);
err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
- mutex_unlock(&tty->termios_mutex);
+ mutex_unlock(&tty->winsize_mutex);
return err ? -EFAULT: 0;
}
unsigned long flags;
/* Lock the tty */
- mutex_lock(&tty->termios_mutex);
+ mutex_lock(&tty->winsize_mutex);
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
goto done;
/* Get the PID values and reference them so we can
tty->winsize = *ws;
done:
- mutex_unlock(&tty->termios_mutex);
+ mutex_unlock(&tty->winsize_mutex);
return 0;
}
EXPORT_SYMBOL(tty_do_resize);
tty->session = NULL;
tty->pgrp = NULL;
mutex_init(&tty->legacy_mutex);
- mutex_init(&tty->termios_mutex);
+ mutex_init(&tty->throttle_mutex);
+ init_rwsem(&tty->termios_rwsem);
+ mutex_init(&tty->winsize_mutex);
init_ldsem(&tty->ldisc_sem);
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);