aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/pty.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/pty.c')
-rw-r--r--drivers/char/pty.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index d83a43130df4..ad46eae1f9bb 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -62,7 +62,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
62 if (tty->driver == ptm_driver) 62 if (tty->driver == ptm_driver)
63 devpts_pty_kill(tty->link); 63 devpts_pty_kill(tty->link);
64#endif 64#endif
65 tty_unlock();
65 tty_vhangup(tty->link); 66 tty_vhangup(tty->link);
67 tty_lock();
66 } 68 }
67} 69}
68 70
@@ -171,6 +173,23 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg)
171 return 0; 173 return 0;
172} 174}
173 175
176/* Send a signal to the slave */
177static int pty_signal(struct tty_struct *tty, int sig)
178{
179 unsigned long flags;
180 struct pid *pgrp;
181
182 if (tty->link) {
183 spin_lock_irqsave(&tty->link->ctrl_lock, flags);
184 pgrp = get_pid(tty->link->pgrp);
185 spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
186
187 kill_pgrp(pgrp, sig, 1);
188 put_pid(pgrp);
189 }
190 return 0;
191}
192
174static void pty_flush_buffer(struct tty_struct *tty) 193static void pty_flush_buffer(struct tty_struct *tty)
175{ 194{
176 struct tty_struct *to = tty->link; 195 struct tty_struct *to = tty->link;
@@ -321,6 +340,8 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file,
321 switch (cmd) { 340 switch (cmd) {
322 case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ 341 case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
323 return pty_set_lock(tty, (int __user *) arg); 342 return pty_set_lock(tty, (int __user *) arg);
343 case TIOCSIG: /* Send signal to other side of pty */
344 return pty_signal(tty, (int) arg);
324 } 345 }
325 return -ENOIOCTLCMD; 346 return -ENOIOCTLCMD;
326} 347}
@@ -476,6 +497,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
476 return pty_set_lock(tty, (int __user *)arg); 497 return pty_set_lock(tty, (int __user *)arg);
477 case TIOCGPTN: /* Get PT Number */ 498 case TIOCGPTN: /* Get PT Number */
478 return put_user(tty->index, (unsigned int __user *)arg); 499 return put_user(tty->index, (unsigned int __user *)arg);
500 case TIOCSIG: /* Send signal to other side of pty */
501 return pty_signal(tty, (int) arg);
479 } 502 }
480 503
481 return -ENOIOCTLCMD; 504 return -ENOIOCTLCMD;
@@ -626,7 +649,7 @@ static const struct tty_operations pty_unix98_ops = {
626 * allocated_ptys_lock handles the list of free pty numbers 649 * allocated_ptys_lock handles the list of free pty numbers
627 */ 650 */
628 651
629static int __ptmx_open(struct inode *inode, struct file *filp) 652static int ptmx_open(struct inode *inode, struct file *filp)
630{ 653{
631 struct tty_struct *tty; 654 struct tty_struct *tty;
632 int retval; 655 int retval;
@@ -635,11 +658,14 @@ static int __ptmx_open(struct inode *inode, struct file *filp)
635 nonseekable_open(inode, filp); 658 nonseekable_open(inode, filp);
636 659
637 /* find a device that is not in use. */ 660 /* find a device that is not in use. */
661 tty_lock();
638 index = devpts_new_index(inode); 662 index = devpts_new_index(inode);
663 tty_unlock();
639 if (index < 0) 664 if (index < 0)
640 return index; 665 return index;
641 666
642 mutex_lock(&tty_mutex); 667 mutex_lock(&tty_mutex);
668 tty_lock();
643 tty = tty_init_dev(ptm_driver, index, 1); 669 tty = tty_init_dev(ptm_driver, index, 1);
644 mutex_unlock(&tty_mutex); 670 mutex_unlock(&tty_mutex);
645 671
@@ -657,26 +683,21 @@ static int __ptmx_open(struct inode *inode, struct file *filp)
657 goto out1; 683 goto out1;
658 684
659 retval = ptm_driver->ops->open(tty, filp); 685 retval = ptm_driver->ops->open(tty, filp);
660 if (!retval) 686 if (retval)
661 return 0; 687 goto out2;
662out1: 688out1:
689 tty_unlock();
690 return retval;
691out2:
692 tty_unlock();
663 tty_release(inode, filp); 693 tty_release(inode, filp);
664 return retval; 694 return retval;
665out: 695out:
666 devpts_kill_index(inode, index); 696 devpts_kill_index(inode, index);
697 tty_unlock();
667 return retval; 698 return retval;
668} 699}
669 700
670static int ptmx_open(struct inode *inode, struct file *filp)
671{
672 int ret;
673
674 lock_kernel();
675 ret = __ptmx_open(inode, filp);
676 unlock_kernel();
677 return ret;
678}
679
680static struct file_operations ptmx_fops; 701static struct file_operations ptmx_fops;
681 702
682static void __init unix98_pty_init(void) 703static void __init unix98_pty_init(void)