diff options
Diffstat (limited to 'drivers/tty/pty.c')
| -rw-r--r-- | drivers/tty/pty.c | 30 | 
1 files changed, 22 insertions, 8 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index a82b39939a9..4219f040adb 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);  |