Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5785c95b authored by Arjan van de Ven's avatar Arjan van de Ven Committed by Linus Torvalds
Browse files

[PATCH] tty: make termios_sem a mutex



[akpm@osdl.org: fix]
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Arjan van de Ven <arjan@infradead.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 54306cf0
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -618,9 +618,9 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
 
static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
{
	down(&tty->termios_sem);
	mutex_lock(&tty->termios_mutex);
	tty->termios->c_line = num;
	up(&tty->termios_sem);
	mutex_unlock(&tty->termios_mutex);
}

/*
@@ -1338,9 +1338,9 @@ static void do_tty_hangup(void *data)
	 */
	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
	{
		down(&tty->termios_sem);
		mutex_lock(&tty->termios_mutex);
		*tty->termios = tty->driver->init_termios;
		up(&tty->termios_sem);
		mutex_unlock(&tty->termios_mutex);
	}
	
	/* Defer ldisc switch */
@@ -2750,9 +2750,9 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg)
{
	int err;

	down(&tty->termios_sem);
	mutex_lock(&tty->termios_mutex);
	err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
	up(&tty->termios_sem);
	mutex_unlock(&tty->termios_mutex);

	return err ? -EFAULT: 0;
}
@@ -2782,14 +2782,15 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
	if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
		return -EFAULT;

	down(&tty->termios_sem);
	mutex_lock(&tty->termios_mutex);
	if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg)))
		goto done;

#ifdef CONFIG_VT
	if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) {
		if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col, tmp_ws.ws_row)) {
			up(&tty->termios_sem);
		if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col,
					tmp_ws.ws_row)) {
			mutex_unlock(&tty->termios_mutex);
 			return -ENXIO;
		}
	}
@@ -2801,7 +2802,7 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
	tty->winsize = tmp_ws;
	real_tty->winsize = tmp_ws;
done:
	up(&tty->termios_sem);
	mutex_unlock(&tty->termios_mutex);
	return 0;
}

@@ -3576,7 +3577,7 @@ static void initialize_tty_struct(struct tty_struct *tty)
	tty_buffer_init(tty);
	INIT_WORK(&tty->buf.work, flush_to_ldisc, tty);
	init_MUTEX(&tty->buf.pty_sem);
	init_MUTEX(&tty->termios_sem);
	mutex_init(&tty->termios_mutex);
	init_waitqueue_head(&tty->write_wait);
	init_waitqueue_head(&tty->read_wait);
	INIT_WORK(&tty->hangup_work, do_tty_hangup, tty);
+9 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/mutex.h>

#include <asm/io.h>
#include <asm/uaccess.h>
@@ -131,7 +132,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios

	/* FIXME: we need to decide on some locking/ordering semantics
	   for the set_termios notification eventually */
	down(&tty->termios_sem);
	mutex_lock(&tty->termios_mutex);

	*tty->termios = *new_termios;
	unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
@@ -176,7 +177,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
			(ld->set_termios)(tty, &old_termios);
		tty_ldisc_deref(ld);
	}
	up(&tty->termios_sem);
	mutex_unlock(&tty->termios_mutex);
}

/**
@@ -284,13 +285,13 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
{
	struct sgttyb tmp;

	down(&tty->termios_sem);
	mutex_lock(&tty->termios_mutex);
	tmp.sg_ispeed = 0;
	tmp.sg_ospeed = 0;
	tmp.sg_erase = tty->termios->c_cc[VERASE];
	tmp.sg_kill = tty->termios->c_cc[VKILL];
	tmp.sg_flags = get_sgflags(tty);
	up(&tty->termios_sem);
	mutex_unlock(&tty->termios_mutex);
	
	return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
@@ -345,12 +346,12 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
	if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
		return -EFAULT;

	down(&tty->termios_sem);		
	mutex_lock(&tty->termios_mutex);
	termios =  *tty->termios;
	termios.c_cc[VERASE] = tmp.sg_erase;
	termios.c_cc[VKILL] = tmp.sg_kill;
	set_sgflags(&termios, tmp.sg_flags);
	up(&tty->termios_sem);
	mutex_unlock(&tty->termios_mutex);
	change_termios(tty, &termios);
	return 0;
}
@@ -592,11 +593,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
		case TIOCSSOFTCAR:
			if (get_user(arg, (unsigned int __user *) arg))
				return -EFAULT;
			down(&tty->termios_sem);
			mutex_lock(&tty->termios_mutex);
			tty->termios->c_cflag =
				((tty->termios->c_cflag & ~CLOCAL) |
				 (arg ? CLOCAL : 0));
			up(&tty->termios_sem);
			mutex_unlock(&tty->termios_mutex);
			return 0;
		default:
			return -ENOIOCTLCMD;
+1 −1
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ struct tty_struct {
	struct tty_driver *driver;
	int index;
	struct tty_ldisc ldisc;
	struct semaphore termios_sem;
	struct mutex termios_mutex;
	struct termios *termios, *termios_locked;
	char name[64];
	int pgrp;