V4L/DVB (10978): Report tuning algorith correctly
[safe/jmp/linux-2.6] / drivers / char / pty.c
index 3c6b791..31038a0 100644 (file)
@@ -5,8 +5,6 @@
  *
  *  Added support for a Unix98-style ptmx device.
  *    -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
- *  Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to
- *      waiting writers -- Sapan Bhatia <sapan@corewars.org>
  *
  *  When reading this code see also fs/devpts. In particular note that the
  *  driver_data field is used by the devpts side as a binding to the devpts
@@ -34,7 +32,7 @@
 
 /* These are global because they are accessed in tty_io.c */
 #ifdef CONFIG_UNIX98_PTYS
-struct tty_driver *ptm_driver;
+static struct tty_driver *ptm_driver;
 static struct tty_driver *pts_driver;
 #endif
 
@@ -217,7 +215,6 @@ static int pty_open(struct tty_struct *tty, struct file *filp)
 
        clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
        set_bit(TTY_THROTTLED, &tty->flags);
-       set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
        retval = 0;
 out:
        return retval;
@@ -230,6 +227,53 @@ static void pty_set_termios(struct tty_struct *tty,
        tty->termios->c_cflag |= (CS8 | CREAD);
 }
 
+/**
+ *     pty_do_resize           -       resize event
+ *     @tty: tty being resized
+ *     @ws: window size being set.
+ *
+ *     Update the termios variables and send the neccessary signals to
+ *     peform a terminal resize correctly
+ */
+
+int pty_resize(struct tty_struct *tty,  struct winsize *ws)
+{
+       struct pid *pgrp, *rpgrp;
+       unsigned long flags;
+       struct tty_struct *pty = tty->link;
+
+       /* For a PTY we need to lock the tty side */
+       mutex_lock(&tty->termios_mutex);
+       if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
+               goto done;
+
+       /* Get the PID values and reference them so we can
+          avoid holding the tty ctrl lock while sending signals.
+          We need to lock these individually however. */
+
+       spin_lock_irqsave(&tty->ctrl_lock, flags);
+       pgrp = get_pid(tty->pgrp);
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+
+       spin_lock_irqsave(&pty->ctrl_lock, flags);
+       rpgrp = get_pid(pty->pgrp);
+       spin_unlock_irqrestore(&pty->ctrl_lock, flags);
+
+       if (pgrp)
+               kill_pgrp(pgrp, SIGWINCH, 1);
+       if (rpgrp != pgrp && rpgrp)
+               kill_pgrp(rpgrp, SIGWINCH, 1);
+
+       put_pid(pgrp);
+       put_pid(rpgrp);
+
+       tty->winsize = *ws;
+       pty->winsize = *ws;     /* Never used so will go away soon */
+done:
+       mutex_unlock(&tty->termios_mutex);
+       return 0;
+}
+
 static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
 {
        struct tty_struct *o_tty;
@@ -290,6 +334,7 @@ static const struct tty_operations pty_ops = {
        .chars_in_buffer = pty_chars_in_buffer,
        .unthrottle = pty_unthrottle,
        .set_termios = pty_set_termios,
+       .resize = pty_resize
 };
 
 /* Traditional BSD devices */
@@ -319,6 +364,7 @@ static const struct tty_operations pty_ops_bsd = {
        .unthrottle = pty_unthrottle,
        .set_termios = pty_set_termios,
        .ioctl = pty_bsd_ioctl,
+       .resize = pty_resize
 };
 
 static void __init legacy_pty_init(void)
@@ -488,7 +534,6 @@ static void pty_unix98_shutdown(struct tty_struct *tty)
 {
        /* We have our own method as we don't use the tty index */
        kfree(tty->termios);
-       kfree(tty->termios_locked);
 }
 
 /* We have no need to install and remove our tty objects as devpts does all
@@ -509,20 +554,17 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
        }
        initialize_tty_struct(o_tty, driver->other, idx);
 
-       tty->termios = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
+       tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
        if (tty->termios == NULL)
                goto free_mem_out;
        *tty->termios = driver->init_termios;
-       tty->termios_locked = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
-       if (tty->termios_locked == NULL)
-               goto free_mem_out;
-       o_tty->termios = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
+       tty->termios_locked = tty->termios + 1;
+
+       o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
        if (o_tty->termios == NULL)
                goto free_mem_out;
        *o_tty->termios = driver->other->init_termios;
-       o_tty->termios_locked = kzalloc(sizeof(struct ktermios), GFP_KERNEL);
-       if (o_tty->termios_locked == NULL)
-               goto free_mem_out;
+       o_tty->termios_locked = o_tty->termios + 1;
 
        tty_driver_kref_get(driver->other);
        if (driver->subtype == PTY_TYPE_MASTER)
@@ -540,10 +582,10 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
        pty_count++;
        return 0;
 free_mem_out:
-       pty_unix98_shutdown(o_tty);
+       kfree(o_tty->termios);
        module_put(o_tty->driver->owner);
        free_tty_struct(o_tty);
-       pty_unix98_shutdown(tty);
+       kfree(tty->termios);
        return -ENOMEM;
 }
 
@@ -565,7 +607,8 @@ static const struct tty_operations ptm_unix98_ops = {
        .unthrottle = pty_unthrottle,
        .set_termios = pty_set_termios,
        .ioctl = pty_unix98_ioctl,
-       .shutdown = pty_unix98_shutdown
+       .shutdown = pty_unix98_shutdown,
+       .resize = pty_resize
 };
 
 static const struct tty_operations pty_unix98_ops = {