]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.20-tty-fixes.patch
- ported from linux-2.4.25-atmdd.patch
[packages/kernel.git] / linux-2.4.20-tty-fixes.patch
CommitLineData
10679586 1 # From RH: TIOCCONS fix and /dev/console write fix
2 # One of them probably fixes CAN-2002-0247, but which??? They didn't tell :/
3diff -urN S21-rh/drivers/char/tty_io.c S21-rh-tty/drivers/char/tty_io.c
4--- S21-rh/drivers/char/tty_io.c Sat May 17 11:31:48 2003
5+++ S21-rh-tty/drivers/char/tty_io.c Sat May 17 11:32:35 2003
6@@ -127,12 +127,6 @@
7 extern struct tty_driver pts_driver[]; /* Unix98 pty slaves; for /dev/ptmx */
8 #endif
9
10-/*
11- * redirect is the pseudo-tty that console output
12- * is redirected to if asked by TIOCCONS.
13- */
14-struct tty_struct * redirect;
15-
16 static void initialize_tty_struct(struct tty_struct *tty);
17
18 static ssize_t tty_read(struct file *, char *, size_t, loff_t *);
19@@ -430,6 +424,8 @@
20 release: tty_release,
21 };
22
23+static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED;
24+static struct file *redirect;
25 /*
26 * This can be called by the "eventd" kernel thread. That is process synchronous,
27 * but doesn't hold any locks, so we need to make sure we have the appropriate
28@@ -439,6 +435,7 @@
29 {
30 struct tty_struct *tty = (struct tty_struct *) data;
31 struct file * cons_filp = NULL;
32+ struct file *f = NULL;
33 struct task_struct *p;
34 struct list_head *l;
35 int closecount = 0, n;
36@@ -449,6 +446,15 @@
37
38 /* inuse_filps is protected by the single kernel lock */
39 lock_kernel();
40+
41+ spin_lock(&redirect_lock);
42+ if (redirect && redirect->private_data == tty) {
43+ f = redirect;
44+ redirect = NULL;
45+ }
46+ spin_unlock(&redirect_lock);
47+ if (f)
48+ fput(f);
49
50 check_tty_count(tty, "do_tty_hangup");
51 file_list_lock();
52@@ -748,11 +754,7 @@
53 {
54 int is_console;
55 struct tty_struct * tty;
56- struct inode *inode;
57-
58- /* Can't seek (pwrite) on ttys. */
59- if (ppos != &file->f_pos)
60- return -ESPIPE;
61+ struct inode *inode = file->f_dentry->d_inode;
62
63 /*
64 * For now, we redirect writes from /dev/console as
65@@ -762,10 +764,28 @@
66 is_console = (inode->i_rdev == SYSCONS_DEV ||
67 inode->i_rdev == CONSOLE_DEV);
68
69- if (is_console && redirect)
70- tty = redirect;
71- else
72- tty = (struct tty_struct *)file->private_data;
73+ if (is_console) {
74+ struct file *p = NULL;
75+
76+ spin_lock(&redirect_lock);
77+ if (redirect) {
78+ get_file(redirect);
79+ p = redirect;
80+ }
81+ spin_unlock(&redirect_lock);
82+
83+ if (p) {
84+ ssize_t res = p->f_op->write(p, buf, count, ppos);
85+ fput(p);
86+ return res;
87+ }
88+ }
89+
90+ /* Can't seek (pwrite) on ttys. */
91+ if (ppos != &file->f_pos)
92+ return -ESPIPE;
93+
94+ tty = (struct tty_struct *)file->private_data;
95 if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
96 return -EIO;
97 if (!tty || !tty->driver.write || (test_bit(TTY_IO_ERROR, &tty->flags)))
98@@ -1231,7 +1251,7 @@
99 /*
100 * If _either_ side is closing, make sure there aren't any
101 * processes that still think tty or o_tty is their controlling
102- * tty. Also, clear redirect if it points to either tty.
103+ * tty.
104 */
105 if (tty_closing || o_tty_closing) {
106 struct task_struct *p;
107@@ -1245,9 +1265,6 @@
108 for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid)
109 p->tty = NULL;
110 read_unlock(&tasklist_lock);
111-
112- if (redirect == tty || (o_tty && redirect == o_tty))
113- redirect = NULL;
114 }
115
116 /* check whether both sides are closing ... */
117@@ -1526,19 +1543,29 @@
118 return 0;
119 }
120
121-static int tioccons(struct inode *inode,
122- struct tty_struct *tty, struct tty_struct *real_tty)
123+static int tioccons(struct inode *inode, struct file *file)
124 {
125 if (inode->i_rdev == SYSCONS_DEV ||
126 inode->i_rdev == CONSOLE_DEV) {
127+ struct file *f;
128 if (!suser())
129 return -EPERM;
130+ spin_lock(&redirect_lock);
131+ f = redirect;
132 redirect = NULL;
133+ spin_unlock(&redirect_lock);
134+ if (f)
135+ fput(f);
136 return 0;
137 }
138- if (redirect)
139+ spin_lock(&redirect_lock);
140+ if (redirect) {
141+ spin_unlock(&redirect_lock);
142 return -EBUSY;
143- redirect = real_tty;
144+ }
145+ get_file(file);
146+ redirect = file;
147+ spin_unlock(&redirect_lock);
148 return 0;
149 }
150
151@@ -1759,7 +1786,7 @@
152 case TIOCSWINSZ:
153 return tiocswinsz(tty, real_tty, (struct winsize *) arg);
154 case TIOCCONS:
155- return tioccons(inode, tty, real_tty);
156+ return real_tty!=tty ? -EINVAL : tioccons(inode, file);
157 case FIONBIO:
158 return fionbio(file, (int *) arg);
159 case TIOCEXCL:
160diff -urN S21-rh/include/linux/tty.h S21-rh-tty/include/linux/tty.h
161--- S21-rh/include/linux/tty.h Sat May 17 11:31:52 2003
162+++ S21-rh-tty/include/linux/tty.h Sat May 17 11:32:35 2003
163@@ -341,7 +341,6 @@
164 extern void tty_write_flush(struct tty_struct *);
165
166 extern struct termios tty_std_termios;
167-extern struct tty_struct * redirect;
168 extern struct tty_ldisc ldiscs[];
169 extern int fg_console, last_console, want_console;
170
171--- drivers/char/tty_io.c Sat May 17 11:14:02 2003
172+++ linux/drivers/char/tty_io.c Sun May 25 07:49:08 2003
173@@ -751,6 +751,10 @@
174 struct tty_struct * tty;
175 struct inode *inode = file->f_dentry->d_inode;
176
177+ /* Can't seek (pwrite) on ttys. */
178+ if (ppos != &file->f_pos)
179+ return -ESPIPE;
180+
181 /*
182 * For now, we redirect writes from /dev/console as
183 * well as /dev/tty0.
184@@ -770,15 +774,11 @@
185 spin_unlock(&redirect_lock);
186
187 if (p) {
188- ssize_t res = p->f_op->write(p, buf, count, ppos);
189+ ssize_t res = p->f_op->write(p, buf, count, &p->f_pos);
190 fput(p);
191 return res;
192 }
193 }
194-
195- /* Can't seek (pwrite) on ttys. */
196- if (ppos != &file->f_pos)
197- return -ESPIPE;
198
199 tty = (struct tty_struct *)file->private_data;
200 if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
This page took 0.143222 seconds and 4 git commands to generate.