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 a82b39939a9c..4219f040adb8 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -4,9 +4,6 @@ | |||
4 | * Added support for a Unix98-style ptmx device. | 4 | * Added support for a Unix98-style ptmx device. |
5 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 | 5 | * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 |
6 | * | 6 | * |
7 | * When reading this code see also fs/devpts. In particular note that the | ||
8 | * driver_data field is used by the devpts side as a binding to the devpts | ||
9 | * inode. | ||
10 | */ | 7 | */ |
11 | 8 | ||
12 | #include <linux/module.h> | 9 | #include <linux/module.h> |
@@ -59,7 +56,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
59 | #ifdef CONFIG_UNIX98_PTYS | 56 | #ifdef CONFIG_UNIX98_PTYS |
60 | if (tty->driver == ptm_driver) { | 57 | if (tty->driver == ptm_driver) { |
61 | mutex_lock(&devpts_mutex); | 58 | mutex_lock(&devpts_mutex); |
62 | devpts_pty_kill(tty->link); | 59 | devpts_pty_kill(tty->link->driver_data); |
63 | mutex_unlock(&devpts_mutex); | 60 | mutex_unlock(&devpts_mutex); |
64 | } | 61 | } |
65 | #endif | 62 | #endif |
@@ -96,7 +93,7 @@ static void pty_unthrottle(struct tty_struct *tty) | |||
96 | 93 | ||
97 | static int pty_space(struct tty_struct *to) | 94 | static int pty_space(struct tty_struct *to) |
98 | { | 95 | { |
99 | int n = 8192 - to->buf.memory_used; | 96 | int n = 8192 - to->port->buf.memory_used; |
100 | if (n < 0) | 97 | if (n < 0) |
101 | return 0; | 98 | return 0; |
102 | return n; | 99 | return n; |
@@ -348,6 +345,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | |||
348 | tty_port_init(ports[1]); | 345 | tty_port_init(ports[1]); |
349 | o_tty->port = ports[0]; | 346 | o_tty->port = ports[0]; |
350 | tty->port = ports[1]; | 347 | tty->port = ports[1]; |
348 | o_tty->port->itty = o_tty; | ||
351 | 349 | ||
352 | tty_driver_kref_get(driver); | 350 | tty_driver_kref_get(driver); |
353 | tty->count++; | 351 | tty->count++; |
@@ -366,8 +364,15 @@ err: | |||
366 | return retval; | 364 | return retval; |
367 | } | 365 | } |
368 | 366 | ||
367 | /* this is called once with whichever end is closed last */ | ||
368 | static void pty_unix98_shutdown(struct tty_struct *tty) | ||
369 | { | ||
370 | devpts_kill_index(tty->driver_data, tty->index); | ||
371 | } | ||
372 | |||
369 | static void pty_cleanup(struct tty_struct *tty) | 373 | static void pty_cleanup(struct tty_struct *tty) |
370 | { | 374 | { |
375 | tty->port->itty = NULL; | ||
371 | kfree(tty->port); | 376 | kfree(tty->port); |
372 | } | 377 | } |
373 | 378 | ||
@@ -547,7 +552,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, | |||
547 | struct tty_struct *tty; | 552 | struct tty_struct *tty; |
548 | 553 | ||
549 | mutex_lock(&devpts_mutex); | 554 | mutex_lock(&devpts_mutex); |
550 | tty = devpts_get_tty(pts_inode, idx); | 555 | tty = devpts_get_priv(pts_inode); |
551 | mutex_unlock(&devpts_mutex); | 556 | mutex_unlock(&devpts_mutex); |
552 | /* Master must be open before slave */ | 557 | /* Master must be open before slave */ |
553 | if (!tty) | 558 | if (!tty) |
@@ -581,6 +586,7 @@ static const struct tty_operations ptm_unix98_ops = { | |||
581 | .set_termios = pty_set_termios, | 586 | .set_termios = pty_set_termios, |
582 | .ioctl = pty_unix98_ioctl, | 587 | .ioctl = pty_unix98_ioctl, |
583 | .resize = pty_resize, | 588 | .resize = pty_resize, |
589 | .shutdown = pty_unix98_shutdown, | ||
584 | .cleanup = pty_cleanup | 590 | .cleanup = pty_cleanup |
585 | }; | 591 | }; |
586 | 592 | ||
@@ -596,6 +602,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
596 | .chars_in_buffer = pty_chars_in_buffer, | 602 | .chars_in_buffer = pty_chars_in_buffer, |
597 | .unthrottle = pty_unthrottle, | 603 | .unthrottle = pty_unthrottle, |
598 | .set_termios = pty_set_termios, | 604 | .set_termios = pty_set_termios, |
605 | .shutdown = pty_unix98_shutdown, | ||
599 | .cleanup = pty_cleanup, | 606 | .cleanup = pty_cleanup, |
600 | }; | 607 | }; |
601 | 608 | ||
@@ -614,6 +621,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
614 | static int ptmx_open(struct inode *inode, struct file *filp) | 621 | static int ptmx_open(struct inode *inode, struct file *filp) |
615 | { | 622 | { |
616 | struct tty_struct *tty; | 623 | struct tty_struct *tty; |
624 | struct inode *slave_inode; | ||
617 | int retval; | 625 | int retval; |
618 | int index; | 626 | int index; |
619 | 627 | ||
@@ -650,15 +658,21 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
650 | 658 | ||
651 | tty_add_file(tty, filp); | 659 | tty_add_file(tty, filp); |
652 | 660 | ||
653 | retval = devpts_pty_new(inode, tty->link); | 661 | slave_inode = devpts_pty_new(inode, |
654 | if (retval) | 662 | MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index, |
663 | tty->link); | ||
664 | if (IS_ERR(slave_inode)) { | ||
665 | retval = PTR_ERR(slave_inode); | ||
655 | goto err_release; | 666 | goto err_release; |
667 | } | ||
656 | 668 | ||
657 | retval = ptm_driver->ops->open(tty, filp); | 669 | retval = ptm_driver->ops->open(tty, filp); |
658 | if (retval) | 670 | if (retval) |
659 | goto err_release; | 671 | goto err_release; |
660 | 672 | ||
661 | tty_unlock(tty); | 673 | tty_unlock(tty); |
674 | tty->driver_data = inode; | ||
675 | tty->link->driver_data = slave_inode; | ||
662 | return 0; | 676 | return 0; |
663 | err_release: | 677 | err_release: |
664 | tty_unlock(tty); | 678 | tty_unlock(tty); |