summaryrefslogtreecommitdiffstats
path: root/drivers/tty/pty.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/pty.c')
-rw-r--r--drivers/tty/pty.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index a82b399..4219f04 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -4,9 +4,6 @@
* Added support for a Unix98-style ptmx device.
* -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
*
- * 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
- * inode.
*/
#include <linux/module.h>
@@ -59,7 +56,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
#ifdef CONFIG_UNIX98_PTYS
if (tty->driver == ptm_driver) {
mutex_lock(&devpts_mutex);
- devpts_pty_kill(tty->link);
+ devpts_pty_kill(tty->link->driver_data);
mutex_unlock(&devpts_mutex);
}
#endif
@@ -96,7 +93,7 @@ static void pty_unthrottle(struct tty_struct *tty)
static int pty_space(struct tty_struct *to)
{
- int n = 8192 - to->buf.memory_used;
+ int n = 8192 - to->port->buf.memory_used;
if (n < 0)
return 0;
return n;
@@ -348,6 +345,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
tty_port_init(ports[1]);
o_tty->port = ports[0];
tty->port = ports[1];
+ o_tty->port->itty = o_tty;
tty_driver_kref_get(driver);
tty->count++;
@@ -366,8 +364,15 @@ err:
return retval;
}
+/* this is called once with whichever end is closed last */
+static void pty_unix98_shutdown(struct tty_struct *tty)
+{
+ devpts_kill_index(tty->driver_data, tty->index);
+}
+
static void pty_cleanup(struct tty_struct *tty)
{
+ tty->port->itty = NULL;
kfree(tty->port);
}
@@ -547,7 +552,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
struct tty_struct *tty;
mutex_lock(&devpts_mutex);
- tty = devpts_get_tty(pts_inode, idx);
+ tty = devpts_get_priv(pts_inode);
mutex_unlock(&devpts_mutex);
/* Master must be open before slave */
if (!tty)
@@ -581,6 +586,7 @@ static const struct tty_operations ptm_unix98_ops = {
.set_termios = pty_set_termios,
.ioctl = pty_unix98_ioctl,
.resize = pty_resize,
+ .shutdown = pty_unix98_shutdown,
.cleanup = pty_cleanup
};
@@ -596,6 +602,7 @@ static const struct tty_operations pty_unix98_ops = {
.chars_in_buffer = pty_chars_in_buffer,
.unthrottle = pty_unthrottle,
.set_termios = pty_set_termios,
+ .shutdown = pty_unix98_shutdown,
.cleanup = pty_cleanup,
};
@@ -614,6 +621,7 @@ static const struct tty_operations pty_unix98_ops = {
static int ptmx_open(struct inode *inode, struct file *filp)
{
struct tty_struct *tty;
+ struct inode *slave_inode;
int retval;
int index;
@@ -650,15 +658,21 @@ static int ptmx_open(struct inode *inode, struct file *filp)
tty_add_file(tty, filp);
- retval = devpts_pty_new(inode, tty->link);
- if (retval)
+ slave_inode = devpts_pty_new(inode,
+ MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index,
+ tty->link);
+ if (IS_ERR(slave_inode)) {
+ retval = PTR_ERR(slave_inode);
goto err_release;
+ }
retval = ptm_driver->ops->open(tty, filp);
if (retval)
goto err_release;
tty_unlock(tty);
+ tty->driver_data = inode;
+ tty->link->driver_data = slave_inode;
return 0;
err_release:
tty_unlock(tty);
OpenPOWER on IntegriCloud