aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c84
1 files changed, 54 insertions, 30 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index cd5b829634ea..949067a0bd47 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -188,6 +188,41 @@ void free_tty_struct(struct tty_struct *tty)
188 kfree(tty); 188 kfree(tty);
189} 189}
190 190
191static inline struct tty_struct *file_tty(struct file *file)
192{
193 return ((struct tty_file_private *)file->private_data)->tty;
194}
195
196/* Associate a new file with the tty structure */
197void tty_add_file(struct tty_struct *tty, struct file *file)
198{
199 struct tty_file_private *priv;
200
201 /* XXX: must implement proper error handling in callers */
202 priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL);
203
204 priv->tty = tty;
205 priv->file = file;
206 file->private_data = priv;
207
208 spin_lock(&tty_files_lock);
209 list_add(&priv->list, &tty->tty_files);
210 spin_unlock(&tty_files_lock);
211}
212
213/* Delete file from its tty */
214void tty_del_file(struct file *file)
215{
216 struct tty_file_private *priv = file->private_data;
217
218 spin_lock(&tty_files_lock);
219 list_del(&priv->list);
220 spin_unlock(&tty_files_lock);
221 file->private_data = NULL;
222 kfree(priv);
223}
224
225
191#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) 226#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)
192 227
193/** 228/**
@@ -500,6 +535,7 @@ void __tty_hangup(struct tty_struct *tty)
500 struct file *cons_filp = NULL; 535 struct file *cons_filp = NULL;
501 struct file *filp, *f = NULL; 536 struct file *filp, *f = NULL;
502 struct task_struct *p; 537 struct task_struct *p;
538 struct tty_file_private *priv;
503 int closecount = 0, n; 539 int closecount = 0, n;
504 unsigned long flags; 540 unsigned long flags;
505 int refs = 0; 541 int refs = 0;
@@ -509,7 +545,7 @@ void __tty_hangup(struct tty_struct *tty)
509 545
510 546
511 spin_lock(&redirect_lock); 547 spin_lock(&redirect_lock);
512 if (redirect && redirect->private_data == tty) { 548 if (redirect && file_tty(redirect) == tty) {
513 f = redirect; 549 f = redirect;
514 redirect = NULL; 550 redirect = NULL;
515 } 551 }
@@ -524,7 +560,8 @@ void __tty_hangup(struct tty_struct *tty)
524 560
525 spin_lock(&tty_files_lock); 561 spin_lock(&tty_files_lock);
526 /* This breaks for file handles being sent over AF_UNIX sockets ? */ 562 /* This breaks for file handles being sent over AF_UNIX sockets ? */
527 list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { 563 list_for_each_entry(priv, &tty->tty_files, list) {
564 filp = priv->file;
528 if (filp->f_op->write == redirected_tty_write) 565 if (filp->f_op->write == redirected_tty_write)
529 cons_filp = filp; 566 cons_filp = filp;
530 if (filp->f_op->write != tty_write) 567 if (filp->f_op->write != tty_write)
@@ -892,12 +929,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
892 loff_t *ppos) 929 loff_t *ppos)
893{ 930{
894 int i; 931 int i;
895 struct tty_struct *tty; 932 struct inode *inode = file->f_path.dentry->d_inode;
896 struct inode *inode; 933 struct tty_struct *tty = file_tty(file);
897 struct tty_ldisc *ld; 934 struct tty_ldisc *ld;
898 935
899 tty = file->private_data;
900 inode = file->f_path.dentry->d_inode;
901 if (tty_paranoia_check(tty, inode, "tty_read")) 936 if (tty_paranoia_check(tty, inode, "tty_read"))
902 return -EIO; 937 return -EIO;
903 if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) 938 if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
@@ -1068,12 +1103,11 @@ void tty_write_message(struct tty_struct *tty, char *msg)
1068static ssize_t tty_write(struct file *file, const char __user *buf, 1103static ssize_t tty_write(struct file *file, const char __user *buf,
1069 size_t count, loff_t *ppos) 1104 size_t count, loff_t *ppos)
1070{ 1105{
1071 struct tty_struct *tty;
1072 struct inode *inode = file->f_path.dentry->d_inode; 1106 struct inode *inode = file->f_path.dentry->d_inode;
1107 struct tty_struct *tty = file_tty(file);
1108 struct tty_ldisc *ld;
1073 ssize_t ret; 1109 ssize_t ret;
1074 struct tty_ldisc *ld;
1075 1110
1076 tty = file->private_data;
1077 if (tty_paranoia_check(tty, inode, "tty_write")) 1111 if (tty_paranoia_check(tty, inode, "tty_write"))
1078 return -EIO; 1112 return -EIO;
1079 if (!tty || !tty->ops->write || 1113 if (!tty || !tty->ops->write ||
@@ -1510,13 +1544,13 @@ static void release_tty(struct tty_struct *tty, int idx)
1510 1544
1511int tty_release(struct inode *inode, struct file *filp) 1545int tty_release(struct inode *inode, struct file *filp)
1512{ 1546{
1513 struct tty_struct *tty, *o_tty; 1547 struct tty_struct *tty = file_tty(filp);
1548 struct tty_struct *o_tty;
1514 int pty_master, tty_closing, o_tty_closing, do_sleep; 1549 int pty_master, tty_closing, o_tty_closing, do_sleep;
1515 int devpts; 1550 int devpts;
1516 int idx; 1551 int idx;
1517 char buf[64]; 1552 char buf[64];
1518 1553
1519 tty = filp->private_data;
1520 if (tty_paranoia_check(tty, inode, "tty_release_dev")) 1554 if (tty_paranoia_check(tty, inode, "tty_release_dev"))
1521 return 0; 1555 return 0;
1522 1556
@@ -1674,11 +1708,7 @@ int tty_release(struct inode *inode, struct file *filp)
1674 * - do_tty_hangup no longer sees this file descriptor as 1708 * - do_tty_hangup no longer sees this file descriptor as
1675 * something that needs to be handled for hangups. 1709 * something that needs to be handled for hangups.
1676 */ 1710 */
1677 spin_lock(&tty_files_lock); 1711 tty_del_file(filp);
1678 BUG_ON(list_empty(&filp->f_u.fu_list));
1679 list_del_init(&filp->f_u.fu_list);
1680 spin_unlock(&tty_files_lock);
1681 filp->private_data = NULL;
1682 1712
1683 /* 1713 /*
1684 * Perform some housekeeping before deciding whether to return. 1714 * Perform some housekeeping before deciding whether to return.
@@ -1845,12 +1875,8 @@ got_driver:
1845 return PTR_ERR(tty); 1875 return PTR_ERR(tty);
1846 } 1876 }
1847 1877
1848 filp->private_data = tty; 1878 tty_add_file(tty, filp);
1849 BUG_ON(list_empty(&filp->f_u.fu_list)); 1879
1850 file_sb_list_del(filp); /* __dentry_open has put it on the sb list */
1851 spin_lock(&tty_files_lock);
1852 list_add(&filp->f_u.fu_list, &tty->tty_files);
1853 spin_unlock(&tty_files_lock);
1854 check_tty_count(tty, "tty_open"); 1880 check_tty_count(tty, "tty_open");
1855 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 1881 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1856 tty->driver->subtype == PTY_TYPE_MASTER) 1882 tty->driver->subtype == PTY_TYPE_MASTER)
@@ -1926,11 +1952,10 @@ got_driver:
1926 1952
1927static unsigned int tty_poll(struct file *filp, poll_table *wait) 1953static unsigned int tty_poll(struct file *filp, poll_table *wait)
1928{ 1954{
1929 struct tty_struct *tty; 1955 struct tty_struct *tty = file_tty(filp);
1930 struct tty_ldisc *ld; 1956 struct tty_ldisc *ld;
1931 int ret = 0; 1957 int ret = 0;
1932 1958
1933 tty = filp->private_data;
1934 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) 1959 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
1935 return 0; 1960 return 0;
1936 1961
@@ -1943,11 +1968,10 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
1943 1968
1944static int __tty_fasync(int fd, struct file *filp, int on) 1969static int __tty_fasync(int fd, struct file *filp, int on)
1945{ 1970{
1946 struct tty_struct *tty; 1971 struct tty_struct *tty = file_tty(filp);
1947 unsigned long flags; 1972 unsigned long flags;
1948 int retval = 0; 1973 int retval = 0;
1949 1974
1950 tty = filp->private_data;
1951 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) 1975 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
1952 goto out; 1976 goto out;
1953 1977
@@ -2501,13 +2525,13 @@ EXPORT_SYMBOL(tty_pair_get_pty);
2501 */ 2525 */
2502long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 2526long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2503{ 2527{
2504 struct tty_struct *tty, *real_tty; 2528 struct tty_struct *tty = file_tty(file);
2529 struct tty_struct *real_tty;
2505 void __user *p = (void __user *)arg; 2530 void __user *p = (void __user *)arg;
2506 int retval; 2531 int retval;
2507 struct tty_ldisc *ld; 2532 struct tty_ldisc *ld;
2508 struct inode *inode = file->f_dentry->d_inode; 2533 struct inode *inode = file->f_dentry->d_inode;
2509 2534
2510 tty = file->private_data;
2511 if (tty_paranoia_check(tty, inode, "tty_ioctl")) 2535 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
2512 return -EINVAL; 2536 return -EINVAL;
2513 2537
@@ -2629,7 +2653,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
2629 unsigned long arg) 2653 unsigned long arg)
2630{ 2654{
2631 struct inode *inode = file->f_dentry->d_inode; 2655 struct inode *inode = file->f_dentry->d_inode;
2632 struct tty_struct *tty = file->private_data; 2656 struct tty_struct *tty = file_tty(file);
2633 struct tty_ldisc *ld; 2657 struct tty_ldisc *ld;
2634 int retval = -ENOIOCTLCMD; 2658 int retval = -ENOIOCTLCMD;
2635 2659
@@ -2721,7 +2745,7 @@ void __do_SAK(struct tty_struct *tty)
2721 if (!filp) 2745 if (!filp)
2722 continue; 2746 continue;
2723 if (filp->f_op->read == tty_read && 2747 if (filp->f_op->read == tty_read &&
2724 filp->private_data == tty) { 2748 file_tty(filp) == tty) {
2725 printk(KERN_NOTICE "SAK: killed process %d" 2749 printk(KERN_NOTICE "SAK: killed process %d"
2726 " (%s): fd#%d opened to the tty\n", 2750 " (%s): fd#%d opened to the tty\n",
2727 task_pid_nr(p), p->comm, i); 2751 task_pid_nr(p), p->comm, i);