Blame view
drivers/tty/tty_io.c
83.5 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
* Copyright (C) 1991, 1992 Linus Torvalds */ /* * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles * or rs-channels. It also implements echoing, cooked mode etc. * * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0. * * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the * tty_struct and tty_queue structures. Previously there was an array * of 256 tty_struct's which was statically allocated, and the * tty_queue structures were allocated at boot time. Both are now * dynamically allocated only when the tty is open. * * Also restructured routines so that there is more of a separation * between the high-level tty routines (tty_io.c and tty_ioctl.c) and * the low-level tty routines (serial.c, pty.c, console.c). This |
37bdfb074 tty_io: drag scre... |
20 |
* makes for cleaner and more compact code. -TYT, 9/17/92 |
1da177e4c Linux-2.6.12-rc2 |
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
* * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines * which can be dynamically activated and de-activated by the line * discipline handling modules (like SLIP). * * NOTE: pay no attention to the line discipline code (yet); its * interface is still subject to change in this version... * -- TYT, 1/31/92 * * Added functionality to the OPOST tty handling. No delays, but all * other bits should be there. * -- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993. * * Rewrote canonical mode and added more termios flags. * -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94 * * Reorganized FASYNC support so mouse code can share it. * -- ctm@ardi.com, 9Sep95 * * New TIOCLINUX variants added. * -- mj@k332.feld.cvut.cz, 19-Nov-95 |
37bdfb074 tty_io: drag scre... |
42 |
* |
1da177e4c Linux-2.6.12-rc2 |
43 44 45 46 47 48 49 |
* Restrict vt switching via ioctl() * -- grif@cs.ucr.edu, 5-Dec-95 * * Move console and virtual terminal code to more appropriate files, * implement CONFIG_VT and generalize console device interface. * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97 * |
d81ed1030 tty: Remove more ... |
50 |
* Rewrote tty_init_dev and tty_release_dev to eliminate races. |
1da177e4c Linux-2.6.12-rc2 |
51 52 53 54 55 56 57 58 59 60 61 62 |
* -- Bill Hawes <whawes@star.net>, June 97 * * Added devfs support. * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 13-Jan-1998 * * Added support for a Unix98-style ptmx device. * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998 * * Reduced memory usage for older ARM systems * -- Russell King <rmk@arm.linux.org.uk> * * Move do_SAK() into process context. Less stack use in devfs functions. |
37bdfb074 tty_io: drag scre... |
63 64 |
* alloc_tty_struct() always uses kmalloc() * -- Andrew Morton <andrewm@uow.edu.eu> 17Mar01 |
1da177e4c Linux-2.6.12-rc2 |
65 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
66 67 68 69 70 71 72 73 74 75 76 77 |
#include <linux/types.h> #include <linux/major.h> #include <linux/errno.h> #include <linux/signal.h> #include <linux/fcntl.h> #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/tty.h> #include <linux/tty_driver.h> #include <linux/tty_flip.h> #include <linux/devpts_fs.h> #include <linux/file.h> |
9f3acc314 [PATCH] split lin... |
78 |
#include <linux/fdtable.h> |
1da177e4c Linux-2.6.12-rc2 |
79 80 81 82 83 84 85 86 87 88 89 |
#include <linux/console.h> #include <linux/timer.h> #include <linux/ctype.h> #include <linux/kd.h> #include <linux/mm.h> #include <linux/string.h> #include <linux/slab.h> #include <linux/poll.h> #include <linux/proc_fs.h> #include <linux/init.h> #include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
90 |
#include <linux/device.h> |
1da177e4c Linux-2.6.12-rc2 |
91 92 |
#include <linux/wait.h> #include <linux/bitops.h> |
b20f3ae5f [PATCH] char/tty_... |
93 |
#include <linux/delay.h> |
a352def21 tty: Ldisc revamp |
94 |
#include <linux/seq_file.h> |
d281da7ff tty: Make tiocgic... |
95 |
#include <linux/serial.h> |
5a3c6b251 drivers/tty: use ... |
96 |
#include <linux/ratelimit.h> |
1da177e4c Linux-2.6.12-rc2 |
97 |
|
a352def21 tty: Ldisc revamp |
98 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
99 100 101 102 103 |
#include <asm/system.h> #include <linux/kbd_kern.h> #include <linux/vt_kern.h> #include <linux/selection.h> |
1da177e4c Linux-2.6.12-rc2 |
104 105 |
#include <linux/kmod.h> |
b488893a3 pid namespaces: c... |
106 |
#include <linux/nsproxy.h> |
1da177e4c Linux-2.6.12-rc2 |
107 108 109 110 111 |
#undef TTY_DEBUG_HANGUP #define TTY_PARANOIA_CHECK 1 #define CHECK_TTY_COUNT 1 |
edc6afc54 [PATCH] tty: swit... |
112 |
struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ |
1da177e4c Linux-2.6.12-rc2 |
113 114 115 116 117 |
.c_iflag = ICRNL | IXON, .c_oflag = OPOST | ONLCR, .c_cflag = B38400 | CS8 | CREAD | HUPCL, .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN, |
edc6afc54 [PATCH] tty: swit... |
118 119 120 |
.c_cc = INIT_C_CC, .c_ispeed = 38400, .c_ospeed = 38400 |
1da177e4c Linux-2.6.12-rc2 |
121 122 123 124 125 126 127 |
}; EXPORT_SYMBOL(tty_std_termios); /* This list gets poked at by procfs and various bits of boot up code. This could do with some rationalisation such as pulling the tty proc function into this file */ |
37bdfb074 tty_io: drag scre... |
128 |
|
1da177e4c Linux-2.6.12-rc2 |
129 |
LIST_HEAD(tty_drivers); /* linked list of tty drivers */ |
24ec839c4 [PATCH] tty: ->si... |
130 |
/* Mutex to protect creating and releasing a tty. This is shared with |
1da177e4c Linux-2.6.12-rc2 |
131 |
vt.c for deeply disgusting hack reasons */ |
70522e121 [PATCH] sem2mutex... |
132 |
DEFINE_MUTEX(tty_mutex); |
de2a84f2b [PATCH] solaris e... |
133 |
EXPORT_SYMBOL(tty_mutex); |
1da177e4c Linux-2.6.12-rc2 |
134 |
|
ee2ffa0df fs: cleanup files... |
135 136 |
/* Spinlock to protect the tty->tty_files list */ DEFINE_SPINLOCK(tty_files_lock); |
1da177e4c Linux-2.6.12-rc2 |
137 138 |
static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
37bdfb074 tty_io: drag scre... |
139 140 |
ssize_t redirected_tty_write(struct file *, const char __user *, size_t, loff_t *); |
1da177e4c Linux-2.6.12-rc2 |
141 142 |
static unsigned int tty_poll(struct file *, poll_table *); static int tty_open(struct inode *, struct file *); |
04f378b19 tty: BKL pushdown |
143 |
long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
e10cc1df1 tty: add compat_i... |
144 |
#ifdef CONFIG_COMPAT |
37bdfb074 tty_io: drag scre... |
145 |
static long tty_compat_ioctl(struct file *file, unsigned int cmd, |
e10cc1df1 tty: add compat_i... |
146 147 148 149 |
unsigned long arg); #else #define tty_compat_ioctl NULL #endif |
ec79d6056 tty: replace BKL ... |
150 |
static int __tty_fasync(int fd, struct file *filp, int on); |
37bdfb074 tty_io: drag scre... |
151 |
static int tty_fasync(int fd, struct file *filp, int on); |
d5698c28b [PATCH] tty: clea... |
152 |
static void release_tty(struct tty_struct *tty, int idx); |
2a65f1d9f tty: simplify cal... |
153 |
static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
98a27ba48 tty: introduce no... |
154 |
static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
1da177e4c Linux-2.6.12-rc2 |
155 |
|
af9b897ee [PATCH] tty layer... |
156 157 158 159 160 161 162 |
/** * alloc_tty_struct - allocate a tty object * * Return a new empty tty structure. The data fields have not * been initialized in any way but has been zeroed * * Locking: none |
af9b897ee [PATCH] tty layer... |
163 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
164 |
|
bf970ee46 tty: extract the ... |
165 |
struct tty_struct *alloc_tty_struct(void) |
1da177e4c Linux-2.6.12-rc2 |
166 |
{ |
1266b1e1a [PATCH] tty: triv... |
167 |
return kzalloc(sizeof(struct tty_struct), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
168 |
} |
af9b897ee [PATCH] tty layer... |
169 170 171 172 173 174 175 176 |
/** * free_tty_struct - free a disused tty * @tty: tty struct to free * * Free the write buffers, tty queue and tty memory itself. * * Locking: none. Must be called after tty is definitely unused */ |
bf970ee46 tty: extract the ... |
177 |
void free_tty_struct(struct tty_struct *tty) |
1da177e4c Linux-2.6.12-rc2 |
178 |
{ |
30004ac9c tty: add tty_stru... |
179 180 |
if (tty->dev) put_device(tty->dev); |
1da177e4c Linux-2.6.12-rc2 |
181 |
kfree(tty->write_buf); |
33f0f88f1 [PATCH] TTY layer... |
182 |
tty_buffer_free_all(tty); |
1da177e4c Linux-2.6.12-rc2 |
183 184 |
kfree(tty); } |
d996b62a8 tty: fix fu_list ... |
185 186 187 188 |
static inline struct tty_struct *file_tty(struct file *file) { return ((struct tty_file_private *)file->private_data)->tty; } |
fa90e1c93 TTY: make tty_add... |
189 |
int tty_alloc_file(struct file *file) |
d996b62a8 tty: fix fu_list ... |
190 191 |
{ struct tty_file_private *priv; |
f573bd176 tty: Remove __GFP... |
192 193 194 |
priv = kmalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; |
d996b62a8 tty: fix fu_list ... |
195 |
|
fa90e1c93 TTY: make tty_add... |
196 197 198 199 200 201 202 203 204 |
file->private_data = priv; return 0; } /* Associate a new file with the tty structure */ void tty_add_file(struct tty_struct *tty, struct file *file) { struct tty_file_private *priv = file->private_data; |
d996b62a8 tty: fix fu_list ... |
205 206 |
priv->tty = tty; priv->file = file; |
d996b62a8 tty: fix fu_list ... |
207 208 209 210 |
spin_lock(&tty_files_lock); list_add(&priv->list, &tty->tty_files); spin_unlock(&tty_files_lock); |
fa90e1c93 TTY: make tty_add... |
211 |
} |
f573bd176 tty: Remove __GFP... |
212 |
|
fa90e1c93 TTY: make tty_add... |
213 214 215 216 217 218 219 220 221 222 223 224 |
/** * tty_free_file - free file->private_data * * This shall be used only for fail path handling when tty_add_file was not * called yet. */ void tty_free_file(struct file *file) { struct tty_file_private *priv = file->private_data; file->private_data = NULL; kfree(priv); |
d996b62a8 tty: fix fu_list ... |
225 226 227 228 229 230 231 232 233 234 |
} /* Delete file from its tty */ void tty_del_file(struct file *file) { struct tty_file_private *priv = file->private_data; spin_lock(&tty_files_lock); list_del(&priv->list); spin_unlock(&tty_files_lock); |
fa90e1c93 TTY: make tty_add... |
235 |
tty_free_file(file); |
d996b62a8 tty: fix fu_list ... |
236 |
} |
1da177e4c Linux-2.6.12-rc2 |
237 |
#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) |
af9b897ee [PATCH] tty layer... |
238 239 240 241 242 243 244 245 246 247 |
/** * tty_name - return tty naming * @tty: tty structure * @buf: buffer for output * * Convert a tty structure into a name. The name reflects the kernel * naming policy and if udev is in use may not reflect user space * * Locking: none */ |
1da177e4c Linux-2.6.12-rc2 |
248 249 250 251 252 253 254 255 256 257 |
char *tty_name(struct tty_struct *tty, char *buf) { if (!tty) /* Hmm. NULL pointer. That's fun. */ strcpy(buf, "NULL tty"); else strcpy(buf, tty->name); return buf; } EXPORT_SYMBOL(tty_name); |
d769a6697 [PATCH] uninline ... |
258 |
int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, |
1da177e4c Linux-2.6.12-rc2 |
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
const char *routine) { #ifdef TTY_PARANOIA_CHECK if (!tty) { printk(KERN_WARNING "null TTY for (%d:%d) in %s ", imajor(inode), iminor(inode), routine); return 1; } if (tty->magic != TTY_MAGIC) { printk(KERN_WARNING "bad magic number for tty struct (%d:%d) in %s ", imajor(inode), iminor(inode), routine); return 1; } #endif return 0; } static int check_tty_count(struct tty_struct *tty, const char *routine) { #ifdef CHECK_TTY_COUNT struct list_head *p; int count = 0; |
37bdfb074 tty_io: drag scre... |
285 |
|
ee2ffa0df fs: cleanup files... |
286 |
spin_lock(&tty_files_lock); |
1da177e4c Linux-2.6.12-rc2 |
287 288 289 |
list_for_each(p, &tty->tty_files) { count++; } |
ee2ffa0df fs: cleanup files... |
290 |
spin_unlock(&tty_files_lock); |
1da177e4c Linux-2.6.12-rc2 |
291 292 293 294 295 296 297 298 299 300 |
if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_SLAVE && tty->link && tty->link->count) count++; if (tty->count != count) { printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) " "!= #fd's(%d) in %s ", tty->name, tty->count, count, routine); return count; |
24ec839c4 [PATCH] tty: ->si... |
301 |
} |
1da177e4c Linux-2.6.12-rc2 |
302 303 304 |
#endif return 0; } |
af9b897ee [PATCH] tty layer... |
305 |
/** |
af9b897ee [PATCH] tty layer... |
306 307 308 309 310 311 312 313 |
* get_tty_driver - find device of a tty * @dev_t: device identifier * @index: returns the index of the tty * * This routine returns a tty driver structure, given a device number * and also passes back the index number. * * Locking: caller must hold tty_mutex |
1da177e4c Linux-2.6.12-rc2 |
314 |
*/ |
af9b897ee [PATCH] tty layer... |
315 |
|
1da177e4c Linux-2.6.12-rc2 |
316 317 318 319 320 321 322 323 324 |
static struct tty_driver *get_tty_driver(dev_t device, int *index) { struct tty_driver *p; list_for_each_entry(p, &tty_drivers, tty_drivers) { dev_t base = MKDEV(p->major, p->minor_start); if (device < base || device >= base + p->num) continue; *index = device - base; |
7d7b93c14 tty: kref the tty... |
325 |
return tty_driver_kref_get(p); |
1da177e4c Linux-2.6.12-rc2 |
326 327 328 |
} return NULL; } |
f2d937f3b consoles: polling... |
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
#ifdef CONFIG_CONSOLE_POLL /** * tty_find_polling_driver - find device of a polled tty * @name: name string to match * @line: pointer to resulting tty line nr * * This routine returns a tty driver structure, given a name * and the condition that the tty driver is capable of polled * operation. */ struct tty_driver *tty_find_polling_driver(char *name, int *line) { struct tty_driver *p, *res = NULL; int tty_line = 0; |
0dca0fd2b kgdboc,tty: Fix t... |
344 |
int len; |
5f0878acb tty: Fix oops whe... |
345 |
char *str, *stp; |
f2d937f3b consoles: polling... |
346 |
|
0dca0fd2b kgdboc,tty: Fix t... |
347 348 349 350 351 352 353 354 |
for (str = name; *str; str++) if ((*str >= '0' && *str <= '9') || *str == ',') break; if (!*str) return NULL; len = str - name; tty_line = simple_strtoul(str, &str, 10); |
f2d937f3b consoles: polling... |
355 356 357 |
mutex_lock(&tty_mutex); /* Search through the tty devices to look for a match */ list_for_each_entry(p, &tty_drivers, tty_drivers) { |
0dca0fd2b kgdboc,tty: Fix t... |
358 359 |
if (strncmp(name, p->name, len) != 0) continue; |
5f0878acb tty: Fix oops whe... |
360 361 362 363 364 |
stp = str; if (*stp == ',') stp++; if (*stp == '\0') stp = NULL; |
f2d937f3b consoles: polling... |
365 |
|
6eb68d6f3 tty: fix tty_line... |
366 |
if (tty_line >= 0 && tty_line < p->num && p->ops && |
5f0878acb tty: Fix oops whe... |
367 |
p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) { |
7d7b93c14 tty: kref the tty... |
368 |
res = tty_driver_kref_get(p); |
f2d937f3b consoles: polling... |
369 370 371 372 373 374 375 376 377 378 |
*line = tty_line; break; } } mutex_unlock(&tty_mutex); return res; } EXPORT_SYMBOL_GPL(tty_find_polling_driver); #endif |
af9b897ee [PATCH] tty layer... |
379 380 381 382 383 384 385 386 |
/** * tty_check_change - check for POSIX terminal changes * @tty: tty to check * * If we try to write to, or set the state of, a terminal and we're * not in the foreground, send a SIGTTOU. If the signal is blocked or * ignored, go ahead and perform the operation. (POSIX 7.2) * |
978e595f8 tty/serial: lay t... |
387 |
* Locking: ctrl_lock |
1da177e4c Linux-2.6.12-rc2 |
388 |
*/ |
af9b897ee [PATCH] tty layer... |
389 |
|
37bdfb074 tty_io: drag scre... |
390 |
int tty_check_change(struct tty_struct *tty) |
1da177e4c Linux-2.6.12-rc2 |
391 |
{ |
47f86834b redo locking of t... |
392 393 |
unsigned long flags; int ret = 0; |
1da177e4c Linux-2.6.12-rc2 |
394 395 |
if (current->signal->tty != tty) return 0; |
47f86834b redo locking of t... |
396 397 |
spin_lock_irqsave(&tty->ctrl_lock, flags); |
ab521dc0f [PATCH] tty: upda... |
398 399 400 |
if (!tty->pgrp) { printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL! "); |
9ffee4cbc tty_check_change(... |
401 |
goto out_unlock; |
1da177e4c Linux-2.6.12-rc2 |
402 |
} |
ab521dc0f [PATCH] tty: upda... |
403 |
if (task_pgrp(current) == tty->pgrp) |
9ffee4cbc tty_check_change(... |
404 405 |
goto out_unlock; spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
406 |
if (is_ignored(SIGTTOU)) |
47f86834b redo locking of t... |
407 408 409 410 411 |
goto out; if (is_current_pgrp_orphaned()) { ret = -EIO; goto out; } |
040b6362d tty: fix leakage ... |
412 413 |
kill_pgrp(task_pgrp(current), SIGTTOU, 1); set_thread_flag(TIF_SIGPENDING); |
47f86834b redo locking of t... |
414 415 |
ret = -ERESTARTSYS; out: |
9ffee4cbc tty_check_change(... |
416 417 |
return ret; out_unlock: |
47f86834b redo locking of t... |
418 419 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); return ret; |
1da177e4c Linux-2.6.12-rc2 |
420 421 422 |
} EXPORT_SYMBOL(tty_check_change); |
37bdfb074 tty_io: drag scre... |
423 |
static ssize_t hung_up_tty_read(struct file *file, char __user *buf, |
1da177e4c Linux-2.6.12-rc2 |
424 425 426 427 |
size_t count, loff_t *ppos) { return 0; } |
37bdfb074 tty_io: drag scre... |
428 |
static ssize_t hung_up_tty_write(struct file *file, const char __user *buf, |
1da177e4c Linux-2.6.12-rc2 |
429 430 431 432 433 434 |
size_t count, loff_t *ppos) { return -EIO; } /* No kernel lock held - none needed ;) */ |
37bdfb074 tty_io: drag scre... |
435 |
static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait) |
1da177e4c Linux-2.6.12-rc2 |
436 437 438 |
{ return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; } |
04f378b19 tty: BKL pushdown |
439 440 |
static long hung_up_tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
38ad2ed08 tty: restore lock... |
441 442 443 |
{ return cmd == TIOCSPGRP ? -ENOTTY : -EIO; } |
37bdfb074 tty_io: drag scre... |
444 |
static long hung_up_tty_compat_ioctl(struct file *file, |
38ad2ed08 tty: restore lock... |
445 |
unsigned int cmd, unsigned long arg) |
1da177e4c Linux-2.6.12-rc2 |
446 447 448 |
{ return cmd == TIOCSPGRP ? -ENOTTY : -EIO; } |
62322d255 [PATCH] make more... |
449 |
static const struct file_operations tty_fops = { |
1da177e4c Linux-2.6.12-rc2 |
450 451 452 453 |
.llseek = no_llseek, .read = tty_read, .write = tty_write, .poll = tty_poll, |
04f378b19 tty: BKL pushdown |
454 |
.unlocked_ioctl = tty_ioctl, |
e10cc1df1 tty: add compat_i... |
455 |
.compat_ioctl = tty_compat_ioctl, |
1da177e4c Linux-2.6.12-rc2 |
456 457 458 459 |
.open = tty_open, .release = tty_release, .fasync = tty_fasync, }; |
62322d255 [PATCH] make more... |
460 |
static const struct file_operations console_fops = { |
1da177e4c Linux-2.6.12-rc2 |
461 462 463 464 |
.llseek = no_llseek, .read = tty_read, .write = redirected_tty_write, .poll = tty_poll, |
04f378b19 tty: BKL pushdown |
465 |
.unlocked_ioctl = tty_ioctl, |
e10cc1df1 tty: add compat_i... |
466 |
.compat_ioctl = tty_compat_ioctl, |
1da177e4c Linux-2.6.12-rc2 |
467 468 469 470 |
.open = tty_open, .release = tty_release, .fasync = tty_fasync, }; |
62322d255 [PATCH] make more... |
471 |
static const struct file_operations hung_up_tty_fops = { |
1da177e4c Linux-2.6.12-rc2 |
472 473 474 475 |
.llseek = no_llseek, .read = hung_up_tty_read, .write = hung_up_tty_write, .poll = hung_up_tty_poll, |
04f378b19 tty: BKL pushdown |
476 |
.unlocked_ioctl = hung_up_tty_ioctl, |
38ad2ed08 tty: restore lock... |
477 |
.compat_ioctl = hung_up_tty_compat_ioctl, |
1da177e4c Linux-2.6.12-rc2 |
478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
.release = tty_release, }; static DEFINE_SPINLOCK(redirect_lock); static struct file *redirect; /** * tty_wakeup - request more data * @tty: terminal * * Internal and external helper for wakeups of tty. This function * informs the line discipline if present that the driver is ready * to receive more output data. */ |
37bdfb074 tty_io: drag scre... |
492 |
|
1da177e4c Linux-2.6.12-rc2 |
493 494 495 |
void tty_wakeup(struct tty_struct *tty) { struct tty_ldisc *ld; |
37bdfb074 tty_io: drag scre... |
496 |
|
1da177e4c Linux-2.6.12-rc2 |
497 498 |
if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { ld = tty_ldisc_ref(tty); |
37bdfb074 tty_io: drag scre... |
499 |
if (ld) { |
a352def21 tty: Ldisc revamp |
500 501 |
if (ld->ops->write_wakeup) ld->ops->write_wakeup(tty); |
1da177e4c Linux-2.6.12-rc2 |
502 503 504 |
tty_ldisc_deref(ld); } } |
4b19449db epoll keyed wakeu... |
505 |
wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
1da177e4c Linux-2.6.12-rc2 |
506 507 508 509 510 |
} EXPORT_SYMBOL_GPL(tty_wakeup); /** |
11dbf2039 tty: avoid recurs... |
511 |
* __tty_hangup - actual handler for hangup events |
65f27f384 WorkStruct: Pass ... |
512 |
* @work: tty device |
af9b897ee [PATCH] tty layer... |
513 |
* |
1bad879a0 tty: Fix up escap... |
514 |
* This can be called by the "eventd" kernel thread. That is process |
af9b897ee [PATCH] tty layer... |
515 516 517 518 519 520 521 522 523 |
* synchronous but doesn't hold any locks, so we need to make sure we * have the appropriate locks for what we're doing. * * The hangup event clears any pending redirections onto the hung up * device. It ensures future writes will error and it does the needed * line discipline hangup and signal delivery. The tty object itself * remains intact. * * Locking: |
ec79d6056 tty: replace BKL ... |
524 |
* BTM |
24ec839c4 [PATCH] tty: ->si... |
525 526 527 528 529 530 |
* redirect lock for undoing redirection * file list lock for manipulating list of ttys * tty_ldisc_lock from called functions * termios_mutex resetting termios data * tasklist_lock to walk task list for hangup event * ->siglock to protect ->signal/->sighand |
1da177e4c Linux-2.6.12-rc2 |
531 |
*/ |
11dbf2039 tty: avoid recurs... |
532 |
void __tty_hangup(struct tty_struct *tty) |
1da177e4c Linux-2.6.12-rc2 |
533 |
{ |
37bdfb074 tty_io: drag scre... |
534 |
struct file *cons_filp = NULL; |
1da177e4c Linux-2.6.12-rc2 |
535 536 |
struct file *filp, *f = NULL; struct task_struct *p; |
d996b62a8 tty: fix fu_list ... |
537 |
struct tty_file_private *priv; |
1da177e4c Linux-2.6.12-rc2 |
538 |
int closecount = 0, n; |
47f86834b redo locking of t... |
539 |
unsigned long flags; |
9c9f4ded9 tty: Add a kref c... |
540 |
int refs = 0; |
1da177e4c Linux-2.6.12-rc2 |
541 542 543 |
if (!tty) return; |
1da177e4c Linux-2.6.12-rc2 |
544 545 |
spin_lock(&redirect_lock); |
d996b62a8 tty: fix fu_list ... |
546 |
if (redirect && file_tty(redirect) == tty) { |
1da177e4c Linux-2.6.12-rc2 |
547 548 549 550 |
f = redirect; redirect = NULL; } spin_unlock(&redirect_lock); |
37bdfb074 tty_io: drag scre... |
551 |
|
11dbf2039 tty: avoid recurs... |
552 |
tty_lock(); |
acfa747ba TTY: open/hangup ... |
553 554 |
/* some functions below drop BTM, so we need this bit */ set_bit(TTY_HUPPING, &tty->flags); |
ec79d6056 tty: replace BKL ... |
555 556 557 |
/* inuse_filps is protected by the single tty lock, this really needs to change if we want to flush the workqueue with the lock held */ |
11dbf2039 tty: avoid recurs... |
558 |
check_tty_count(tty, "tty_hangup"); |
36ba782e9 tty: split the lo... |
559 |
|
ee2ffa0df fs: cleanup files... |
560 |
spin_lock(&tty_files_lock); |
1da177e4c Linux-2.6.12-rc2 |
561 |
/* This breaks for file handles being sent over AF_UNIX sockets ? */ |
d996b62a8 tty: fix fu_list ... |
562 563 |
list_for_each_entry(priv, &tty->tty_files, list) { filp = priv->file; |
1da177e4c Linux-2.6.12-rc2 |
564 565 566 567 568 |
if (filp->f_op->write == redirected_tty_write) cons_filp = filp; if (filp->f_op->write != tty_write) continue; closecount++; |
ec79d6056 tty: replace BKL ... |
569 |
__tty_fasync(-1, filp, 0); /* can't block */ |
1da177e4c Linux-2.6.12-rc2 |
570 571 |
filp->f_op = &hung_up_tty_fops; } |
ee2ffa0df fs: cleanup files... |
572 |
spin_unlock(&tty_files_lock); |
37bdfb074 tty_io: drag scre... |
573 |
|
acfa747ba TTY: open/hangup ... |
574 575 576 577 |
/* * it drops BTM and thus races with reopen * we protect the race by TTY_HUPPING */ |
c65c9bc3e tty: rewrite the ... |
578 |
tty_ldisc_hangup(tty); |
37bdfb074 tty_io: drag scre... |
579 |
|
1da177e4c Linux-2.6.12-rc2 |
580 |
read_lock(&tasklist_lock); |
ab521dc0f [PATCH] tty: upda... |
581 582 |
if (tty->session) { do_each_pid_task(tty->session, PIDTYPE_SID, p) { |
24ec839c4 [PATCH] tty: ->si... |
583 |
spin_lock_irq(&p->sighand->siglock); |
9c9f4ded9 tty: Add a kref c... |
584 |
if (p->signal->tty == tty) { |
1da177e4c Linux-2.6.12-rc2 |
585 |
p->signal->tty = NULL; |
9c9f4ded9 tty: Add a kref c... |
586 587 588 589 |
/* We defer the dereferences outside fo the tasklist lock */ refs++; } |
24ec839c4 [PATCH] tty: ->si... |
590 591 |
if (!p->signal->leader) { spin_unlock_irq(&p->sighand->siglock); |
1da177e4c Linux-2.6.12-rc2 |
592 |
continue; |
24ec839c4 [PATCH] tty: ->si... |
593 594 595 |
} __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); |
ab521dc0f [PATCH] tty: upda... |
596 |
put_pid(p->signal->tty_old_pgrp); /* A noop */ |
47f86834b redo locking of t... |
597 |
spin_lock_irqsave(&tty->ctrl_lock, flags); |
ab521dc0f [PATCH] tty: upda... |
598 599 |
if (tty->pgrp) p->signal->tty_old_pgrp = get_pid(tty->pgrp); |
47f86834b redo locking of t... |
600 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
24ec839c4 [PATCH] tty: ->si... |
601 |
spin_unlock_irq(&p->sighand->siglock); |
ab521dc0f [PATCH] tty: upda... |
602 |
} while_each_pid_task(tty->session, PIDTYPE_SID, p); |
1da177e4c Linux-2.6.12-rc2 |
603 604 |
} read_unlock(&tasklist_lock); |
47f86834b redo locking of t... |
605 |
spin_lock_irqsave(&tty->ctrl_lock, flags); |
c65c9bc3e tty: rewrite the ... |
606 607 608 |
clear_bit(TTY_THROTTLED, &tty->flags); clear_bit(TTY_PUSH, &tty->flags); clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
d9c1e9a8f [PATCH] tty: Fix ... |
609 610 |
put_pid(tty->session); put_pid(tty->pgrp); |
ab521dc0f [PATCH] tty: upda... |
611 612 |
tty->session = NULL; tty->pgrp = NULL; |
1da177e4c Linux-2.6.12-rc2 |
613 |
tty->ctrl_status = 0; |
47f86834b redo locking of t... |
614 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
9c9f4ded9 tty: Add a kref c... |
615 616 617 |
/* Account for the p->signal references we killed */ while (refs--) tty_kref_put(tty); |
1da177e4c Linux-2.6.12-rc2 |
618 |
/* |
37bdfb074 tty_io: drag scre... |
619 620 621 622 |
* If one of the devices matches a console pointer, we * cannot just call hangup() because that will cause * tty->count and state->count to go out of sync. * So we just call close() the right number of times. |
1da177e4c Linux-2.6.12-rc2 |
623 624 |
*/ if (cons_filp) { |
f34d7a5b7 tty: The big oper... |
625 |
if (tty->ops->close) |
1da177e4c Linux-2.6.12-rc2 |
626 |
for (n = 0; n < closecount; n++) |
f34d7a5b7 tty: The big oper... |
627 628 629 |
tty->ops->close(tty, cons_filp); } else if (tty->ops->hangup) (tty->ops->hangup)(tty); |
37bdfb074 tty_io: drag scre... |
630 631 632 633 634 635 |
/* * We don't want to have driver/ldisc interactions beyond * the ones we did here. The driver layer expects no * calls after ->hangup() from the ldisc side. However we * can't yet guarantee all that. */ |
1da177e4c Linux-2.6.12-rc2 |
636 |
set_bit(TTY_HUPPED, &tty->flags); |
acfa747ba TTY: open/hangup ... |
637 |
clear_bit(TTY_HUPPING, &tty->flags); |
c65c9bc3e tty: rewrite the ... |
638 |
tty_ldisc_enable(tty); |
11dbf2039 tty: avoid recurs... |
639 640 |
tty_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
641 642 643 |
if (f) fput(f); } |
ddcd9fb66 tty: remove tty_l... |
644 645 646 647 |
static void do_tty_hangup(struct work_struct *work) { struct tty_struct *tty = container_of(work, struct tty_struct, hangup_work); |
11dbf2039 tty: avoid recurs... |
648 |
__tty_hangup(tty); |
ddcd9fb66 tty: remove tty_l... |
649 |
} |
af9b897ee [PATCH] tty layer... |
650 651 652 653 654 655 656 |
/** * tty_hangup - trigger a hangup event * @tty: tty to hangup * * A carrier loss (virtual or otherwise) has occurred on this like * schedule a hangup sequence to run after this event. */ |
37bdfb074 tty_io: drag scre... |
657 |
void tty_hangup(struct tty_struct *tty) |
1da177e4c Linux-2.6.12-rc2 |
658 659 660 |
{ #ifdef TTY_DEBUG_HANGUP char buf[64]; |
1da177e4c Linux-2.6.12-rc2 |
661 662 663 664 665 666 667 |
printk(KERN_DEBUG "%s hangup... ", tty_name(tty, buf)); #endif schedule_work(&tty->hangup_work); } EXPORT_SYMBOL(tty_hangup); |
af9b897ee [PATCH] tty layer... |
668 669 670 671 672 673 |
/** * tty_vhangup - process vhangup * @tty: tty to hangup * * The user has asked via system call for the terminal to be hung up. * We do this synchronously so that when the syscall returns the process |
3a4fa0a25 Fix misspellings ... |
674 |
* is complete. That guarantee is necessary for security reasons. |
af9b897ee [PATCH] tty layer... |
675 |
*/ |
37bdfb074 tty_io: drag scre... |
676 |
void tty_vhangup(struct tty_struct *tty) |
1da177e4c Linux-2.6.12-rc2 |
677 678 679 680 681 682 683 |
{ #ifdef TTY_DEBUG_HANGUP char buf[64]; printk(KERN_DEBUG "%s vhangup... ", tty_name(tty, buf)); #endif |
11dbf2039 tty: avoid recurs... |
684 |
__tty_hangup(tty); |
1da177e4c Linux-2.6.12-rc2 |
685 |
} |
37bdfb074 tty_io: drag scre... |
686 |
|
1da177e4c Linux-2.6.12-rc2 |
687 |
EXPORT_SYMBOL(tty_vhangup); |
11dbf2039 tty: avoid recurs... |
688 |
|
af9b897ee [PATCH] tty layer... |
689 |
/** |
2cb5998b5 tty: the vhangup ... |
690 691 692 693 694 695 696 697 |
* tty_vhangup_self - process vhangup for own ctty * * Perform a vhangup on the current controlling tty */ void tty_vhangup_self(void) { struct tty_struct *tty; |
2cb5998b5 tty: the vhangup ... |
698 699 700 701 702 |
tty = get_current_tty(); if (tty) { tty_vhangup(tty); tty_kref_put(tty); } |
2cb5998b5 tty: the vhangup ... |
703 704 705 |
} /** |
af9b897ee [PATCH] tty layer... |
706 707 708 709 710 711 |
* tty_hung_up_p - was tty hung up * @filp: file pointer of tty * * Return true if the tty has been subject to a vhangup or a carrier * loss */ |
37bdfb074 tty_io: drag scre... |
712 |
int tty_hung_up_p(struct file *filp) |
1da177e4c Linux-2.6.12-rc2 |
713 714 715 716 717 |
{ return (filp->f_op == &hung_up_tty_fops); } EXPORT_SYMBOL(tty_hung_up_p); |
ab521dc0f [PATCH] tty: upda... |
718 |
static void session_clear_tty(struct pid *session) |
24ec839c4 [PATCH] tty: ->si... |
719 720 |
{ struct task_struct *p; |
ab521dc0f [PATCH] tty: upda... |
721 |
do_each_pid_task(session, PIDTYPE_SID, p) { |
24ec839c4 [PATCH] tty: ->si... |
722 |
proc_clear_tty(p); |
ab521dc0f [PATCH] tty: upda... |
723 |
} while_each_pid_task(session, PIDTYPE_SID, p); |
24ec839c4 [PATCH] tty: ->si... |
724 |
} |
af9b897ee [PATCH] tty layer... |
725 726 727 |
/** * disassociate_ctty - disconnect controlling tty * @on_exit: true if exiting so need to "hang up" the session |
1da177e4c Linux-2.6.12-rc2 |
728 |
* |
af9b897ee [PATCH] tty layer... |
729 730 731 732 |
* This function is typically called only by the session leader, when * it wants to disassociate itself from its controlling tty. * * It performs the following functions: |
1da177e4c Linux-2.6.12-rc2 |
733 734 735 736 737 |
* (1) Sends a SIGHUP and SIGCONT to the foreground process group * (2) Clears the tty from being controlling the session * (3) Clears the controlling tty for all processes in the * session group. * |
af9b897ee [PATCH] tty layer... |
738 739 740 |
* The argument on_exit is set to 1 if called when a process is * exiting; it is 0 if called by the ioctl TIOCNOTTY. * |
24ec839c4 [PATCH] tty: ->si... |
741 |
* Locking: |
ec79d6056 tty: replace BKL ... |
742 743 |
* BTM is taken for hysterical raisins, and held when * called from no_tty(). |
24ec839c4 [PATCH] tty: ->si... |
744 745 746 747 |
* tty_mutex is taken to protect tty * ->siglock is taken to protect ->signal/->sighand * tasklist_lock is taken to walk process list for sessions * ->siglock is taken to protect ->signal/->sighand |
1da177e4c Linux-2.6.12-rc2 |
748 |
*/ |
af9b897ee [PATCH] tty layer... |
749 |
|
1da177e4c Linux-2.6.12-rc2 |
750 751 752 |
void disassociate_ctty(int on_exit) { struct tty_struct *tty; |
1da177e4c Linux-2.6.12-rc2 |
753 |
|
5ec93d115 tty: Move the lea... |
754 755 |
if (!current->signal->leader) return; |
1da177e4c Linux-2.6.12-rc2 |
756 |
|
24ec839c4 [PATCH] tty: ->si... |
757 |
tty = get_current_tty(); |
1da177e4c Linux-2.6.12-rc2 |
758 |
if (tty) { |
1411dc4aa TTY: move pgrp ki... |
759 |
struct pid *tty_pgrp = get_pid(tty->pgrp); |
ddcd9fb66 tty: remove tty_l... |
760 |
if (on_exit) { |
ddcd9fb66 tty: remove tty_l... |
761 |
if (tty->driver->type != TTY_DRIVER_TYPE_PTY) |
11dbf2039 tty: avoid recurs... |
762 |
tty_vhangup(tty); |
ddcd9fb66 tty: remove tty_l... |
763 |
} |
452a00d2e tty: Make get_cur... |
764 |
tty_kref_put(tty); |
1411dc4aa TTY: move pgrp ki... |
765 766 767 768 769 770 |
if (tty_pgrp) { kill_pgrp(tty_pgrp, SIGHUP, on_exit); if (!on_exit) kill_pgrp(tty_pgrp, SIGCONT, on_exit); put_pid(tty_pgrp); } |
680a96710 [PATCH] tty: clar... |
771 |
} else if (on_exit) { |
ab521dc0f [PATCH] tty: upda... |
772 |
struct pid *old_pgrp; |
680a96710 [PATCH] tty: clar... |
773 774 |
spin_lock_irq(¤t->sighand->siglock); old_pgrp = current->signal->tty_old_pgrp; |
ab521dc0f [PATCH] tty: upda... |
775 |
current->signal->tty_old_pgrp = NULL; |
680a96710 [PATCH] tty: clar... |
776 |
spin_unlock_irq(¤t->sighand->siglock); |
24ec839c4 [PATCH] tty: ->si... |
777 |
if (old_pgrp) { |
ab521dc0f [PATCH] tty: upda... |
778 779 780 |
kill_pgrp(old_pgrp, SIGHUP, on_exit); kill_pgrp(old_pgrp, SIGCONT, on_exit); put_pid(old_pgrp); |
1da177e4c Linux-2.6.12-rc2 |
781 |
} |
1da177e4c Linux-2.6.12-rc2 |
782 783 |
return; } |
1da177e4c Linux-2.6.12-rc2 |
784 |
|
24ec839c4 [PATCH] tty: ->si... |
785 |
spin_lock_irq(¤t->sighand->siglock); |
2a65f1d9f tty: simplify cal... |
786 |
put_pid(current->signal->tty_old_pgrp); |
23cac8deb [PATCH] tty: use ... |
787 |
current->signal->tty_old_pgrp = NULL; |
24ec839c4 [PATCH] tty: ->si... |
788 |
spin_unlock_irq(¤t->sighand->siglock); |
24ec839c4 [PATCH] tty: ->si... |
789 790 |
tty = get_current_tty(); if (tty) { |
47f86834b redo locking of t... |
791 792 |
unsigned long flags; spin_lock_irqsave(&tty->ctrl_lock, flags); |
ab521dc0f [PATCH] tty: upda... |
793 794 795 796 |
put_pid(tty->session); put_pid(tty->pgrp); tty->session = NULL; tty->pgrp = NULL; |
47f86834b redo locking of t... |
797 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
452a00d2e tty: Make get_cur... |
798 |
tty_kref_put(tty); |
24ec839c4 [PATCH] tty: ->si... |
799 800 801 802 803 804 |
} else { #ifdef TTY_DEBUG_HANGUP printk(KERN_DEBUG "error attempted to write to tty [0x%p]" " = NULL", tty); #endif } |
1da177e4c Linux-2.6.12-rc2 |
805 806 807 |
/* Now clear signal->tty under the lock */ read_lock(&tasklist_lock); |
ab521dc0f [PATCH] tty: upda... |
808 |
session_clear_tty(task_session(current)); |
1da177e4c Linux-2.6.12-rc2 |
809 |
read_unlock(&tasklist_lock); |
1da177e4c Linux-2.6.12-rc2 |
810 |
} |
98a27ba48 tty: introduce no... |
811 812 813 814 815 816 817 |
/** * * no_tty - Ensure the current process does not have a controlling tty */ void no_tty(void) { struct task_struct *tsk = current; |
ec79d6056 tty: replace BKL ... |
818 |
tty_lock(); |
5ec93d115 tty: Move the lea... |
819 |
disassociate_ctty(0); |
ec79d6056 tty: replace BKL ... |
820 |
tty_unlock(); |
98a27ba48 tty: introduce no... |
821 822 |
proc_clear_tty(tsk); } |
af9b897ee [PATCH] tty layer... |
823 824 |
/** |
beb7dd86a Fix misspellings ... |
825 |
* stop_tty - propagate flow control |
af9b897ee [PATCH] tty layer... |
826 827 828 |
* @tty: tty to stop * * Perform flow control to the driver. For PTY/TTY pairs we |
beb7dd86a Fix misspellings ... |
829 |
* must also propagate the TIOCKPKT status. May be called |
af9b897ee [PATCH] tty layer... |
830 831 832 833 834 835 836 837 838 |
* on an already stopped device and will not re-call the driver * method. * * This functionality is used by both the line disciplines for * halting incoming flow and by the driver. It may therefore be * called from any context, may be under the tty atomic_write_lock * but not always. * * Locking: |
04f378b19 tty: BKL pushdown |
839 |
* Uses the tty control lock internally |
af9b897ee [PATCH] tty layer... |
840 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
841 842 |
void stop_tty(struct tty_struct *tty) { |
04f378b19 tty: BKL pushdown |
843 844 845 846 |
unsigned long flags; spin_lock_irqsave(&tty->ctrl_lock, flags); if (tty->stopped) { spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
847 |
return; |
04f378b19 tty: BKL pushdown |
848 |
} |
1da177e4c Linux-2.6.12-rc2 |
849 850 851 852 |
tty->stopped = 1; if (tty->link && tty->link->packet) { tty->ctrl_status &= ~TIOCPKT_START; tty->ctrl_status |= TIOCPKT_STOP; |
4b19449db epoll keyed wakeu... |
853 |
wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); |
1da177e4c Linux-2.6.12-rc2 |
854 |
} |
04f378b19 tty: BKL pushdown |
855 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
f34d7a5b7 tty: The big oper... |
856 857 |
if (tty->ops->stop) (tty->ops->stop)(tty); |
1da177e4c Linux-2.6.12-rc2 |
858 859 860 |
} EXPORT_SYMBOL(stop_tty); |
af9b897ee [PATCH] tty layer... |
861 |
/** |
beb7dd86a Fix misspellings ... |
862 |
* start_tty - propagate flow control |
af9b897ee [PATCH] tty layer... |
863 864 865 |
* @tty: tty to start * * Start a tty that has been stopped if at all possible. Perform |
3a4fa0a25 Fix misspellings ... |
866 |
* any necessary wakeups and propagate the TIOCPKT status. If this |
af9b897ee [PATCH] tty layer... |
867 868 869 870 |
* is the tty was previous stopped and is being started then the * driver start method is invoked and the line discipline woken. * * Locking: |
04f378b19 tty: BKL pushdown |
871 |
* ctrl_lock |
af9b897ee [PATCH] tty layer... |
872 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
873 874 |
void start_tty(struct tty_struct *tty) { |
04f378b19 tty: BKL pushdown |
875 876 877 878 |
unsigned long flags; spin_lock_irqsave(&tty->ctrl_lock, flags); if (!tty->stopped || tty->flow_stopped) { spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
879 |
return; |
04f378b19 tty: BKL pushdown |
880 |
} |
1da177e4c Linux-2.6.12-rc2 |
881 882 883 884 |
tty->stopped = 0; if (tty->link && tty->link->packet) { tty->ctrl_status &= ~TIOCPKT_STOP; tty->ctrl_status |= TIOCPKT_START; |
4b19449db epoll keyed wakeu... |
885 |
wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); |
1da177e4c Linux-2.6.12-rc2 |
886 |
} |
04f378b19 tty: BKL pushdown |
887 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
f34d7a5b7 tty: The big oper... |
888 889 |
if (tty->ops->start) (tty->ops->start)(tty); |
1da177e4c Linux-2.6.12-rc2 |
890 891 |
/* If we have a running line discipline it may need kicking */ tty_wakeup(tty); |
1da177e4c Linux-2.6.12-rc2 |
892 893 894 |
} EXPORT_SYMBOL(start_tty); |
af9b897ee [PATCH] tty layer... |
895 896 897 898 899 900 901 902 903 904 905 |
/** * tty_read - read method for tty device files * @file: pointer to tty file * @buf: user buffer * @count: size of user buffer * @ppos: unused * * Perform the read system call function on this terminal device. Checks * for hung up devices before calling the line discipline method. * * Locking: |
47f86834b redo locking of t... |
906 907 |
* Locks the line discipline internally while needed. Multiple * read calls may be outstanding in parallel. |
af9b897ee [PATCH] tty layer... |
908 |
*/ |
37bdfb074 tty_io: drag scre... |
909 |
static ssize_t tty_read(struct file *file, char __user *buf, size_t count, |
1da177e4c Linux-2.6.12-rc2 |
910 911 912 |
loff_t *ppos) { int i; |
d996b62a8 tty: fix fu_list ... |
913 914 |
struct inode *inode = file->f_path.dentry->d_inode; struct tty_struct *tty = file_tty(file); |
1da177e4c Linux-2.6.12-rc2 |
915 |
struct tty_ldisc *ld; |
1da177e4c Linux-2.6.12-rc2 |
916 917 918 919 920 921 922 923 |
if (tty_paranoia_check(tty, inode, "tty_read")) return -EIO; if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) return -EIO; /* We want to wait for the line discipline to sort out in this situation */ ld = tty_ldisc_ref_wait(tty); |
a352def21 tty: Ldisc revamp |
924 925 |
if (ld->ops->read) i = (ld->ops->read)(tty, file, buf, count); |
1da177e4c Linux-2.6.12-rc2 |
926 927 928 |
else i = -EIO; tty_ldisc_deref(ld); |
1da177e4c Linux-2.6.12-rc2 |
929 930 931 932 |
if (i > 0) inode->i_atime = current_fs_time(inode->i_sb); return i; } |
9c1729db3 Prevent an O_NDEL... |
933 |
void tty_write_unlock(struct tty_struct *tty) |
83c67571b TTY: tty_io, anno... |
934 |
__releases(&tty->atomic_write_lock) |
9c1729db3 Prevent an O_NDEL... |
935 936 |
{ mutex_unlock(&tty->atomic_write_lock); |
4b19449db epoll keyed wakeu... |
937 |
wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
9c1729db3 Prevent an O_NDEL... |
938 939 940 |
} int tty_write_lock(struct tty_struct *tty, int ndelay) |
83c67571b TTY: tty_io, anno... |
941 |
__acquires(&tty->atomic_write_lock) |
9c1729db3 Prevent an O_NDEL... |
942 943 944 945 946 947 948 949 950 |
{ if (!mutex_trylock(&tty->atomic_write_lock)) { if (ndelay) return -EAGAIN; if (mutex_lock_interruptible(&tty->atomic_write_lock)) return -ERESTARTSYS; } return 0; } |
1da177e4c Linux-2.6.12-rc2 |
951 952 953 954 955 956 957 958 959 960 961 |
/* * Split writes up in sane blocksizes to avoid * denial-of-service type attacks */ static inline ssize_t do_tty_write( ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t), struct tty_struct *tty, struct file *file, const char __user *buf, size_t count) { |
9c1729db3 Prevent an O_NDEL... |
962 |
ssize_t ret, written = 0; |
1da177e4c Linux-2.6.12-rc2 |
963 |
unsigned int chunk; |
37bdfb074 tty_io: drag scre... |
964 |
|
9c1729db3 Prevent an O_NDEL... |
965 966 967 |
ret = tty_write_lock(tty, file->f_flags & O_NDELAY); if (ret < 0) return ret; |
1da177e4c Linux-2.6.12-rc2 |
968 969 970 971 972 973 974 975 976 977 978 979 980 |
/* * We chunk up writes into a temporary buffer. This * simplifies low-level drivers immensely, since they * don't have locking issues and user mode accesses. * * But if TTY_NO_WRITE_SPLIT is set, we should use a * big chunk-size.. * * The default chunk-size is 2kB, because the NTTY * layer has problems with bigger chunks. It will * claim to be able to handle more characters than * it actually does. |
af9b897ee [PATCH] tty layer... |
981 982 983 |
* * FIXME: This can probably go away now except that 64K chunks * are too likely to fail unless switched to vmalloc... |
1da177e4c Linux-2.6.12-rc2 |
984 985 986 987 988 989 |
*/ chunk = 2048; if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) chunk = 65536; if (count < chunk) chunk = count; |
70522e121 [PATCH] sem2mutex... |
990 |
/* write_buf/write_cnt is protected by the atomic_write_lock mutex */ |
1da177e4c Linux-2.6.12-rc2 |
991 |
if (tty->write_cnt < chunk) { |
402fda920 tty: tty_io.c sha... |
992 |
unsigned char *buf_chunk; |
1da177e4c Linux-2.6.12-rc2 |
993 994 995 |
if (chunk < 1024) chunk = 1024; |
402fda920 tty: tty_io.c sha... |
996 997 |
buf_chunk = kmalloc(chunk, GFP_KERNEL); if (!buf_chunk) { |
9c1729db3 Prevent an O_NDEL... |
998 999 |
ret = -ENOMEM; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1000 1001 1002 |
} kfree(tty->write_buf); tty->write_cnt = chunk; |
402fda920 tty: tty_io.c sha... |
1003 |
tty->write_buf = buf_chunk; |
1da177e4c Linux-2.6.12-rc2 |
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 |
} /* Do the write .. */ for (;;) { size_t size = count; if (size > chunk) size = chunk; ret = -EFAULT; if (copy_from_user(tty->write_buf, buf, size)) break; |
1da177e4c Linux-2.6.12-rc2 |
1014 |
ret = write(tty, file, tty->write_buf, size); |
1da177e4c Linux-2.6.12-rc2 |
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 |
if (ret <= 0) break; written += ret; buf += ret; count -= ret; if (!count) break; ret = -ERESTARTSYS; if (signal_pending(current)) break; cond_resched(); } if (written) { |
a7113a966 [PATCH] struct pa... |
1028 |
struct inode *inode = file->f_path.dentry->d_inode; |
1da177e4c Linux-2.6.12-rc2 |
1029 1030 1031 |
inode->i_mtime = current_fs_time(inode->i_sb); ret = written; } |
9c1729db3 Prevent an O_NDEL... |
1032 1033 |
out: tty_write_unlock(tty); |
1da177e4c Linux-2.6.12-rc2 |
1034 1035 |
return ret; } |
95f9bfc6b tty: Move tty_wri... |
1036 1037 1038 1039 1040 1041 1042 1043 1044 |
/** * tty_write_message - write a message to a certain tty, not just the console. * @tty: the destination tty_struct * @msg: the message to write * * This is used for messages that need to be redirected to a specific tty. * We don't put it into the syslog queue right now maybe in the future if * really needed. * |
ec79d6056 tty: replace BKL ... |
1045 |
* We must still hold the BTM and test the CLOSING flag for the moment. |
95f9bfc6b tty: Move tty_wri... |
1046 1047 1048 1049 |
*/ void tty_write_message(struct tty_struct *tty, char *msg) { |
95f9bfc6b tty: Move tty_wri... |
1050 1051 |
if (tty) { mutex_lock(&tty->atomic_write_lock); |
ec79d6056 tty: replace BKL ... |
1052 |
tty_lock(); |
eeb89d918 tty: push the BKL... |
1053 |
if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { |
ec79d6056 tty: replace BKL ... |
1054 |
tty_unlock(); |
95f9bfc6b tty: Move tty_wri... |
1055 |
tty->ops->write(tty, msg, strlen(msg)); |
eeb89d918 tty: push the BKL... |
1056 |
} else |
ec79d6056 tty: replace BKL ... |
1057 |
tty_unlock(); |
95f9bfc6b tty: Move tty_wri... |
1058 1059 |
tty_write_unlock(tty); } |
95f9bfc6b tty: Move tty_wri... |
1060 1061 |
return; } |
1da177e4c Linux-2.6.12-rc2 |
1062 |
|
af9b897ee [PATCH] tty layer... |
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 |
/** * tty_write - write method for tty device file * @file: tty file pointer * @buf: user data to write * @count: bytes to write * @ppos: unused * * Write data to a tty device via the line discipline. * * Locking: * Locks the line discipline as required * Writes to the tty driver are serialized by the atomic_write_lock * and are then processed in chunks to the device. The line discipline |
a88a69c91 n_tty: Fix loss o... |
1076 |
* write method will not be invoked in parallel for each device. |
af9b897ee [PATCH] tty layer... |
1077 |
*/ |
37bdfb074 tty_io: drag scre... |
1078 1079 |
static ssize_t tty_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) |
1da177e4c Linux-2.6.12-rc2 |
1080 |
{ |
a7113a966 [PATCH] struct pa... |
1081 |
struct inode *inode = file->f_path.dentry->d_inode; |
d996b62a8 tty: fix fu_list ... |
1082 1083 |
struct tty_struct *tty = file_tty(file); struct tty_ldisc *ld; |
1da177e4c Linux-2.6.12-rc2 |
1084 |
ssize_t ret; |
37bdfb074 tty_io: drag scre... |
1085 |
|
1da177e4c Linux-2.6.12-rc2 |
1086 1087 |
if (tty_paranoia_check(tty, inode, "tty_write")) return -EIO; |
f34d7a5b7 tty: The big oper... |
1088 |
if (!tty || !tty->ops->write || |
37bdfb074 tty_io: drag scre... |
1089 1090 |
(test_bit(TTY_IO_ERROR, &tty->flags))) return -EIO; |
f34d7a5b7 tty: The big oper... |
1091 1092 1093 1094 1095 |
/* Short term debug to catch buggy drivers */ if (tty->ops->write_room == NULL) printk(KERN_ERR "tty driver %s lacks a write_room method. ", tty->driver->name); |
37bdfb074 tty_io: drag scre... |
1096 |
ld = tty_ldisc_ref_wait(tty); |
a352def21 tty: Ldisc revamp |
1097 |
if (!ld->ops->write) |
1da177e4c Linux-2.6.12-rc2 |
1098 1099 |
ret = -EIO; else |
a352def21 tty: Ldisc revamp |
1100 |
ret = do_tty_write(ld->ops->write, tty, file, buf, count); |
1da177e4c Linux-2.6.12-rc2 |
1101 1102 1103 |
tty_ldisc_deref(ld); return ret; } |
37bdfb074 tty_io: drag scre... |
1104 1105 |
ssize_t redirected_tty_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) |
1da177e4c Linux-2.6.12-rc2 |
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 |
{ struct file *p = NULL; spin_lock(&redirect_lock); if (redirect) { get_file(redirect); p = redirect; } spin_unlock(&redirect_lock); if (p) { ssize_t res; res = vfs_write(p, buf, count, &p->f_pos); fput(p); return res; } |
1da177e4c Linux-2.6.12-rc2 |
1122 1123 1124 1125 |
return tty_write(file, buf, count, ppos); } static char ptychar[] = "pqrstuvwxyzabcde"; |
af9b897ee [PATCH] tty layer... |
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 |
/** * pty_line_name - generate name for a pty * @driver: the tty driver in use * @index: the minor number * @p: output buffer of at least 6 bytes * * Generate a name from a driver reference and write it to the output * buffer. * * Locking: None */ static void pty_line_name(struct tty_driver *driver, int index, char *p) |
1da177e4c Linux-2.6.12-rc2 |
1138 1139 1140 1141 |
{ int i = index + driver->name_base; /* ->name is initialized to "ttyp", but "tty" is expected */ sprintf(p, "%s%c%x", |
37bdfb074 tty_io: drag scre... |
1142 1143 |
driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name, ptychar[i >> 4 & 0xf], i & 0xf); |
1da177e4c Linux-2.6.12-rc2 |
1144 |
} |
af9b897ee [PATCH] tty layer... |
1145 |
/** |
8b0a88d59 tty: More driver ... |
1146 |
* tty_line_name - generate name for a tty |
af9b897ee [PATCH] tty layer... |
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 |
* @driver: the tty driver in use * @index: the minor number * @p: output buffer of at least 7 bytes * * Generate a name from a driver reference and write it to the output * buffer. * * Locking: None */ static void tty_line_name(struct tty_driver *driver, int index, char *p) |
1da177e4c Linux-2.6.12-rc2 |
1157 1158 1159 |
{ sprintf(p, "%s%d", driver->name, index + driver->name_base); } |
99f1fe189 tty: Clean up the... |
1160 1161 1162 1163 |
/** * tty_driver_lookup_tty() - find an existing tty, if any * @driver: the driver for the tty * @idx: the minor number |
234997057 tty: Move parts o... |
1164 |
* |
99f1fe189 tty: Clean up the... |
1165 |
* Return the tty, if found or ERR_PTR() otherwise. |
234997057 tty: Move parts o... |
1166 |
* |
99f1fe189 tty: Clean up the... |
1167 1168 1169 |
* Locking: tty_mutex must be held. If tty is found, the mutex must * be held until the 'fast-open' is also done. Will change once we * have refcounting in the driver and per driver locking |
234997057 tty: Move parts o... |
1170 |
*/ |
a47d545f5 tty: Fix sparse s... |
1171 |
static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, |
15f1a6338 Add an instance p... |
1172 |
struct inode *inode, int idx) |
234997057 tty: Move parts o... |
1173 1174 |
{ struct tty_struct *tty; |
99f1fe189 tty: Clean up the... |
1175 |
if (driver->ops->lookup) |
15f1a6338 Add an instance p... |
1176 |
return driver->ops->lookup(driver, inode, idx); |
234997057 tty: Move parts o... |
1177 |
|
8b0a88d59 tty: More driver ... |
1178 |
tty = driver->ttys[idx]; |
234997057 tty: Move parts o... |
1179 1180 |
return tty; } |
99f1fe189 tty: Clean up the... |
1181 |
/** |
bf970ee46 tty: extract the ... |
1182 1183 1184 1185 1186 1187 1188 1189 1190 |
* tty_init_termios - helper for termios setup * @tty: the tty to set up * * Initialise the termios structures for this tty. Thus runs under * the tty_mutex currently so we can be relaxed about ordering. */ int tty_init_termios(struct tty_struct *tty) { |
fe6e29fdb tty: simplify kte... |
1191 |
struct ktermios *tp; |
bf970ee46 tty: extract the ... |
1192 1193 1194 |
int idx = tty->index; tp = tty->driver->termios[idx]; |
bf970ee46 tty: extract the ... |
1195 |
if (tp == NULL) { |
fe6e29fdb tty: simplify kte... |
1196 1197 |
tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); if (tp == NULL) |
bf970ee46 tty: extract the ... |
1198 |
return -ENOMEM; |
bf970ee46 tty: extract the ... |
1199 1200 1201 |
memcpy(tp, &tty->driver->init_termios, sizeof(struct ktermios)); tty->driver->termios[idx] = tp; |
bf970ee46 tty: extract the ... |
1202 1203 |
} tty->termios = tp; |
fe6e29fdb tty: simplify kte... |
1204 |
tty->termios_locked = tp + 1; |
bf970ee46 tty: extract the ... |
1205 1206 1207 1208 1209 1210 |
/* Compatibility until drivers always set this */ tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); return 0; } |
fe1ae7fdd tty: USB serial t... |
1211 |
EXPORT_SYMBOL_GPL(tty_init_termios); |
bf970ee46 tty: extract the ... |
1212 1213 |
/** |
8b0a88d59 tty: More driver ... |
1214 1215 1216 1217 1218 |
* tty_driver_install_tty() - install a tty entry in the driver * @driver: the driver for the tty * @tty: the tty * * Install a tty object into the driver tables. The tty->index field |
bf970ee46 tty: extract the ... |
1219 1220 1221 |
* will be set by the time this is called. This method is responsible * for ensuring any need additional structures are allocated and * configured. |
8b0a88d59 tty: More driver ... |
1222 1223 1224 1225 1226 1227 |
* * Locking: tty_mutex for now */ static int tty_driver_install_tty(struct tty_driver *driver, struct tty_struct *tty) { |
bf970ee46 tty: extract the ... |
1228 |
int idx = tty->index; |
eeb89d918 tty: push the BKL... |
1229 |
int ret; |
bf970ee46 tty: extract the ... |
1230 |
|
eeb89d918 tty: push the BKL... |
1231 |
if (driver->ops->install) { |
eeb89d918 tty: push the BKL... |
1232 |
ret = driver->ops->install(driver, tty); |
eeb89d918 tty: push the BKL... |
1233 1234 |
return ret; } |
bf970ee46 tty: extract the ... |
1235 1236 1237 1238 1239 1240 1241 1242 |
if (tty_init_termios(tty) == 0) { tty_driver_kref_get(driver); tty->count++; driver->ttys[idx] = tty; return 0; } return -ENOMEM; |
8b0a88d59 tty: More driver ... |
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 |
} /** * tty_driver_remove_tty() - remove a tty from the driver tables * @driver: the driver for the tty * @idx: the minor number * * Remvoe a tty object from the driver tables. The tty->index field * will be set by the time this is called. * * Locking: tty_mutex for now */ |
24d406a6b TTY: pty, fix pty... |
1255 |
void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty) |
8b0a88d59 tty: More driver ... |
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 |
{ if (driver->ops->remove) driver->ops->remove(driver, tty); else driver->ttys[tty->index] = NULL; } /* * tty_reopen() - fast re-open of an open tty * @tty - the tty to open |
234997057 tty: Move parts o... |
1266 |
* |
99f1fe189 tty: Clean up the... |
1267 |
* Return 0 on success, -errno on error. |
234997057 tty: Move parts o... |
1268 |
* |
99f1fe189 tty: Clean up the... |
1269 1270 |
* Locking: tty_mutex must be held from the time the tty was found * till this open completes. |
234997057 tty: Move parts o... |
1271 |
*/ |
99f1fe189 tty: Clean up the... |
1272 |
static int tty_reopen(struct tty_struct *tty) |
234997057 tty: Move parts o... |
1273 1274 |
{ struct tty_driver *driver = tty->driver; |
e2efafbf1 TTY: don't allow ... |
1275 |
if (test_bit(TTY_CLOSING, &tty->flags) || |
acfa747ba TTY: open/hangup ... |
1276 |
test_bit(TTY_HUPPING, &tty->flags) || |
e2efafbf1 TTY: don't allow ... |
1277 |
test_bit(TTY_LDISC_CHANGING, &tty->flags)) |
234997057 tty: Move parts o... |
1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 |
return -EIO; if (driver->type == TTY_DRIVER_TYPE_PTY && driver->subtype == PTY_TYPE_MASTER) { /* * special case for PTY masters: only one open permitted, * and the slave side open count is incremented as well. */ if (tty->count) return -EIO; tty->link->count++; } tty->count++; tty->driver = driver; /* N.B. why do this every time?? */ |
1aa4bed82 tty: fix sanity c... |
1293 |
mutex_lock(&tty->ldisc_mutex); |
99f1fe189 tty: Clean up the... |
1294 |
WARN_ON(!test_bit(TTY_LDISC, &tty->flags)); |
1aa4bed82 tty: fix sanity c... |
1295 |
mutex_unlock(&tty->ldisc_mutex); |
234997057 tty: Move parts o... |
1296 1297 1298 |
return 0; } |
af9b897ee [PATCH] tty layer... |
1299 |
/** |
d81ed1030 tty: Remove more ... |
1300 |
* tty_init_dev - initialise a tty device |
af9b897ee [PATCH] tty layer... |
1301 1302 |
* @driver: tty driver we are opening a device on * @idx: device index |
15582d36a pty: If the admin... |
1303 1304 |
* @ret_tty: returned tty structure * @first_ok: ok to open a new device (used by ptmx) |
af9b897ee [PATCH] tty layer... |
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 |
* * Prepare a tty device. This may not be a "new" clean device but * could also be an active device. The pty drivers require special * handling because of this. * * Locking: * The function is called under the tty_mutex, which * protects us from the tty struct or driver itself going away. * * On exit the tty device has the line discipline attached and * a reference count of 1. If a pair was created for pty/tty use * and the other was a pty master then it too has a reference count of 1. * |
1da177e4c Linux-2.6.12-rc2 |
1318 |
* WSH 06/09/97: Rewritten to remove races and properly clean up after a |
70522e121 [PATCH] sem2mutex... |
1319 1320 |
* failed open. The new code protects the open with a mutex, so it's * really quite straightforward. The mutex locking can probably be |
1da177e4c Linux-2.6.12-rc2 |
1321 1322 |
* relaxed for the (most common) case of reopening a tty. */ |
af9b897ee [PATCH] tty layer... |
1323 |
|
73ec06fc5 tty: Finish fixin... |
1324 1325 |
struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, int first_ok) |
1da177e4c Linux-2.6.12-rc2 |
1326 |
{ |
bf970ee46 tty: extract the ... |
1327 |
struct tty_struct *tty; |
73ec06fc5 tty: Finish fixin... |
1328 |
int retval; |
1da177e4c Linux-2.6.12-rc2 |
1329 |
|
234997057 tty: Move parts o... |
1330 |
/* Check if pty master is being opened multiple times */ |
15582d36a pty: If the admin... |
1331 |
if (driver->subtype == PTY_TYPE_MASTER && |
eeb89d918 tty: push the BKL... |
1332 |
(driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { |
73ec06fc5 tty: Finish fixin... |
1333 |
return ERR_PTR(-EIO); |
eeb89d918 tty: push the BKL... |
1334 |
} |
73ec06fc5 tty: Finish fixin... |
1335 |
|
1da177e4c Linux-2.6.12-rc2 |
1336 1337 1338 1339 |
/* * First time open is complex, especially for PTY devices. * This code guarantees that either everything succeeds and the * TTY is ready for operation, or else the table slots are vacated |
37bdfb074 tty_io: drag scre... |
1340 |
* and the allocated memory released. (Except that the termios |
1da177e4c Linux-2.6.12-rc2 |
1341 1342 |
* and locked termios may be retained.) */ |
73ec06fc5 tty: Finish fixin... |
1343 1344 |
if (!try_module_get(driver->owner)) return ERR_PTR(-ENODEV); |
1da177e4c Linux-2.6.12-rc2 |
1345 |
|
1da177e4c Linux-2.6.12-rc2 |
1346 |
tty = alloc_tty_struct(); |
d55435037 TTY: unify tty_in... |
1347 1348 1349 1350 |
if (!tty) { retval = -ENOMEM; goto err_module_put; } |
bf970ee46 tty: extract the ... |
1351 |
initialize_tty_struct(tty, driver, idx); |
1da177e4c Linux-2.6.12-rc2 |
1352 |
|
73ec06fc5 tty: Finish fixin... |
1353 |
retval = tty_driver_install_tty(driver, tty); |
d55435037 TTY: unify tty_in... |
1354 |
if (retval < 0) |
a9dccddb6 TTY: plug in dein... |
1355 |
goto err_deinit_tty; |
8b0a88d59 tty: More driver ... |
1356 |
|
37bdfb074 tty_io: drag scre... |
1357 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1358 |
* Structures all installed ... call the ldisc open routines. |
d5698c28b [PATCH] tty: clea... |
1359 1360 |
* If we fail here just call release_tty to clean up. No need * to decrement the use counts, as release_tty doesn't care. |
1da177e4c Linux-2.6.12-rc2 |
1361 |
*/ |
bf970ee46 tty: extract the ... |
1362 |
retval = tty_ldisc_setup(tty, tty->link); |
01e1abb2c tty: Split ldisc ... |
1363 |
if (retval) |
d55435037 TTY: unify tty_in... |
1364 |
goto err_release_tty; |
73ec06fc5 tty: Finish fixin... |
1365 |
return tty; |
1da177e4c Linux-2.6.12-rc2 |
1366 |
|
a9dccddb6 TTY: plug in dein... |
1367 1368 |
err_deinit_tty: deinitialize_tty_struct(tty); |
d55435037 TTY: unify tty_in... |
1369 1370 |
free_tty_struct(tty); err_module_put: |
1da177e4c Linux-2.6.12-rc2 |
1371 |
module_put(driver->owner); |
d55435037 TTY: unify tty_in... |
1372 |
return ERR_PTR(retval); |
1da177e4c Linux-2.6.12-rc2 |
1373 |
|
d5698c28b [PATCH] tty: clea... |
1374 |
/* call the tty release_tty routine to clean out this slot */ |
d55435037 TTY: unify tty_in... |
1375 |
err_release_tty: |
5a3c6b251 drivers/tty: use ... |
1376 |
printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " |
4050914f7 [PATCH] rate limi... |
1377 1378 |
"clearing slot %d ", idx); |
d5698c28b [PATCH] tty: clea... |
1379 |
release_tty(tty, idx); |
73ec06fc5 tty: Finish fixin... |
1380 |
return ERR_PTR(retval); |
1da177e4c Linux-2.6.12-rc2 |
1381 |
} |
feebed651 tty: shutdown method |
1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 |
void tty_free_termios(struct tty_struct *tty) { struct ktermios *tp; int idx = tty->index; /* Kill this flag and push into drivers for locking etc */ if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { /* FIXME: Locking on ->termios array */ tp = tty->termios; tty->driver->termios[idx] = NULL; kfree(tp); |
feebed651 tty: shutdown method |
1392 1393 1394 1395 1396 1397 |
} } EXPORT_SYMBOL(tty_free_termios); void tty_shutdown(struct tty_struct *tty) { |
8b0a88d59 tty: More driver ... |
1398 |
tty_driver_remove_tty(tty->driver, tty); |
feebed651 tty: shutdown method |
1399 1400 1401 |
tty_free_termios(tty); } EXPORT_SYMBOL(tty_shutdown); |
af9b897ee [PATCH] tty layer... |
1402 |
/** |
d5698c28b [PATCH] tty: clea... |
1403 |
* release_one_tty - release tty structure memory |
9c9f4ded9 tty: Add a kref c... |
1404 |
* @kref: kref of tty we are obliterating |
af9b897ee [PATCH] tty layer... |
1405 1406 1407 1408 1409 1410 1411 1412 1413 |
* * Releases memory associated with a tty structure, and clears out the * driver table slots. This function is called when a device is no longer * in use. It also gets called when setup of a device fails. * * Locking: * tty_mutex - sometimes only * takes the file list lock internally when working on the list * of ttys that the driver keeps. |
b50989dc4 tty: make the kre... |
1414 1415 |
* * This method gets called from a work queue so that the driver private |
f278a2f7b tty: Fix regressi... |
1416 |
* cleanup ops can sleep (needed for USB at least) |
1da177e4c Linux-2.6.12-rc2 |
1417 |
*/ |
b50989dc4 tty: make the kre... |
1418 |
static void release_one_tty(struct work_struct *work) |
1da177e4c Linux-2.6.12-rc2 |
1419 |
{ |
b50989dc4 tty: make the kre... |
1420 1421 |
struct tty_struct *tty = container_of(work, struct tty_struct, hangup_work); |
6f967f789 tty: use krefs to... |
1422 |
struct tty_driver *driver = tty->driver; |
d5698c28b [PATCH] tty: clea... |
1423 |
|
f278a2f7b tty: Fix regressi... |
1424 1425 |
if (tty->ops->cleanup) tty->ops->cleanup(tty); |
1da177e4c Linux-2.6.12-rc2 |
1426 |
tty->magic = 0; |
7d7b93c14 tty: kref the tty... |
1427 |
tty_driver_kref_put(driver); |
6f967f789 tty: use krefs to... |
1428 |
module_put(driver->owner); |
d5698c28b [PATCH] tty: clea... |
1429 |
|
ee2ffa0df fs: cleanup files... |
1430 |
spin_lock(&tty_files_lock); |
1da177e4c Linux-2.6.12-rc2 |
1431 |
list_del_init(&tty->tty_files); |
ee2ffa0df fs: cleanup files... |
1432 |
spin_unlock(&tty_files_lock); |
d5698c28b [PATCH] tty: clea... |
1433 |
|
6da8d866d tty: release_one_... |
1434 1435 |
put_pid(tty->pgrp); put_pid(tty->session); |
1da177e4c Linux-2.6.12-rc2 |
1436 1437 |
free_tty_struct(tty); } |
b50989dc4 tty: make the kre... |
1438 1439 1440 |
static void queue_release_one_tty(struct kref *kref) { struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
f278a2f7b tty: Fix regressi... |
1441 1442 1443 1444 1445 |
if (tty->ops->shutdown) tty->ops->shutdown(tty); else tty_shutdown(tty); |
b50989dc4 tty: make the kre... |
1446 1447 1448 1449 1450 |
/* The hangup queue is now free so we can reuse it rather than waste a chunk of memory for each port */ INIT_WORK(&tty->hangup_work, release_one_tty); schedule_work(&tty->hangup_work); } |
d5698c28b [PATCH] tty: clea... |
1451 |
/** |
9c9f4ded9 tty: Add a kref c... |
1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 |
* tty_kref_put - release a tty kref * @tty: tty device * * Release a reference to a tty device and if need be let the kref * layer destruct the object for us */ void tty_kref_put(struct tty_struct *tty) { if (tty) |
b50989dc4 tty: make the kre... |
1462 |
kref_put(&tty->kref, queue_release_one_tty); |
9c9f4ded9 tty: Add a kref c... |
1463 1464 1465 1466 |
} EXPORT_SYMBOL(tty_kref_put); /** |
d5698c28b [PATCH] tty: clea... |
1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 |
* release_tty - release tty structure memory * * Release both @tty and a possible linked partner (think pty pair), * and decrement the refcount of the backing module. * * Locking: * tty_mutex - sometimes only * takes the file list lock internally when working on the list * of ttys that the driver keeps. * FIXME: should we require tty_mutex is held here ?? |
9c9f4ded9 tty: Add a kref c... |
1477 |
* |
d5698c28b [PATCH] tty: clea... |
1478 1479 1480 |
*/ static void release_tty(struct tty_struct *tty, int idx) { |
9c9f4ded9 tty: Add a kref c... |
1481 1482 |
/* This should always be true but check for the moment */ WARN_ON(tty->index != idx); |
d5698c28b [PATCH] tty: clea... |
1483 |
if (tty->link) |
9c9f4ded9 tty: Add a kref c... |
1484 1485 |
tty_kref_put(tty->link); tty_kref_put(tty); |
d5698c28b [PATCH] tty: clea... |
1486 |
} |
eeb89d918 tty: push the BKL... |
1487 |
/** |
955787ca9 TTY: move debug c... |
1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 |
* tty_release_checks - check a tty before real release * @tty: tty to check * @o_tty: link of @tty (if any) * @idx: index of the tty * * Performs some paranoid checking before true release of the @tty. * This is a no-op unless TTY_PARANOIA_CHECK is defined. */ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, int idx) { #ifdef TTY_PARANOIA_CHECK if (idx < 0 || idx >= tty->driver->num) { |
9de44bd60 TTY: open/release... |
1501 1502 1503 |
printk(KERN_DEBUG "%s: bad idx when trying to free (%s) ", __func__, tty->name); |
955787ca9 TTY: move debug c... |
1504 1505 1506 1507 1508 1509 1510 1511 |
return -1; } /* not much to check for devpts */ if (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) return 0; if (tty != tty->driver->ttys[idx]) { |
9de44bd60 TTY: open/release... |
1512 1513 1514 |
printk(KERN_DEBUG "%s: driver.table[%d] not tty for (%s) ", __func__, idx, tty->name); |
955787ca9 TTY: move debug c... |
1515 1516 1517 |
return -1; } if (tty->termios != tty->driver->termios[idx]) { |
9de44bd60 TTY: open/release... |
1518 1519 1520 |
printk(KERN_DEBUG "%s: driver.termios[%d] not termios for (%s) ", __func__, idx, tty->name); |
955787ca9 TTY: move debug c... |
1521 1522 1523 1524 |
return -1; } if (tty->driver->other) { if (o_tty != tty->driver->other->ttys[idx]) { |
9de44bd60 TTY: open/release... |
1525 1526 1527 |
printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s) ", __func__, idx, tty->name); |
955787ca9 TTY: move debug c... |
1528 1529 1530 |
return -1; } if (o_tty->termios != tty->driver->other->termios[idx]) { |
9de44bd60 TTY: open/release... |
1531 1532 1533 |
printk(KERN_DEBUG "%s: other->termios[%d] not o_termios for (%s) ", __func__, idx, tty->name); |
955787ca9 TTY: move debug c... |
1534 1535 1536 |
return -1; } if (o_tty->link != tty) { |
9de44bd60 TTY: open/release... |
1537 1538 |
printk(KERN_DEBUG "%s: bad pty pointers ", __func__); |
955787ca9 TTY: move debug c... |
1539 1540 1541 1542 1543 1544 1545 1546 |
return -1; } } #endif return 0; } /** |
eeb89d918 tty: push the BKL... |
1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 |
* tty_release - vfs callback for close * @inode: inode of tty * @filp: file pointer for handle to tty * * Called the last time each file handle is closed that references * this tty. There may however be several such references. * * Locking: * Takes bkl. See tty_release_dev * |
1da177e4c Linux-2.6.12-rc2 |
1557 1558 1559 1560 1561 1562 1563 |
* Even releasing the tty structures is a tricky business.. We have * to be very careful that the structures are all released at the * same time, as interrupts might otherwise get the wrong pointers. * * WSH 09/09/97: rewritten to avoid some nasty race conditions that could * lead to double frees or releasing memory still in use. */ |
eeb89d918 tty: push the BKL... |
1564 1565 |
int tty_release(struct inode *inode, struct file *filp) |
1da177e4c Linux-2.6.12-rc2 |
1566 |
{ |
d996b62a8 tty: fix fu_list ... |
1567 1568 |
struct tty_struct *tty = file_tty(filp); struct tty_struct *o_tty; |
1da177e4c Linux-2.6.12-rc2 |
1569 |
int pty_master, tty_closing, o_tty_closing, do_sleep; |
14a6283eb [PATCH] tty relea... |
1570 |
int devpts; |
1da177e4c Linux-2.6.12-rc2 |
1571 1572 |
int idx; char buf[64]; |
37bdfb074 tty_io: drag scre... |
1573 |
|
9de44bd60 TTY: open/release... |
1574 |
if (tty_paranoia_check(tty, inode, __func__)) |
eeb89d918 tty: push the BKL... |
1575 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1576 |
|
ec79d6056 tty: replace BKL ... |
1577 |
tty_lock(); |
9de44bd60 TTY: open/release... |
1578 |
check_tty_count(tty, __func__); |
1da177e4c Linux-2.6.12-rc2 |
1579 |
|
ec79d6056 tty: replace BKL ... |
1580 |
__tty_fasync(-1, filp, 0); |
1da177e4c Linux-2.6.12-rc2 |
1581 1582 1583 1584 1585 |
idx = tty->index; pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER); devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1da177e4c Linux-2.6.12-rc2 |
1586 |
o_tty = tty->link; |
955787ca9 TTY: move debug c... |
1587 |
if (tty_release_checks(tty, o_tty, idx)) { |
ec79d6056 tty: replace BKL ... |
1588 |
tty_unlock(); |
eeb89d918 tty: push the BKL... |
1589 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1590 |
} |
1da177e4c Linux-2.6.12-rc2 |
1591 1592 |
#ifdef TTY_DEBUG_HANGUP |
9de44bd60 TTY: open/release... |
1593 1594 1595 |
printk(KERN_DEBUG "%s: %s (tty count=%d)... ", __func__, tty_name(tty, buf), tty->count); |
1da177e4c Linux-2.6.12-rc2 |
1596 |
#endif |
f34d7a5b7 tty: The big oper... |
1597 1598 |
if (tty->ops->close) tty->ops->close(tty, filp); |
1da177e4c Linux-2.6.12-rc2 |
1599 |
|
ec79d6056 tty: replace BKL ... |
1600 |
tty_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 |
/* * Sanity check: if tty->count is going to zero, there shouldn't be * any waiters on tty->read_wait or tty->write_wait. We test the * wait queues and kick everyone out _before_ actually starting to * close. This ensures that we won't block while releasing the tty * structure. * * The test for the o_tty closing is necessary, since the master and * slave sides may close in any order. If the slave side closes out * first, its count will be one, since the master side holds an open. * Thus this test wouldn't be triggered at the time the slave closes, * so we do it now. * * Note that it's possible for the tty to be opened again while we're * flushing out waiters. By recalculating the closing flags before * each iteration we avoid any problems. */ while (1) { /* Guard against races with tty->count changes elsewhere and opens on /dev/tty */ |
37bdfb074 tty_io: drag scre... |
1621 |
|
70522e121 [PATCH] sem2mutex... |
1622 |
mutex_lock(&tty_mutex); |
ec79d6056 tty: replace BKL ... |
1623 |
tty_lock(); |
1da177e4c Linux-2.6.12-rc2 |
1624 1625 1626 |
tty_closing = tty->count <= 1; o_tty_closing = o_tty && (o_tty->count <= (pty_master ? 1 : 0)); |
1da177e4c Linux-2.6.12-rc2 |
1627 1628 1629 1630 |
do_sleep = 0; if (tty_closing) { if (waitqueue_active(&tty->read_wait)) { |
4b19449db epoll keyed wakeu... |
1631 |
wake_up_poll(&tty->read_wait, POLLIN); |
1da177e4c Linux-2.6.12-rc2 |
1632 1633 1634 |
do_sleep++; } if (waitqueue_active(&tty->write_wait)) { |
4b19449db epoll keyed wakeu... |
1635 |
wake_up_poll(&tty->write_wait, POLLOUT); |
1da177e4c Linux-2.6.12-rc2 |
1636 1637 1638 1639 1640 |
do_sleep++; } } if (o_tty_closing) { if (waitqueue_active(&o_tty->read_wait)) { |
4b19449db epoll keyed wakeu... |
1641 |
wake_up_poll(&o_tty->read_wait, POLLIN); |
1da177e4c Linux-2.6.12-rc2 |
1642 1643 1644 |
do_sleep++; } if (waitqueue_active(&o_tty->write_wait)) { |
4b19449db epoll keyed wakeu... |
1645 |
wake_up_poll(&o_tty->write_wait, POLLOUT); |
1da177e4c Linux-2.6.12-rc2 |
1646 1647 1648 1649 1650 |
do_sleep++; } } if (!do_sleep) break; |
9de44bd60 TTY: open/release... |
1651 1652 1653 |
printk(KERN_WARNING "%s: %s: read/write wait queue active! ", __func__, tty_name(tty, buf)); |
ec79d6056 tty: replace BKL ... |
1654 |
tty_unlock(); |
70522e121 [PATCH] sem2mutex... |
1655 |
mutex_unlock(&tty_mutex); |
1da177e4c Linux-2.6.12-rc2 |
1656 |
schedule(); |
37bdfb074 tty_io: drag scre... |
1657 |
} |
1da177e4c Linux-2.6.12-rc2 |
1658 1659 |
/* |
37bdfb074 tty_io: drag scre... |
1660 1661 |
* The closing flags are now consistent with the open counts on * both sides, and we've completed the last operation that could |
1da177e4c Linux-2.6.12-rc2 |
1662 1663 |
* block, so it's safe to proceed with closing. */ |
1da177e4c Linux-2.6.12-rc2 |
1664 1665 |
if (pty_master) { if (--o_tty->count < 0) { |
9de44bd60 TTY: open/release... |
1666 1667 1668 |
printk(KERN_WARNING "%s: bad pty slave count (%d) for %s ", __func__, o_tty->count, tty_name(o_tty, buf)); |
1da177e4c Linux-2.6.12-rc2 |
1669 1670 1671 1672 |
o_tty->count = 0; } } if (--tty->count < 0) { |
9de44bd60 TTY: open/release... |
1673 1674 1675 |
printk(KERN_WARNING "%s: bad tty->count (%d) for %s ", __func__, tty->count, tty_name(tty, buf)); |
1da177e4c Linux-2.6.12-rc2 |
1676 1677 |
tty->count = 0; } |
37bdfb074 tty_io: drag scre... |
1678 |
|
1da177e4c Linux-2.6.12-rc2 |
1679 1680 1681 1682 1683 1684 1685 1686 1687 |
/* * We've decremented tty->count, so we need to remove this file * descriptor off the tty->tty_files list; this serves two * purposes: * - check_tty_count sees the correct number of file descriptors * associated with this tty. * - do_tty_hangup no longer sees this file descriptor as * something that needs to be handled for hangups. */ |
d996b62a8 tty: fix fu_list ... |
1688 |
tty_del_file(filp); |
1da177e4c Linux-2.6.12-rc2 |
1689 1690 1691 1692 1693 1694 1695 1696 |
/* * Perform some housekeeping before deciding whether to return. * * Set the TTY_CLOSING flag if this was the last open. In the * case of a pty we may have to wait around for the other side * to close, and TTY_CLOSING makes sure we can't be reopened. */ |
37bdfb074 tty_io: drag scre... |
1697 |
if (tty_closing) |
1da177e4c Linux-2.6.12-rc2 |
1698 |
set_bit(TTY_CLOSING, &tty->flags); |
37bdfb074 tty_io: drag scre... |
1699 |
if (o_tty_closing) |
1da177e4c Linux-2.6.12-rc2 |
1700 1701 1702 1703 1704 1705 1706 1707 |
set_bit(TTY_CLOSING, &o_tty->flags); /* * If _either_ side is closing, make sure there aren't any * processes that still think tty or o_tty is their controlling * tty. */ if (tty_closing || o_tty_closing) { |
1da177e4c Linux-2.6.12-rc2 |
1708 |
read_lock(&tasklist_lock); |
24ec839c4 [PATCH] tty: ->si... |
1709 |
session_clear_tty(tty->session); |
1da177e4c Linux-2.6.12-rc2 |
1710 |
if (o_tty) |
24ec839c4 [PATCH] tty: ->si... |
1711 |
session_clear_tty(o_tty->session); |
1da177e4c Linux-2.6.12-rc2 |
1712 1713 |
read_unlock(&tasklist_lock); } |
70522e121 [PATCH] sem2mutex... |
1714 |
mutex_unlock(&tty_mutex); |
da965822a [PATCH] tty refer... |
1715 |
|
1da177e4c Linux-2.6.12-rc2 |
1716 |
/* check whether both sides are closing ... */ |
eeb89d918 tty: push the BKL... |
1717 |
if (!tty_closing || (o_tty && !o_tty_closing)) { |
ec79d6056 tty: replace BKL ... |
1718 |
tty_unlock(); |
eeb89d918 tty: push the BKL... |
1719 1720 |
return 0; } |
37bdfb074 tty_io: drag scre... |
1721 |
|
1da177e4c Linux-2.6.12-rc2 |
1722 |
#ifdef TTY_DEBUG_HANGUP |
9de44bd60 TTY: open/release... |
1723 1724 |
printk(KERN_DEBUG "%s: freeing tty structure... ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
1725 1726 |
#endif /* |
01e1abb2c tty: Split ldisc ... |
1727 |
* Ask the line discipline code to release its structures |
1da177e4c Linux-2.6.12-rc2 |
1728 |
*/ |
01e1abb2c tty: Split ldisc ... |
1729 |
tty_ldisc_release(tty, o_tty); |
1da177e4c Linux-2.6.12-rc2 |
1730 |
/* |
d5698c28b [PATCH] tty: clea... |
1731 |
* The release_tty function takes care of the details of clearing |
1da177e4c Linux-2.6.12-rc2 |
1732 1733 |
* the slots and preserving the termios structure. */ |
d5698c28b [PATCH] tty: clea... |
1734 |
release_tty(tty, idx); |
1da177e4c Linux-2.6.12-rc2 |
1735 |
|
1da177e4c Linux-2.6.12-rc2 |
1736 |
/* Make this pty number available for reallocation */ |
718a91633 devpts: factor ou... |
1737 |
if (devpts) |
15f1a6338 Add an instance p... |
1738 |
devpts_kill_index(inode, idx); |
ec79d6056 tty: replace BKL ... |
1739 |
tty_unlock(); |
eeb89d918 tty: push the BKL... |
1740 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1741 |
} |
af9b897ee [PATCH] tty layer... |
1742 |
/** |
b82154ac3 TTY: extract /dev... |
1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 |
* tty_open_current_tty - get tty of current task for open * @device: device number * @filp: file pointer to tty * @return: tty of the current task iff @device is /dev/tty * * We cannot return driver and index like for the other nodes because * devpts will not work then. It expects inodes to be from devpts FS. */ static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) { struct tty_struct *tty; if (device != MKDEV(TTYAUX_MAJOR, 0)) return NULL; tty = get_current_tty(); if (!tty) return ERR_PTR(-ENXIO); filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ /* noctty = 1; */ tty_kref_put(tty); /* FIXME: we put a reference and return a TTY! */ return tty; } /** |
5b5e70408 TTY: extract driv... |
1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 |
* tty_lookup_driver - lookup a tty driver for a given device file * @device: device number * @filp: file pointer to tty * @noctty: set if the device should not become a controlling tty * @index: index for the device in the @return driver * @return: driver for this inode (with increased refcount) * * If @return is not erroneous, the caller is responsible to decrement the * refcount by tty_driver_kref_put. * * Locking: tty_mutex protects get_tty_driver */ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, int *noctty, int *index) { struct tty_driver *driver; |
2cd0050cf TTY: move tty_loo... |
1786 |
switch (device) { |
5b5e70408 TTY: extract driv... |
1787 |
#ifdef CONFIG_VT |
2cd0050cf TTY: move tty_loo... |
1788 |
case MKDEV(TTY_MAJOR, 0): { |
5b5e70408 TTY: extract driv... |
1789 1790 1791 1792 |
extern struct tty_driver *console_driver; driver = tty_driver_kref_get(console_driver); *index = fg_console; *noctty = 1; |
2cd0050cf TTY: move tty_loo... |
1793 |
break; |
5b5e70408 TTY: extract driv... |
1794 1795 |
} #endif |
2cd0050cf TTY: move tty_loo... |
1796 |
case MKDEV(TTYAUX_MAJOR, 1): { |
5b5e70408 TTY: extract driv... |
1797 1798 1799 1800 1801 1802 1803 |
struct tty_driver *console_driver = console_device(index); if (console_driver) { driver = tty_driver_kref_get(console_driver); if (driver) { /* Don't let /dev/console block */ filp->f_flags |= O_NONBLOCK; *noctty = 1; |
2cd0050cf TTY: move tty_loo... |
1804 |
break; |
5b5e70408 TTY: extract driv... |
1805 1806 1807 1808 |
} } return ERR_PTR(-ENODEV); } |
2cd0050cf TTY: move tty_loo... |
1809 1810 1811 1812 1813 1814 |
default: driver = get_tty_driver(device, index); if (!driver) return ERR_PTR(-ENODEV); break; } |
5b5e70408 TTY: extract driv... |
1815 1816 1817 1818 |
return driver; } /** |
eeb89d918 tty: push the BKL... |
1819 |
* tty_open - open a tty device |
af9b897ee [PATCH] tty layer... |
1820 1821 |
* @inode: inode of device file * @filp: file pointer to tty |
1da177e4c Linux-2.6.12-rc2 |
1822 |
* |
af9b897ee [PATCH] tty layer... |
1823 1824 1825 |
* tty_open and tty_release keep up the tty count that contains the * number of opens done on a tty. We cannot use the inode-count, as * different inodes might point to the same tty. |
1da177e4c Linux-2.6.12-rc2 |
1826 |
* |
af9b897ee [PATCH] tty layer... |
1827 1828 1829 1830 1831 1832 1833 |
* Open-counting is needed for pty masters, as well as for keeping * track of serial lines: DTR is dropped when the last close happens. * (This is not done solely through tty->count, now. - Ted 1/27/92) * * The termios state of a pty is reset on first open so that * settings don't persist across reuse. * |
5b5e70408 TTY: extract driv... |
1834 |
* Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
24ec839c4 [PATCH] tty: ->si... |
1835 1836 |
* tty->count should protect the rest. * ->siglock protects ->signal/->sighand |
1da177e4c Linux-2.6.12-rc2 |
1837 |
*/ |
af9b897ee [PATCH] tty layer... |
1838 |
|
eeb89d918 tty: push the BKL... |
1839 |
static int tty_open(struct inode *inode, struct file *filp) |
1da177e4c Linux-2.6.12-rc2 |
1840 |
{ |
b82154ac3 TTY: extract /dev... |
1841 |
struct tty_struct *tty; |
1da177e4c Linux-2.6.12-rc2 |
1842 |
int noctty, retval; |
b82154ac3 TTY: extract /dev... |
1843 |
struct tty_driver *driver = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1844 1845 |
int index; dev_t device = inode->i_rdev; |
846c151a4 __tty_open(): use... |
1846 |
unsigned saved_flags = filp->f_flags; |
1da177e4c Linux-2.6.12-rc2 |
1847 1848 |
nonseekable_open(inode, filp); |
37bdfb074 tty_io: drag scre... |
1849 |
|
1da177e4c Linux-2.6.12-rc2 |
1850 |
retry_open: |
fa90e1c93 TTY: make tty_add... |
1851 1852 1853 |
retval = tty_alloc_file(filp); if (retval) return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
1854 1855 1856 |
noctty = filp->f_flags & O_NOCTTY; index = -1; retval = 0; |
37bdfb074 tty_io: drag scre... |
1857 |
|
70522e121 [PATCH] sem2mutex... |
1858 |
mutex_lock(&tty_mutex); |
ec79d6056 tty: replace BKL ... |
1859 |
tty_lock(); |
1da177e4c Linux-2.6.12-rc2 |
1860 |
|
b82154ac3 TTY: extract /dev... |
1861 1862 |
tty = tty_open_current_tty(device, filp); if (IS_ERR(tty)) { |
ba5db4489 TTY: coalesce fai... |
1863 1864 |
retval = PTR_ERR(tty); goto err_unlock; |
5b5e70408 TTY: extract driv... |
1865 1866 1867 |
} else if (!tty) { driver = tty_lookup_driver(device, filp, &noctty, &index); if (IS_ERR(driver)) { |
ba5db4489 TTY: coalesce fai... |
1868 1869 |
retval = PTR_ERR(driver); goto err_unlock; |
1da177e4c Linux-2.6.12-rc2 |
1870 |
} |
1da177e4c Linux-2.6.12-rc2 |
1871 |
|
4a2b5fddd Move tty lookup/r... |
1872 |
/* check whether we're reopening an existing tty */ |
15f1a6338 Add an instance p... |
1873 |
tty = tty_driver_lookup_tty(driver, inode, index); |
808ffa3d3 tty_open can retu... |
1874 |
if (IS_ERR(tty)) { |
ba5db4489 TTY: coalesce fai... |
1875 1876 |
retval = PTR_ERR(tty); goto err_unlock; |
808ffa3d3 tty_open can retu... |
1877 |
} |
4a2b5fddd Move tty lookup/r... |
1878 1879 1880 1881 1882 1883 1884 1885 |
} if (tty) { retval = tty_reopen(tty); if (retval) tty = ERR_PTR(retval); } else tty = tty_init_dev(driver, index, 0); |
70522e121 [PATCH] sem2mutex... |
1886 |
mutex_unlock(&tty_mutex); |
b82154ac3 TTY: extract /dev... |
1887 1888 |
if (driver) tty_driver_kref_put(driver); |
eeb89d918 tty: push the BKL... |
1889 |
if (IS_ERR(tty)) { |
ec79d6056 tty: replace BKL ... |
1890 |
tty_unlock(); |
ba5db4489 TTY: coalesce fai... |
1891 1892 |
retval = PTR_ERR(tty); goto err_file; |
eeb89d918 tty: push the BKL... |
1893 |
} |
1da177e4c Linux-2.6.12-rc2 |
1894 |
|
fa90e1c93 TTY: make tty_add... |
1895 |
tty_add_file(tty, filp); |
d996b62a8 tty: fix fu_list ... |
1896 |
|
9de44bd60 TTY: open/release... |
1897 |
check_tty_count(tty, __func__); |
1da177e4c Linux-2.6.12-rc2 |
1898 1899 1900 1901 |
if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER) noctty = 1; #ifdef TTY_DEBUG_HANGUP |
9de44bd60 TTY: open/release... |
1902 1903 |
printk(KERN_DEBUG "%s: opening %s... ", __func__, tty->name); |
1da177e4c Linux-2.6.12-rc2 |
1904 |
#endif |
909bc7741 vt: remove uneede... |
1905 1906 1907 1908 |
if (tty->ops->open) retval = tty->ops->open(tty, filp); else retval = -ENODEV; |
1da177e4c Linux-2.6.12-rc2 |
1909 |
filp->f_flags = saved_flags; |
37bdfb074 tty_io: drag scre... |
1910 1911 |
if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) |
1da177e4c Linux-2.6.12-rc2 |
1912 1913 1914 1915 |
retval = -EBUSY; if (retval) { #ifdef TTY_DEBUG_HANGUP |
9de44bd60 TTY: open/release... |
1916 1917 1918 |
printk(KERN_DEBUG "%s: error %d in opening %s... ", __func__, retval, tty->name); |
1da177e4c Linux-2.6.12-rc2 |
1919 |
#endif |
64ba3dc31 tty: never hold B... |
1920 |
tty_unlock(); /* need to call tty_release without BTM */ |
eeb89d918 tty: push the BKL... |
1921 |
tty_release(inode, filp); |
64ba3dc31 tty: never hold B... |
1922 |
if (retval != -ERESTARTSYS) |
1da177e4c Linux-2.6.12-rc2 |
1923 |
return retval; |
64ba3dc31 tty: never hold B... |
1924 1925 |
if (signal_pending(current)) |
1da177e4c Linux-2.6.12-rc2 |
1926 |
return retval; |
64ba3dc31 tty: never hold B... |
1927 |
|
1da177e4c Linux-2.6.12-rc2 |
1928 1929 1930 1931 |
schedule(); /* * Need to reset f_op in case a hangup happened. */ |
64ba3dc31 tty: never hold B... |
1932 |
tty_lock(); |
1da177e4c Linux-2.6.12-rc2 |
1933 1934 |
if (filp->f_op == &hung_up_tty_fops) filp->f_op = &tty_fops; |
ec79d6056 tty: replace BKL ... |
1935 |
tty_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
1936 1937 |
goto retry_open; } |
ec79d6056 tty: replace BKL ... |
1938 |
tty_unlock(); |
eeb89d918 tty: push the BKL... |
1939 |
|
24ec839c4 [PATCH] tty: ->si... |
1940 1941 |
mutex_lock(&tty_mutex); |
ec79d6056 tty: replace BKL ... |
1942 |
tty_lock(); |
24ec839c4 [PATCH] tty: ->si... |
1943 |
spin_lock_irq(¤t->sighand->siglock); |
1da177e4c Linux-2.6.12-rc2 |
1944 1945 1946 |
if (!noctty && current->signal->leader && !current->signal->tty && |
ab521dc0f [PATCH] tty: upda... |
1947 |
tty->session == NULL) |
2a65f1d9f tty: simplify cal... |
1948 |
__proc_set_tty(current, tty); |
24ec839c4 [PATCH] tty: ->si... |
1949 |
spin_unlock_irq(¤t->sighand->siglock); |
ec79d6056 tty: replace BKL ... |
1950 |
tty_unlock(); |
24ec839c4 [PATCH] tty: ->si... |
1951 |
mutex_unlock(&tty_mutex); |
1da177e4c Linux-2.6.12-rc2 |
1952 |
return 0; |
ba5db4489 TTY: coalesce fai... |
1953 1954 1955 1956 1957 1958 1959 1960 1961 |
err_unlock: tty_unlock(); mutex_unlock(&tty_mutex); /* after locks to avoid deadlock */ if (!IS_ERR_OR_NULL(driver)) tty_driver_kref_put(driver); err_file: tty_free_file(filp); return retval; |
1da177e4c Linux-2.6.12-rc2 |
1962 |
} |
39d95b9d8 tty: cdev lock_ke... |
1963 |
|
af9b897ee [PATCH] tty layer... |
1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 |
/** * tty_poll - check tty status * @filp: file being polled * @wait: poll wait structures to update * * Call the line discipline polling method to obtain the poll * status of the device. * * Locking: locks called line discipline but ldisc poll method * may be re-entered freely by other callers. */ |
37bdfb074 tty_io: drag scre... |
1975 |
static unsigned int tty_poll(struct file *filp, poll_table *wait) |
1da177e4c Linux-2.6.12-rc2 |
1976 |
{ |
d996b62a8 tty: fix fu_list ... |
1977 |
struct tty_struct *tty = file_tty(filp); |
1da177e4c Linux-2.6.12-rc2 |
1978 1979 |
struct tty_ldisc *ld; int ret = 0; |
a7113a966 [PATCH] struct pa... |
1980 |
if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) |
1da177e4c Linux-2.6.12-rc2 |
1981 |
return 0; |
37bdfb074 tty_io: drag scre... |
1982 |
|
1da177e4c Linux-2.6.12-rc2 |
1983 |
ld = tty_ldisc_ref_wait(tty); |
a352def21 tty: Ldisc revamp |
1984 1985 |
if (ld->ops->poll) ret = (ld->ops->poll)(tty, filp, wait); |
1da177e4c Linux-2.6.12-rc2 |
1986 1987 1988 |
tty_ldisc_deref(ld); return ret; } |
ec79d6056 tty: replace BKL ... |
1989 |
static int __tty_fasync(int fd, struct file *filp, int on) |
1da177e4c Linux-2.6.12-rc2 |
1990 |
{ |
d996b62a8 tty: fix fu_list ... |
1991 |
struct tty_struct *tty = file_tty(filp); |
47f86834b redo locking of t... |
1992 |
unsigned long flags; |
5d1e3230f tty_io: fasync BK... |
1993 |
int retval = 0; |
1da177e4c Linux-2.6.12-rc2 |
1994 |
|
a7113a966 [PATCH] struct pa... |
1995 |
if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
5d1e3230f tty_io: fasync BK... |
1996 |
goto out; |
37bdfb074 tty_io: drag scre... |
1997 |
|
1da177e4c Linux-2.6.12-rc2 |
1998 1999 |
retval = fasync_helper(fd, filp, on, &tty->fasync); if (retval <= 0) |
5d1e3230f tty_io: fasync BK... |
2000 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
2001 2002 |
if (on) { |
ab521dc0f [PATCH] tty: upda... |
2003 2004 |
enum pid_type type; struct pid *pid; |
1da177e4c Linux-2.6.12-rc2 |
2005 2006 |
if (!waitqueue_active(&tty->read_wait)) tty->minimum_to_wake = 1; |
47f86834b redo locking of t... |
2007 |
spin_lock_irqsave(&tty->ctrl_lock, flags); |
ab521dc0f [PATCH] tty: upda... |
2008 2009 2010 2011 2012 2013 2014 |
if (tty->pgrp) { pid = tty->pgrp; type = PIDTYPE_PGID; } else { pid = task_pid(current); type = PIDTYPE_PID; } |
80e1e8239 Fix race in tty_f... |
2015 |
get_pid(pid); |
703625118 tty: fix race in ... |
2016 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
80e1e8239 Fix race in tty_f... |
2017 2018 |
retval = __f_setown(filp, pid, type, 0); put_pid(pid); |
1da177e4c Linux-2.6.12-rc2 |
2019 |
if (retval) |
5d1e3230f tty_io: fasync BK... |
2020 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
2021 2022 2023 2024 |
} else { if (!tty->fasync && !waitqueue_active(&tty->read_wait)) tty->minimum_to_wake = N_TTY_BUF_SIZE; } |
5d1e3230f tty_io: fasync BK... |
2025 2026 |
retval = 0; out: |
ec79d6056 tty: replace BKL ... |
2027 2028 2029 2030 2031 2032 2033 2034 2035 |
return retval; } static int tty_fasync(int fd, struct file *filp, int on) { int retval; tty_lock(); retval = __tty_fasync(fd, filp, on); tty_unlock(); |
5d1e3230f tty_io: fasync BK... |
2036 |
return retval; |
1da177e4c Linux-2.6.12-rc2 |
2037 |
} |
af9b897ee [PATCH] tty layer... |
2038 2039 2040 2041 2042 |
/** * tiocsti - fake input character * @tty: tty to fake input into * @p: pointer to character * |
3a4fa0a25 Fix misspellings ... |
2043 |
* Fake input to a tty device. Does the necessary locking and |
af9b897ee [PATCH] tty layer... |
2044 2045 2046 2047 2048 2049 2050 |
* input management. * * FIXME: does not honour flow control ?? * * Locking: * Called functions take tty_ldisc_lock * current->signal->tty check is safe without locks |
28298232a [PATCH] tty: Fix ... |
2051 2052 |
* * FIXME: may race normal receive processing |
af9b897ee [PATCH] tty layer... |
2053 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
2054 2055 2056 2057 |
static int tiocsti(struct tty_struct *tty, char __user *p) { char ch, mbz = 0; struct tty_ldisc *ld; |
37bdfb074 tty_io: drag scre... |
2058 |
|
1da177e4c Linux-2.6.12-rc2 |
2059 2060 2061 2062 |
if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(ch, p)) return -EFAULT; |
1e641743f Audit: Log TIOCSTI |
2063 |
tty_audit_tiocsti(tty, ch); |
1da177e4c Linux-2.6.12-rc2 |
2064 |
ld = tty_ldisc_ref_wait(tty); |
a352def21 tty: Ldisc revamp |
2065 |
ld->ops->receive_buf(tty, &ch, &mbz, 1); |
1da177e4c Linux-2.6.12-rc2 |
2066 2067 2068 |
tty_ldisc_deref(ld); return 0; } |
af9b897ee [PATCH] tty layer... |
2069 2070 2071 2072 2073 |
/** * tiocgwinsz - implement window query ioctl * @tty; tty * @arg: user buffer for result * |
808a0d389 [PATCH] tty: lock... |
2074 |
* Copies the kernel idea of the window size into the user buffer. |
af9b897ee [PATCH] tty layer... |
2075 |
* |
24ec839c4 [PATCH] tty: ->si... |
2076 |
* Locking: tty->termios_mutex is taken to ensure the winsize data |
808a0d389 [PATCH] tty: lock... |
2077 |
* is consistent. |
af9b897ee [PATCH] tty layer... |
2078 |
*/ |
37bdfb074 tty_io: drag scre... |
2079 |
static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) |
1da177e4c Linux-2.6.12-rc2 |
2080 |
{ |
808a0d389 [PATCH] tty: lock... |
2081 |
int err; |
5785c95ba [PATCH] tty: make... |
2082 |
mutex_lock(&tty->termios_mutex); |
808a0d389 [PATCH] tty: lock... |
2083 |
err = copy_to_user(arg, &tty->winsize, sizeof(*arg)); |
5785c95ba [PATCH] tty: make... |
2084 |
mutex_unlock(&tty->termios_mutex); |
808a0d389 [PATCH] tty: lock... |
2085 2086 |
return err ? -EFAULT: 0; |
1da177e4c Linux-2.6.12-rc2 |
2087 |
} |
af9b897ee [PATCH] tty layer... |
2088 |
/** |
8c9a9dd0f tty: remove resiz... |
2089 2090 |
* tty_do_resize - resize event * @tty: tty being resized |
8c9a9dd0f tty: remove resiz... |
2091 2092 2093 |
* @rows: rows (character) * @cols: cols (character) * |
3ad2f3fbb tree-wide: Assort... |
2094 |
* Update the termios variables and send the necessary signals to |
8c9a9dd0f tty: remove resiz... |
2095 |
* peform a terminal resize correctly |
af9b897ee [PATCH] tty layer... |
2096 |
*/ |
fc6f62382 pty: simplify resize |
2097 |
int tty_do_resize(struct tty_struct *tty, struct winsize *ws) |
1da177e4c Linux-2.6.12-rc2 |
2098 |
{ |
fc6f62382 pty: simplify resize |
2099 |
struct pid *pgrp; |
47f86834b redo locking of t... |
2100 |
unsigned long flags; |
1da177e4c Linux-2.6.12-rc2 |
2101 |
|
fc6f62382 pty: simplify resize |
2102 2103 2104 |
/* Lock the tty */ mutex_lock(&tty->termios_mutex); if (!memcmp(ws, &tty->winsize, sizeof(*ws))) |
ca9bda00b [PATCH] tty locki... |
2105 |
goto done; |
47f86834b redo locking of t... |
2106 2107 2108 2109 |
/* Get the PID values and reference them so we can avoid holding the tty ctrl lock while sending signals */ spin_lock_irqsave(&tty->ctrl_lock, flags); pgrp = get_pid(tty->pgrp); |
47f86834b redo locking of t... |
2110 2111 2112 2113 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); if (pgrp) kill_pgrp(pgrp, SIGWINCH, 1); |
47f86834b redo locking of t... |
2114 |
put_pid(pgrp); |
47f86834b redo locking of t... |
2115 |
|
8c9a9dd0f tty: remove resiz... |
2116 |
tty->winsize = *ws; |
ca9bda00b [PATCH] tty locki... |
2117 |
done: |
fc6f62382 pty: simplify resize |
2118 |
mutex_unlock(&tty->termios_mutex); |
1da177e4c Linux-2.6.12-rc2 |
2119 2120 |
return 0; } |
af9b897ee [PATCH] tty layer... |
2121 |
/** |
8c9a9dd0f tty: remove resiz... |
2122 |
* tiocswinsz - implement window size set ioctl |
fc6f62382 pty: simplify resize |
2123 |
* @tty; tty side of tty |
8c9a9dd0f tty: remove resiz... |
2124 2125 2126 2127 2128 2129 2130 |
* @arg: user buffer for result * * Copies the user idea of the window size to the kernel. Traditionally * this is just advisory information but for the Linux console it * actually has driver level meaning and triggers a VC resize. * * Locking: |
25985edce Fix common misspe... |
2131 |
* Driver dependent. The default do_resize method takes the |
8c9a9dd0f tty: remove resiz... |
2132 2133 2134 |
* tty termios mutex and ctrl_lock. The console takes its own lock * then calls into the default method. */ |
fc6f62382 pty: simplify resize |
2135 |
static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg) |
8c9a9dd0f tty: remove resiz... |
2136 2137 2138 2139 2140 2141 |
{ struct winsize tmp_ws; if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) return -EFAULT; if (tty->ops->resize) |
fc6f62382 pty: simplify resize |
2142 |
return tty->ops->resize(tty, &tmp_ws); |
8c9a9dd0f tty: remove resiz... |
2143 |
else |
fc6f62382 pty: simplify resize |
2144 |
return tty_do_resize(tty, &tmp_ws); |
8c9a9dd0f tty: remove resiz... |
2145 2146 2147 |
} /** |
af9b897ee [PATCH] tty layer... |
2148 2149 2150 |
* tioccons - allow admin to move logical console * @file: the file to become console * |
25985edce Fix common misspe... |
2151 |
* Allow the administrator to move the redirected console device |
af9b897ee [PATCH] tty layer... |
2152 2153 2154 |
* * Locking: uses redirect_lock to guard the redirect information */ |
1da177e4c Linux-2.6.12-rc2 |
2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 |
static int tioccons(struct file *file) { if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (file->f_op->write == redirected_tty_write) { struct file *f; spin_lock(&redirect_lock); f = redirect; redirect = NULL; spin_unlock(&redirect_lock); if (f) fput(f); return 0; } spin_lock(&redirect_lock); if (redirect) { spin_unlock(&redirect_lock); return -EBUSY; } get_file(file); redirect = file; spin_unlock(&redirect_lock); return 0; } |
af9b897ee [PATCH] tty layer... |
2179 2180 2181 2182 2183 2184 2185 2186 2187 |
/** * fionbio - non blocking ioctl * @file: file to set blocking value * @p: user parameter * * Historical tty interfaces had a blocking control ioctl before * the generic functionality existed. This piece of history is preserved * in the expected tty API of posix OS's. * |
6146b9af8 tty: Fix a typo n... |
2188 |
* Locking: none, the open file handle ensures it won't go away. |
af9b897ee [PATCH] tty layer... |
2189 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
2190 2191 2192 2193 2194 2195 2196 |
static int fionbio(struct file *file, int __user *p) { int nonblock; if (get_user(nonblock, p)) return -EFAULT; |
db1dd4d37 Use f_lock to pro... |
2197 |
spin_lock(&file->f_lock); |
1da177e4c Linux-2.6.12-rc2 |
2198 2199 2200 2201 |
if (nonblock) file->f_flags |= O_NONBLOCK; else file->f_flags &= ~O_NONBLOCK; |
db1dd4d37 Use f_lock to pro... |
2202 |
spin_unlock(&file->f_lock); |
1da177e4c Linux-2.6.12-rc2 |
2203 2204 |
return 0; } |
af9b897ee [PATCH] tty layer... |
2205 2206 2207 2208 2209 2210 2211 2212 2213 |
/** * tiocsctty - set controlling tty * @tty: tty structure * @arg: user argument * * This ioctl is used to manage job control. It permits a session * leader to set this tty as the controlling tty for the session. * * Locking: |
28298232a [PATCH] tty: Fix ... |
2214 |
* Takes tty_mutex() to protect tty instance |
24ec839c4 [PATCH] tty: ->si... |
2215 2216 |
* Takes tasklist_lock internally to walk sessions * Takes ->siglock() when updating signal->tty |
af9b897ee [PATCH] tty layer... |
2217 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
2218 2219 |
static int tiocsctty(struct tty_struct *tty, int arg) { |
24ec839c4 [PATCH] tty: ->si... |
2220 |
int ret = 0; |
ab521dc0f [PATCH] tty: upda... |
2221 |
if (current->signal->leader && (task_session(current) == tty->session)) |
24ec839c4 [PATCH] tty: ->si... |
2222 2223 2224 |
return ret; mutex_lock(&tty_mutex); |
1da177e4c Linux-2.6.12-rc2 |
2225 2226 2227 2228 |
/* * The process must be a session leader and * not have a controlling tty already. */ |
24ec839c4 [PATCH] tty: ->si... |
2229 2230 2231 2232 |
if (!current->signal->leader || current->signal->tty) { ret = -EPERM; goto unlock; } |
ab521dc0f [PATCH] tty: upda... |
2233 |
if (tty->session) { |
1da177e4c Linux-2.6.12-rc2 |
2234 2235 2236 2237 |
/* * This tty is already the controlling * tty for another session group! */ |
37bdfb074 tty_io: drag scre... |
2238 |
if (arg == 1 && capable(CAP_SYS_ADMIN)) { |
1da177e4c Linux-2.6.12-rc2 |
2239 2240 2241 |
/* * Steal it away */ |
1da177e4c Linux-2.6.12-rc2 |
2242 |
read_lock(&tasklist_lock); |
24ec839c4 [PATCH] tty: ->si... |
2243 |
session_clear_tty(tty->session); |
1da177e4c Linux-2.6.12-rc2 |
2244 |
read_unlock(&tasklist_lock); |
24ec839c4 [PATCH] tty: ->si... |
2245 2246 2247 2248 |
} else { ret = -EPERM; goto unlock; } |
1da177e4c Linux-2.6.12-rc2 |
2249 |
} |
24ec839c4 [PATCH] tty: ->si... |
2250 2251 |
proc_set_tty(current, tty); unlock: |
28298232a [PATCH] tty: Fix ... |
2252 |
mutex_unlock(&tty_mutex); |
24ec839c4 [PATCH] tty: ->si... |
2253 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
2254 |
} |
af9b897ee [PATCH] tty layer... |
2255 |
/** |
5d0fdf1e0 tty_io: fix remai... |
2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 |
* tty_get_pgrp - return a ref counted pgrp pid * @tty: tty to read * * Returns a refcounted instance of the pid struct for the process * group controlling the tty. */ struct pid *tty_get_pgrp(struct tty_struct *tty) { unsigned long flags; struct pid *pgrp; spin_lock_irqsave(&tty->ctrl_lock, flags); pgrp = get_pid(tty->pgrp); spin_unlock_irqrestore(&tty->ctrl_lock, flags); return pgrp; } EXPORT_SYMBOL_GPL(tty_get_pgrp); /** |
af9b897ee [PATCH] tty layer... |
2277 2278 |
* tiocgpgrp - get process group * @tty: tty passed by user |
25985edce Fix common misspe... |
2279 |
* @real_tty: tty side of the tty passed by the user if a pty else the tty |
af9b897ee [PATCH] tty layer... |
2280 2281 2282 2283 2284 |
* @p: returned pid * * Obtain the process group of the tty. If there is no process group * return an error. * |
24ec839c4 [PATCH] tty: ->si... |
2285 |
* Locking: none. Reference to current->signal->tty is safe. |
af9b897ee [PATCH] tty layer... |
2286 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
2287 2288 |
static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) { |
5d0fdf1e0 tty_io: fix remai... |
2289 2290 |
struct pid *pid; int ret; |
1da177e4c Linux-2.6.12-rc2 |
2291 2292 2293 2294 2295 2296 |
/* * (tty == real_tty) is a cheap way of * testing if the tty is NOT a master pty. */ if (tty == real_tty && current->signal->tty != real_tty) return -ENOTTY; |
5d0fdf1e0 tty_io: fix remai... |
2297 2298 2299 2300 |
pid = tty_get_pgrp(real_tty); ret = put_user(pid_vnr(pid), p); put_pid(pid); return ret; |
1da177e4c Linux-2.6.12-rc2 |
2301 |
} |
af9b897ee [PATCH] tty layer... |
2302 2303 2304 2305 2306 2307 2308 2309 2310 |
/** * tiocspgrp - attempt to set process group * @tty: tty passed by user * @real_tty: tty side device matching tty passed by user * @p: pid pointer * * Set the process group of the tty to the session passed. Only * permitted where the tty session is our session. * |
47f86834b redo locking of t... |
2311 |
* Locking: RCU, ctrl lock |
af9b897ee [PATCH] tty layer... |
2312 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
2313 2314 |
static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) { |
04a2e6a5c [PATCH] pid: make... |
2315 2316 |
struct pid *pgrp; pid_t pgrp_nr; |
1da177e4c Linux-2.6.12-rc2 |
2317 |
int retval = tty_check_change(real_tty); |
47f86834b redo locking of t... |
2318 |
unsigned long flags; |
1da177e4c Linux-2.6.12-rc2 |
2319 2320 2321 2322 2323 2324 2325 |
if (retval == -EIO) return -ENOTTY; if (retval) return retval; if (!current->signal->tty || (current->signal->tty != real_tty) || |
ab521dc0f [PATCH] tty: upda... |
2326 |
(real_tty->session != task_session(current))) |
1da177e4c Linux-2.6.12-rc2 |
2327 |
return -ENOTTY; |
04a2e6a5c [PATCH] pid: make... |
2328 |
if (get_user(pgrp_nr, p)) |
1da177e4c Linux-2.6.12-rc2 |
2329 |
return -EFAULT; |
04a2e6a5c [PATCH] pid: make... |
2330 |
if (pgrp_nr < 0) |
1da177e4c Linux-2.6.12-rc2 |
2331 |
return -EINVAL; |
04a2e6a5c [PATCH] pid: make... |
2332 |
rcu_read_lock(); |
b488893a3 pid namespaces: c... |
2333 |
pgrp = find_vpid(pgrp_nr); |
04a2e6a5c [PATCH] pid: make... |
2334 2335 2336 2337 2338 2339 2340 |
retval = -ESRCH; if (!pgrp) goto out_unlock; retval = -EPERM; if (session_of_pgrp(pgrp) != task_session(current)) goto out_unlock; retval = 0; |
47f86834b redo locking of t... |
2341 |
spin_lock_irqsave(&tty->ctrl_lock, flags); |
ab521dc0f [PATCH] tty: upda... |
2342 2343 |
put_pid(real_tty->pgrp); real_tty->pgrp = get_pid(pgrp); |
47f86834b redo locking of t... |
2344 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
04a2e6a5c [PATCH] pid: make... |
2345 2346 2347 |
out_unlock: rcu_read_unlock(); return retval; |
1da177e4c Linux-2.6.12-rc2 |
2348 |
} |
af9b897ee [PATCH] tty layer... |
2349 2350 2351 |
/** * tiocgsid - get session id * @tty: tty passed by user |
25985edce Fix common misspe... |
2352 |
* @real_tty: tty side of the tty passed by the user if a pty else the tty |
af9b897ee [PATCH] tty layer... |
2353 2354 2355 2356 2357 |
* @p: pointer to returned session id * * Obtain the session id of the tty. If there is no session * return an error. * |
24ec839c4 [PATCH] tty: ->si... |
2358 |
* Locking: none. Reference to current->signal->tty is safe. |
af9b897ee [PATCH] tty layer... |
2359 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
2360 2361 2362 2363 2364 2365 2366 2367 |
static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) { /* * (tty == real_tty) is a cheap way of * testing if the tty is NOT a master pty. */ if (tty == real_tty && current->signal->tty != real_tty) return -ENOTTY; |
ab521dc0f [PATCH] tty: upda... |
2368 |
if (!real_tty->session) |
1da177e4c Linux-2.6.12-rc2 |
2369 |
return -ENOTTY; |
b488893a3 pid namespaces: c... |
2370 |
return put_user(pid_vnr(real_tty->session), p); |
1da177e4c Linux-2.6.12-rc2 |
2371 |
} |
af9b897ee [PATCH] tty layer... |
2372 2373 2374 2375 2376 2377 2378 2379 2380 |
/** * tiocsetd - set line discipline * @tty: tty device * @p: pointer to user data * * Set the line discipline according to user request. * * Locking: see tty_set_ldisc, this function is just a helper */ |
1da177e4c Linux-2.6.12-rc2 |
2381 2382 2383 |
static int tiocsetd(struct tty_struct *tty, int __user *p) { int ldisc; |
04f378b19 tty: BKL pushdown |
2384 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
2385 2386 2387 |
if (get_user(ldisc, p)) return -EFAULT; |
04f378b19 tty: BKL pushdown |
2388 |
|
04f378b19 tty: BKL pushdown |
2389 |
ret = tty_set_ldisc(tty, ldisc); |
04f378b19 tty: BKL pushdown |
2390 2391 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
2392 |
} |
af9b897ee [PATCH] tty layer... |
2393 2394 2395 2396 2397 2398 2399 2400 2401 |
/** * send_break - performed time break * @tty: device to break on * @duration: timeout in mS * * Perform a timed break on hardware that lacks its own driver level * timed break functionality. * * Locking: |
28298232a [PATCH] tty: Fix ... |
2402 |
* atomic_write_lock serializes |
af9b897ee [PATCH] tty layer... |
2403 |
* |
af9b897ee [PATCH] tty layer... |
2404 |
*/ |
b20f3ae5f [PATCH] char/tty_... |
2405 |
static int send_break(struct tty_struct *tty, unsigned int duration) |
1da177e4c Linux-2.6.12-rc2 |
2406 |
{ |
9e98966c7 tty: rework break... |
2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 |
int retval; if (tty->ops->break_ctl == NULL) return 0; if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) retval = tty->ops->break_ctl(tty, duration); else { /* Do the work ourselves */ if (tty_write_lock(tty, 0) < 0) return -EINTR; retval = tty->ops->break_ctl(tty, -1); if (retval) goto out; if (!signal_pending(current)) msleep_interruptible(duration); retval = tty->ops->break_ctl(tty, 0); out: tty_write_unlock(tty); if (signal_pending(current)) retval = -EINTR; } return retval; |
1da177e4c Linux-2.6.12-rc2 |
2430 |
} |
af9b897ee [PATCH] tty layer... |
2431 |
/** |
f34d7a5b7 tty: The big oper... |
2432 |
* tty_tiocmget - get modem status |
af9b897ee [PATCH] tty layer... |
2433 2434 2435 2436 2437 2438 2439 2440 2441 |
* @tty: tty device * @file: user file pointer * @p: pointer to result * * Obtain the modem status bits from the tty driver if the feature * is supported. Return -EINVAL if it is not available. * * Locking: none (up to the driver) */ |
60b33c133 tiocmget: kill of... |
2442 |
static int tty_tiocmget(struct tty_struct *tty, int __user *p) |
1da177e4c Linux-2.6.12-rc2 |
2443 2444 |
{ int retval = -EINVAL; |
f34d7a5b7 tty: The big oper... |
2445 |
if (tty->ops->tiocmget) { |
60b33c133 tiocmget: kill of... |
2446 |
retval = tty->ops->tiocmget(tty); |
1da177e4c Linux-2.6.12-rc2 |
2447 2448 2449 2450 2451 2452 |
if (retval >= 0) retval = put_user(retval, p); } return retval; } |
af9b897ee [PATCH] tty layer... |
2453 |
/** |
f34d7a5b7 tty: The big oper... |
2454 |
* tty_tiocmset - set modem status |
af9b897ee [PATCH] tty layer... |
2455 |
* @tty: tty device |
af9b897ee [PATCH] tty layer... |
2456 2457 2458 2459 2460 2461 2462 2463 |
* @cmd: command - clear bits, set bits or set all * @p: pointer to desired bits * * Set the modem status bits from the tty driver if the feature * is supported. Return -EINVAL if it is not available. * * Locking: none (up to the driver) */ |
20b9d1771 tiocmset: kill th... |
2464 |
static int tty_tiocmset(struct tty_struct *tty, unsigned int cmd, |
1da177e4c Linux-2.6.12-rc2 |
2465 2466 |
unsigned __user *p) { |
ae6775178 tty: Clean up tio... |
2467 2468 |
int retval; unsigned int set, clear, val; |
1da177e4c Linux-2.6.12-rc2 |
2469 |
|
ae6775178 tty: Clean up tio... |
2470 2471 |
if (tty->ops->tiocmset == NULL) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
2472 |
|
ae6775178 tty: Clean up tio... |
2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 |
retval = get_user(val, p); if (retval) return retval; set = clear = 0; switch (cmd) { case TIOCMBIS: set = val; break; case TIOCMBIC: clear = val; break; case TIOCMSET: set = val; clear = ~val; break; } set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; |
20b9d1771 tiocmset: kill th... |
2491 |
return tty->ops->tiocmset(tty, set, clear); |
1da177e4c Linux-2.6.12-rc2 |
2492 |
} |
d281da7ff tty: Make tiocgic... |
2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 |
static int tty_tiocgicount(struct tty_struct *tty, void __user *arg) { int retval = -EINVAL; struct serial_icounter_struct icount; memset(&icount, 0, sizeof(icount)); if (tty->ops->get_icount) retval = tty->ops->get_icount(tty, &icount); if (retval != 0) return retval; if (copy_to_user(arg, &icount, sizeof(icount))) return -EFAULT; return 0; } |
e8b70e7d3 tty: Extract vari... |
2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 |
struct tty_struct *tty_pair_get_tty(struct tty_struct *tty) { if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER) tty = tty->link; return tty; } EXPORT_SYMBOL(tty_pair_get_tty); struct tty_struct *tty_pair_get_pty(struct tty_struct *tty) { if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER) return tty; return tty->link; } EXPORT_SYMBOL(tty_pair_get_pty); |
1da177e4c Linux-2.6.12-rc2 |
2523 2524 2525 |
/* * Split this up, as gcc can choke on it otherwise.. */ |
04f378b19 tty: BKL pushdown |
2526 |
long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
1da177e4c Linux-2.6.12-rc2 |
2527 |
{ |
d996b62a8 tty: fix fu_list ... |
2528 2529 |
struct tty_struct *tty = file_tty(file); struct tty_struct *real_tty; |
1da177e4c Linux-2.6.12-rc2 |
2530 2531 2532 |
void __user *p = (void __user *)arg; int retval; struct tty_ldisc *ld; |
04f378b19 tty: BKL pushdown |
2533 |
struct inode *inode = file->f_dentry->d_inode; |
37bdfb074 tty_io: drag scre... |
2534 |
|
1da177e4c Linux-2.6.12-rc2 |
2535 2536 |
if (tty_paranoia_check(tty, inode, "tty_ioctl")) return -EINVAL; |
e8b70e7d3 tty: Extract vari... |
2537 |
real_tty = tty_pair_get_tty(tty); |
1da177e4c Linux-2.6.12-rc2 |
2538 2539 2540 2541 2542 2543 2544 2545 2546 |
/* * Factor out some common prep work */ switch (cmd) { case TIOCSETD: case TIOCSBRK: case TIOCCBRK: case TCSBRK: |
37bdfb074 tty_io: drag scre... |
2547 |
case TCSBRKP: |
1da177e4c Linux-2.6.12-rc2 |
2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 |
retval = tty_check_change(tty); if (retval) return retval; if (cmd != TIOCCBRK) { tty_wait_until_sent(tty, 0); if (signal_pending(current)) return -EINTR; } break; } |
9e98966c7 tty: rework break... |
2558 2559 2560 |
/* * Now do the stuff. */ |
1da177e4c Linux-2.6.12-rc2 |
2561 |
switch (cmd) { |
37bdfb074 tty_io: drag scre... |
2562 2563 2564 |
case TIOCSTI: return tiocsti(tty, p); case TIOCGWINSZ: |
8f5200218 tty: Termios lock... |
2565 |
return tiocgwinsz(real_tty, p); |
37bdfb074 tty_io: drag scre... |
2566 |
case TIOCSWINSZ: |
fc6f62382 pty: simplify resize |
2567 |
return tiocswinsz(real_tty, p); |
37bdfb074 tty_io: drag scre... |
2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 |
case TIOCCONS: return real_tty != tty ? -EINVAL : tioccons(file); case FIONBIO: return fionbio(file, p); case TIOCEXCL: set_bit(TTY_EXCLUSIVE, &tty->flags); return 0; case TIOCNXCL: clear_bit(TTY_EXCLUSIVE, &tty->flags); return 0; case TIOCNOTTY: if (current->signal->tty != tty) return -ENOTTY; no_tty(); return 0; case TIOCSCTTY: return tiocsctty(tty, arg); case TIOCGPGRP: return tiocgpgrp(tty, real_tty, p); case TIOCSPGRP: return tiocspgrp(tty, real_tty, p); case TIOCGSID: return tiocgsid(tty, real_tty, p); case TIOCGETD: |
c65c9bc3e tty: rewrite the ... |
2592 |
return put_user(tty->ldisc->ops->num, (int __user *)p); |
37bdfb074 tty_io: drag scre... |
2593 2594 |
case TIOCSETD: return tiocsetd(tty, p); |
3c95c985f tty: add TIOCVHAN... |
2595 2596 2597 2598 2599 |
case TIOCVHANGUP: if (!capable(CAP_SYS_ADMIN)) return -EPERM; tty_vhangup(tty); return 0; |
b7b8de087 TTY: Add tty ioct... |
2600 2601 2602 2603 2604 |
case TIOCGDEV: { unsigned int ret = new_encode_dev(tty_devnum(real_tty)); return put_user(ret, (unsigned int __user *)p); } |
37bdfb074 tty_io: drag scre... |
2605 2606 2607 2608 |
/* * Break handling */ case TIOCSBRK: /* Turn break on, unconditionally */ |
f34d7a5b7 tty: The big oper... |
2609 |
if (tty->ops->break_ctl) |
9e98966c7 tty: rework break... |
2610 |
return tty->ops->break_ctl(tty, -1); |
37bdfb074 tty_io: drag scre... |
2611 |
return 0; |
37bdfb074 tty_io: drag scre... |
2612 |
case TIOCCBRK: /* Turn break off, unconditionally */ |
f34d7a5b7 tty: The big oper... |
2613 |
if (tty->ops->break_ctl) |
9e98966c7 tty: rework break... |
2614 |
return tty->ops->break_ctl(tty, 0); |
37bdfb074 tty_io: drag scre... |
2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 |
return 0; case TCSBRK: /* SVID version: non-zero arg --> no break */ /* non-zero arg means wait for all output data * to be sent (performed above) but don't send break. * This is used by the tcdrain() termios function. */ if (!arg) return send_break(tty, 250); return 0; case TCSBRKP: /* support for POSIX tcsendbreak() */ return send_break(tty, arg ? arg*100 : 250); case TIOCMGET: |
60b33c133 tiocmget: kill of... |
2628 |
return tty_tiocmget(tty, p); |
37bdfb074 tty_io: drag scre... |
2629 2630 2631 |
case TIOCMSET: case TIOCMBIC: case TIOCMBIS: |
20b9d1771 tiocmset: kill th... |
2632 |
return tty_tiocmset(tty, cmd, p); |
d281da7ff tty: Make tiocgic... |
2633 2634 2635 2636 2637 2638 |
case TIOCGICOUNT: retval = tty_tiocgicount(tty, p); /* For the moment allow fall through to the old method */ if (retval != -EINVAL) return retval; break; |
37bdfb074 tty_io: drag scre... |
2639 2640 2641 2642 2643 2644 |
case TCFLSH: switch (arg) { case TCIFLUSH: case TCIOFLUSH: /* flush tty buffer and allow ldisc to process ioctl */ tty_buffer_flush(tty); |
c5c34d486 tty: flush flip b... |
2645 |
break; |
37bdfb074 tty_io: drag scre... |
2646 2647 |
} break; |
1da177e4c Linux-2.6.12-rc2 |
2648 |
} |
f34d7a5b7 tty: The big oper... |
2649 |
if (tty->ops->ioctl) { |
6caa76b77 tty: now phase ou... |
2650 |
retval = (tty->ops->ioctl)(tty, cmd, arg); |
1da177e4c Linux-2.6.12-rc2 |
2651 2652 2653 2654 2655 |
if (retval != -ENOIOCTLCMD) return retval; } ld = tty_ldisc_ref_wait(tty); retval = -EINVAL; |
a352def21 tty: Ldisc revamp |
2656 2657 |
if (ld->ops->ioctl) { retval = ld->ops->ioctl(tty, file, cmd, arg); |
1da177e4c Linux-2.6.12-rc2 |
2658 2659 2660 2661 2662 2663 |
if (retval == -ENOIOCTLCMD) retval = -EINVAL; } tty_ldisc_deref(ld); return retval; } |
e10cc1df1 tty: add compat_i... |
2664 |
#ifdef CONFIG_COMPAT |
37bdfb074 tty_io: drag scre... |
2665 |
static long tty_compat_ioctl(struct file *file, unsigned int cmd, |
e10cc1df1 tty: add compat_i... |
2666 2667 2668 |
unsigned long arg) { struct inode *inode = file->f_dentry->d_inode; |
d996b62a8 tty: fix fu_list ... |
2669 |
struct tty_struct *tty = file_tty(file); |
e10cc1df1 tty: add compat_i... |
2670 2671 2672 2673 2674 |
struct tty_ldisc *ld; int retval = -ENOIOCTLCMD; if (tty_paranoia_check(tty, inode, "tty_ioctl")) return -EINVAL; |
f34d7a5b7 tty: The big oper... |
2675 |
if (tty->ops->compat_ioctl) { |
6caa76b77 tty: now phase ou... |
2676 |
retval = (tty->ops->compat_ioctl)(tty, cmd, arg); |
e10cc1df1 tty: add compat_i... |
2677 2678 2679 2680 2681 |
if (retval != -ENOIOCTLCMD) return retval; } ld = tty_ldisc_ref_wait(tty); |
a352def21 tty: Ldisc revamp |
2682 2683 |
if (ld->ops->compat_ioctl) retval = ld->ops->compat_ioctl(tty, file, cmd, arg); |
8193c4290 tty: Support comp... |
2684 2685 |
else retval = n_tty_compat_ioctl_helper(tty, file, cmd, arg); |
e10cc1df1 tty: add compat_i... |
2686 2687 2688 2689 2690 |
tty_ldisc_deref(ld); return retval; } #endif |
1da177e4c Linux-2.6.12-rc2 |
2691 2692 2693 2694 2695 2696 |
/* * This implements the "Secure Attention Key" --- the idea is to * prevent trojan horses by killing all processes associated with this * tty when the user hits the "Secure Attention Key". Required for * super-paranoid applications --- see the Orange Book for more details. |
37bdfb074 tty_io: drag scre... |
2697 |
* |
1da177e4c Linux-2.6.12-rc2 |
2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 |
* This code could be nicer; ideally it should send a HUP, wait a few * seconds, then send a INT, and then a KILL signal. But you then * have to coordinate with the init process, since all processes associated * with the current tty must be dead before the new getty is allowed * to spawn. * * Now, if it would be correct ;-/ The current code has a nasty hole - * it doesn't catch files in flight. We may send the descriptor to ourselves * via AF_UNIX socket, close it and later fetch from socket. FIXME. * * Nasty bug: do_SAK is being called in interrupt context. This can * deadlock. We punt it up to process context. AKPM - 16Mar2001 */ |
8b6312f4d [PATCH] vt: refac... |
2711 |
void __do_SAK(struct tty_struct *tty) |
1da177e4c Linux-2.6.12-rc2 |
2712 2713 2714 2715 |
{ #ifdef TTY_SOFT_SAK tty_hangup(tty); #else |
652486fb8 [PATCH] do_SAK: d... |
2716 |
struct task_struct *g, *p; |
ab521dc0f [PATCH] tty: upda... |
2717 |
struct pid *session; |
1da177e4c Linux-2.6.12-rc2 |
2718 2719 |
int i; struct file *filp; |
badf16621 [PATCH] files: br... |
2720 |
struct fdtable *fdt; |
37bdfb074 tty_io: drag scre... |
2721 |
|
1da177e4c Linux-2.6.12-rc2 |
2722 2723 |
if (!tty) return; |
24ec839c4 [PATCH] tty: ->si... |
2724 |
session = tty->session; |
37bdfb074 tty_io: drag scre... |
2725 |
|
b3f13debd [PATCH] tty_io.c ... |
2726 |
tty_ldisc_flush(tty); |
1da177e4c Linux-2.6.12-rc2 |
2727 |
|
f34d7a5b7 tty: The big oper... |
2728 |
tty_driver_flush_buffer(tty); |
37bdfb074 tty_io: drag scre... |
2729 |
|
1da177e4c Linux-2.6.12-rc2 |
2730 |
read_lock(&tasklist_lock); |
652486fb8 [PATCH] do_SAK: d... |
2731 |
/* Kill the entire session */ |
ab521dc0f [PATCH] tty: upda... |
2732 |
do_each_pid_task(session, PIDTYPE_SID, p) { |
652486fb8 [PATCH] do_SAK: d... |
2733 |
printk(KERN_NOTICE "SAK: killed process %d" |
1b0f7ffd0 pids: kill signal... |
2734 2735 |
" (%s): task_session(p)==tty->session ", |
ba25f9dcc Use helpers to ob... |
2736 |
task_pid_nr(p), p->comm); |
652486fb8 [PATCH] do_SAK: d... |
2737 |
send_sig(SIGKILL, p, 1); |
ab521dc0f [PATCH] tty: upda... |
2738 |
} while_each_pid_task(session, PIDTYPE_SID, p); |
652486fb8 [PATCH] do_SAK: d... |
2739 2740 2741 2742 2743 |
/* Now kill any processes that happen to have the * tty open. */ do_each_thread(g, p) { if (p->signal->tty == tty) { |
1da177e4c Linux-2.6.12-rc2 |
2744 |
printk(KERN_NOTICE "SAK: killed process %d" |
1b0f7ffd0 pids: kill signal... |
2745 2746 |
" (%s): task_session(p)==tty->session ", |
ba25f9dcc Use helpers to ob... |
2747 |
task_pid_nr(p), p->comm); |
1da177e4c Linux-2.6.12-rc2 |
2748 2749 2750 2751 2752 |
send_sig(SIGKILL, p, 1); continue; } task_lock(p); if (p->files) { |
ca99c1da0 [PATCH] Fix file ... |
2753 2754 2755 2756 2757 |
/* * We don't take a ref to the file, so we must * hold ->file_lock instead. */ spin_lock(&p->files->file_lock); |
badf16621 [PATCH] files: br... |
2758 |
fdt = files_fdtable(p->files); |
37bdfb074 tty_io: drag scre... |
2759 |
for (i = 0; i < fdt->max_fds; i++) { |
1da177e4c Linux-2.6.12-rc2 |
2760 2761 2762 2763 |
filp = fcheck_files(p->files, i); if (!filp) continue; if (filp->f_op->read == tty_read && |
d996b62a8 tty: fix fu_list ... |
2764 |
file_tty(filp) == tty) { |
1da177e4c Linux-2.6.12-rc2 |
2765 2766 2767 |
printk(KERN_NOTICE "SAK: killed process %d" " (%s): fd#%d opened to the tty ", |
ba25f9dcc Use helpers to ob... |
2768 |
task_pid_nr(p), p->comm, i); |
20ac94378 [PATCH] do_SAK: D... |
2769 |
force_sig(SIGKILL, p); |
1da177e4c Linux-2.6.12-rc2 |
2770 2771 2772 |
break; } } |
ca99c1da0 [PATCH] Fix file ... |
2773 |
spin_unlock(&p->files->file_lock); |
1da177e4c Linux-2.6.12-rc2 |
2774 2775 |
} task_unlock(p); |
652486fb8 [PATCH] do_SAK: d... |
2776 |
} while_each_thread(g, p); |
1da177e4c Linux-2.6.12-rc2 |
2777 2778 2779 |
read_unlock(&tasklist_lock); #endif } |
8b6312f4d [PATCH] vt: refac... |
2780 2781 2782 2783 2784 2785 |
static void do_SAK_work(struct work_struct *work) { struct tty_struct *tty = container_of(work, struct tty_struct, SAK_work); __do_SAK(tty); } |
1da177e4c Linux-2.6.12-rc2 |
2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 |
/* * The tq handling here is a little racy - tty->SAK_work may already be queued. * Fortunately we don't need to worry, because if ->SAK_work is already queued, * the values which we write to it will be identical to the values which it * already has. --akpm */ void do_SAK(struct tty_struct *tty) { if (!tty) return; |
1da177e4c Linux-2.6.12-rc2 |
2796 2797 2798 2799 |
schedule_work(&tty->SAK_work); } EXPORT_SYMBOL(do_SAK); |
30004ac9c tty: add tty_stru... |
2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 |
static int dev_match_devt(struct device *dev, void *data) { dev_t *devt = data; return dev->devt == *devt; } /* Must put_device() after it's unused! */ static struct device *tty_get_device(struct tty_struct *tty) { dev_t devt = tty_devnum(tty); return class_find_device(tty_class, NULL, &devt, dev_match_devt); } |
af9b897ee [PATCH] tty layer... |
2812 |
/** |
af9b897ee [PATCH] tty layer... |
2813 2814 2815 2816 2817 2818 2819 |
* initialize_tty_struct * @tty: tty to initialize * * This subroutine initializes a tty structure that has been newly * allocated. * * Locking: none - tty in question must not be exposed at this point |
1da177e4c Linux-2.6.12-rc2 |
2820 |
*/ |
af9b897ee [PATCH] tty layer... |
2821 |
|
bf970ee46 tty: extract the ... |
2822 2823 |
void initialize_tty_struct(struct tty_struct *tty, struct tty_driver *driver, int idx) |
1da177e4c Linux-2.6.12-rc2 |
2824 2825 |
{ memset(tty, 0, sizeof(struct tty_struct)); |
9c9f4ded9 tty: Add a kref c... |
2826 |
kref_init(&tty->kref); |
1da177e4c Linux-2.6.12-rc2 |
2827 |
tty->magic = TTY_MAGIC; |
01e1abb2c tty: Split ldisc ... |
2828 |
tty_ldisc_init(tty); |
ab521dc0f [PATCH] tty: upda... |
2829 2830 |
tty->session = NULL; tty->pgrp = NULL; |
1da177e4c Linux-2.6.12-rc2 |
2831 |
tty->overrun_time = jiffies; |
33f0f88f1 [PATCH] TTY layer... |
2832 2833 |
tty->buf.head = tty->buf.tail = NULL; tty_buffer_init(tty); |
5785c95ba [PATCH] tty: make... |
2834 |
mutex_init(&tty->termios_mutex); |
c65c9bc3e tty: rewrite the ... |
2835 |
mutex_init(&tty->ldisc_mutex); |
1da177e4c Linux-2.6.12-rc2 |
2836 2837 |
init_waitqueue_head(&tty->write_wait); init_waitqueue_head(&tty->read_wait); |
65f27f384 WorkStruct: Pass ... |
2838 |
INIT_WORK(&tty->hangup_work, do_tty_hangup); |
70522e121 [PATCH] sem2mutex... |
2839 2840 |
mutex_init(&tty->atomic_read_lock); mutex_init(&tty->atomic_write_lock); |
a88a69c91 n_tty: Fix loss o... |
2841 2842 |
mutex_init(&tty->output_lock); mutex_init(&tty->echo_lock); |
1da177e4c Linux-2.6.12-rc2 |
2843 |
spin_lock_init(&tty->read_lock); |
04f378b19 tty: BKL pushdown |
2844 |
spin_lock_init(&tty->ctrl_lock); |
1da177e4c Linux-2.6.12-rc2 |
2845 |
INIT_LIST_HEAD(&tty->tty_files); |
7f1f86a0d [PATCH] Fix SAK_w... |
2846 |
INIT_WORK(&tty->SAK_work, do_SAK_work); |
bf970ee46 tty: extract the ... |
2847 2848 2849 2850 2851 |
tty->driver = driver; tty->ops = driver->ops; tty->index = idx; tty_line_name(driver, idx, tty->name); |
30004ac9c tty: add tty_stru... |
2852 |
tty->dev = tty_get_device(tty); |
1da177e4c Linux-2.6.12-rc2 |
2853 |
} |
f34d7a5b7 tty: The big oper... |
2854 |
/** |
6716671d8 TTY: introduce de... |
2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 |
* deinitialize_tty_struct * @tty: tty to deinitialize * * This subroutine deinitializes a tty structure that has been newly * allocated but tty_release cannot be called on that yet. * * Locking: none - tty in question must not be exposed at this point */ void deinitialize_tty_struct(struct tty_struct *tty) { tty_ldisc_deinit(tty); } /** |
f34d7a5b7 tty: The big oper... |
2869 2870 2871 2872 2873 2874 2875 2876 2877 |
* tty_put_char - write one character to a tty * @tty: tty * @ch: character * * Write one byte to the tty using the provided put_char method * if present. Returns the number of characters successfully output. * * Note: the specific put_char operation in the driver layer may go * away soon. Don't call it directly, use this method |
1da177e4c Linux-2.6.12-rc2 |
2878 |
*/ |
af9b897ee [PATCH] tty layer... |
2879 |
|
f34d7a5b7 tty: The big oper... |
2880 |
int tty_put_char(struct tty_struct *tty, unsigned char ch) |
1da177e4c Linux-2.6.12-rc2 |
2881 |
{ |
f34d7a5b7 tty: The big oper... |
2882 2883 2884 |
if (tty->ops->put_char) return tty->ops->put_char(tty, ch); return tty->ops->write(tty, &ch, 1); |
1da177e4c Linux-2.6.12-rc2 |
2885 |
} |
f34d7a5b7 tty: The big oper... |
2886 |
EXPORT_SYMBOL_GPL(tty_put_char); |
d81ed1030 tty: Remove more ... |
2887 |
struct class *tty_class; |
1da177e4c Linux-2.6.12-rc2 |
2888 2889 |
/** |
af9b897ee [PATCH] tty layer... |
2890 2891 2892 2893 2894 2895 |
* tty_register_device - register a tty device * @driver: the tty driver that describes the tty device * @index: the index in the tty driver for this tty device * @device: a struct device that is associated with this tty device. * This field is optional, if there is no known struct device * for this tty device it can be set to NULL safely. |
1da177e4c Linux-2.6.12-rc2 |
2896 |
* |
01107d343 Driver core: conv... |
2897 2898 |
* Returns a pointer to the struct device for this tty device * (or ERR_PTR(-EFOO) on error). |
1cdcb6b43 [PATCH] TTY: retu... |
2899 |
* |
af9b897ee [PATCH] tty layer... |
2900 2901 2902 2903 2904 2905 |
* This call is required to be made to register an individual tty device * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If * that bit is not set, this function should not be called by a tty * driver. * * Locking: ?? |
1da177e4c Linux-2.6.12-rc2 |
2906 |
*/ |
af9b897ee [PATCH] tty layer... |
2907 |
|
01107d343 Driver core: conv... |
2908 2909 |
struct device *tty_register_device(struct tty_driver *driver, unsigned index, struct device *device) |
1da177e4c Linux-2.6.12-rc2 |
2910 2911 2912 2913 2914 2915 2916 2917 |
{ char name[64]; dev_t dev = MKDEV(driver->major, driver->minor_start) + index; if (index >= driver->num) { printk(KERN_ERR "Attempt to register invalid tty line number " " (%d). ", index); |
1cdcb6b43 [PATCH] TTY: retu... |
2918 |
return ERR_PTR(-EINVAL); |
1da177e4c Linux-2.6.12-rc2 |
2919 |
} |
1da177e4c Linux-2.6.12-rc2 |
2920 2921 2922 2923 |
if (driver->type == TTY_DRIVER_TYPE_PTY) pty_line_name(driver, index, name); else tty_line_name(driver, index, name); |
1cdcb6b43 [PATCH] TTY: retu... |
2924 |
|
03457cd45 device create: ch... |
2925 |
return device_create(tty_class, device, dev, NULL, name); |
1da177e4c Linux-2.6.12-rc2 |
2926 |
} |
7d7b93c14 tty: kref the tty... |
2927 |
EXPORT_SYMBOL(tty_register_device); |
1da177e4c Linux-2.6.12-rc2 |
2928 2929 |
/** |
af9b897ee [PATCH] tty layer... |
2930 2931 2932 |
* tty_unregister_device - unregister a tty device * @driver: the tty driver that describes the tty device * @index: the index in the tty driver for this tty device |
1da177e4c Linux-2.6.12-rc2 |
2933 |
* |
af9b897ee [PATCH] tty layer... |
2934 2935 2936 2937 |
* If a tty device is registered with a call to tty_register_device() then * this function must be called when the tty device is gone. * * Locking: ?? |
1da177e4c Linux-2.6.12-rc2 |
2938 |
*/ |
af9b897ee [PATCH] tty layer... |
2939 |
|
1da177e4c Linux-2.6.12-rc2 |
2940 2941 |
void tty_unregister_device(struct tty_driver *driver, unsigned index) { |
37bdfb074 tty_io: drag scre... |
2942 2943 |
device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); |
1da177e4c Linux-2.6.12-rc2 |
2944 |
} |
1da177e4c Linux-2.6.12-rc2 |
2945 2946 2947 2948 2949 |
EXPORT_SYMBOL(tty_unregister_device); struct tty_driver *alloc_tty_driver(int lines) { struct tty_driver *driver; |
506eb99a2 tty_io: Use kzalloc |
2950 |
driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
2951 |
if (driver) { |
7d7b93c14 tty: kref the tty... |
2952 |
kref_init(&driver->kref); |
1da177e4c Linux-2.6.12-rc2 |
2953 2954 2955 2956 2957 2958 |
driver->magic = TTY_DRIVER_MAGIC; driver->num = lines; /* later we'll move allocation of tables here */ } return driver; } |
7d7b93c14 tty: kref the tty... |
2959 |
EXPORT_SYMBOL(alloc_tty_driver); |
1da177e4c Linux-2.6.12-rc2 |
2960 |
|
7d7b93c14 tty: kref the tty... |
2961 |
static void destruct_tty_driver(struct kref *kref) |
1da177e4c Linux-2.6.12-rc2 |
2962 |
{ |
7d7b93c14 tty: kref the tty... |
2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 |
struct tty_driver *driver = container_of(kref, struct tty_driver, kref); int i; struct ktermios *tp; void *p; if (driver->flags & TTY_DRIVER_INSTALLED) { /* * Free the termios and termios_locked structures because * we don't want to get memory leaks when modular tty * drivers are removed from the kernel. */ for (i = 0; i < driver->num; i++) { tp = driver->termios[i]; if (tp) { driver->termios[i] = NULL; kfree(tp); } |
7d7b93c14 tty: kref the tty... |
2980 2981 2982 2983 2984 2985 |
if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) tty_unregister_device(driver, i); } p = driver->ttys; proc_tty_unregister_driver(driver); driver->ttys = NULL; |
fe6e29fdb tty: simplify kte... |
2986 |
driver->termios = NULL; |
7d7b93c14 tty: kref the tty... |
2987 2988 2989 |
kfree(p); cdev_del(&driver->cdev); } |
1da177e4c Linux-2.6.12-rc2 |
2990 2991 |
kfree(driver); } |
7d7b93c14 tty: kref the tty... |
2992 2993 2994 2995 2996 |
void tty_driver_kref_put(struct tty_driver *driver) { kref_put(&driver->kref, destruct_tty_driver); } EXPORT_SYMBOL(tty_driver_kref_put); |
b68e31d0e [PATCH] const str... |
2997 2998 |
void tty_set_operations(struct tty_driver *driver, const struct tty_operations *op) |
1da177e4c Linux-2.6.12-rc2 |
2999 |
{ |
f34d7a5b7 tty: The big oper... |
3000 3001 |
driver->ops = op; }; |
7d7b93c14 tty: kref the tty... |
3002 |
EXPORT_SYMBOL(tty_set_operations); |
1da177e4c Linux-2.6.12-rc2 |
3003 |
|
7d7b93c14 tty: kref the tty... |
3004 3005 3006 3007 |
void put_tty_driver(struct tty_driver *d) { tty_driver_kref_put(d); } |
1da177e4c Linux-2.6.12-rc2 |
3008 |
EXPORT_SYMBOL(put_tty_driver); |
1da177e4c Linux-2.6.12-rc2 |
3009 3010 3011 3012 3013 3014 3015 |
/* * Called by a tty driver to register itself. */ int tty_register_driver(struct tty_driver *driver) { int error; |
37bdfb074 tty_io: drag scre... |
3016 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
3017 3018 |
dev_t dev; void **p = NULL; |
b670bde0b tty_io: check ret... |
3019 |
struct device *d; |
1da177e4c Linux-2.6.12-rc2 |
3020 |
|
543691a6c tty_register_driv... |
3021 |
if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { |
fe6e29fdb tty: simplify kte... |
3022 |
p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
3023 3024 |
if (!p) return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
3025 3026 3027 |
} if (!driver->major) { |
37bdfb074 tty_io: drag scre... |
3028 3029 |
error = alloc_chrdev_region(&dev, driver->minor_start, driver->num, driver->name); |
1da177e4c Linux-2.6.12-rc2 |
3030 3031 3032 3033 3034 3035 |
if (!error) { driver->major = MAJOR(dev); driver->minor_start = MINOR(dev); } } else { dev = MKDEV(driver->major, driver->minor_start); |
e5717c48e [PATCH] tty_regis... |
3036 |
error = register_chrdev_region(dev, driver->num, driver->name); |
1da177e4c Linux-2.6.12-rc2 |
3037 3038 3039 3040 3041 3042 3043 3044 |
} if (error < 0) { kfree(p); return error; } if (p) { driver->ttys = (struct tty_struct **)p; |
edc6afc54 [PATCH] tty: swit... |
3045 |
driver->termios = (struct ktermios **)(p + driver->num); |
1da177e4c Linux-2.6.12-rc2 |
3046 3047 3048 |
} else { driver->ttys = NULL; driver->termios = NULL; |
1da177e4c Linux-2.6.12-rc2 |
3049 3050 3051 3052 3053 3054 |
} cdev_init(&driver->cdev, &tty_fops); driver->cdev.owner = driver->owner; error = cdev_add(&driver->cdev, dev, driver->num); if (error) { |
1da177e4c Linux-2.6.12-rc2 |
3055 3056 |
unregister_chrdev_region(dev, driver->num); driver->ttys = NULL; |
fe6e29fdb tty: simplify kte... |
3057 |
driver->termios = NULL; |
1da177e4c Linux-2.6.12-rc2 |
3058 3059 3060 |
kfree(p); return error; } |
ca509f69d Protect tty drive... |
3061 |
mutex_lock(&tty_mutex); |
1da177e4c Linux-2.6.12-rc2 |
3062 |
list_add(&driver->tty_drivers, &tty_drivers); |
ca509f69d Protect tty drive... |
3063 |
mutex_unlock(&tty_mutex); |
37bdfb074 tty_io: drag scre... |
3064 3065 |
if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) { |
b670bde0b tty_io: check ret... |
3066 3067 3068 3069 3070 3071 3072 |
for (i = 0; i < driver->num; i++) { d = tty_register_device(driver, i, NULL); if (IS_ERR(d)) { error = PTR_ERR(d); goto err; } } |
1da177e4c Linux-2.6.12-rc2 |
3073 3074 |
} proc_tty_register_driver(driver); |
7d7b93c14 tty: kref the tty... |
3075 |
driver->flags |= TTY_DRIVER_INSTALLED; |
1da177e4c Linux-2.6.12-rc2 |
3076 |
return 0; |
b670bde0b tty_io: check ret... |
3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 |
err: for (i--; i >= 0; i--) tty_unregister_device(driver, i); mutex_lock(&tty_mutex); list_del(&driver->tty_drivers); mutex_unlock(&tty_mutex); unregister_chrdev_region(dev, driver->num); driver->ttys = NULL; driver->termios = NULL; kfree(p); return error; |
1da177e4c Linux-2.6.12-rc2 |
3091 3092 3093 3094 3095 3096 3097 3098 3099 |
} EXPORT_SYMBOL(tty_register_driver); /* * Called by a tty driver to unregister itself. */ int tty_unregister_driver(struct tty_driver *driver) { |
7d7b93c14 tty: kref the tty... |
3100 3101 |
#if 0 /* FIXME */ |
1da177e4c Linux-2.6.12-rc2 |
3102 3103 |
if (driver->refcount) return -EBUSY; |
7d7b93c14 tty: kref the tty... |
3104 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
3105 3106 |
unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), driver->num); |
ca509f69d Protect tty drive... |
3107 |
mutex_lock(&tty_mutex); |
1da177e4c Linux-2.6.12-rc2 |
3108 |
list_del(&driver->tty_drivers); |
ca509f69d Protect tty drive... |
3109 |
mutex_unlock(&tty_mutex); |
1da177e4c Linux-2.6.12-rc2 |
3110 3111 |
return 0; } |
7d7b93c14 tty: kref the tty... |
3112 |
|
1da177e4c Linux-2.6.12-rc2 |
3113 |
EXPORT_SYMBOL(tty_unregister_driver); |
24ec839c4 [PATCH] tty: ->si... |
3114 3115 3116 3117 3118 3119 3120 3121 |
dev_t tty_devnum(struct tty_struct *tty) { return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index; } EXPORT_SYMBOL(tty_devnum); void proc_clear_tty(struct task_struct *p) { |
7c3b1dcf1 tty: make sure th... |
3122 |
unsigned long flags; |
9c9f4ded9 tty: Add a kref c... |
3123 |
struct tty_struct *tty; |
7c3b1dcf1 tty: make sure th... |
3124 |
spin_lock_irqsave(&p->sighand->siglock, flags); |
9c9f4ded9 tty: Add a kref c... |
3125 |
tty = p->signal->tty; |
24ec839c4 [PATCH] tty: ->si... |
3126 |
p->signal->tty = NULL; |
7c3b1dcf1 tty: make sure th... |
3127 |
spin_unlock_irqrestore(&p->sighand->siglock, flags); |
9c9f4ded9 tty: Add a kref c... |
3128 |
tty_kref_put(tty); |
24ec839c4 [PATCH] tty: ->si... |
3129 |
} |
24ec839c4 [PATCH] tty: ->si... |
3130 |
|
47f86834b redo locking of t... |
3131 |
/* Called under the sighand lock */ |
2a65f1d9f tty: simplify cal... |
3132 |
static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) |
24ec839c4 [PATCH] tty: ->si... |
3133 3134 |
{ if (tty) { |
47f86834b redo locking of t... |
3135 3136 3137 |
unsigned long flags; /* We should not have a session or pgrp to put here but.... */ spin_lock_irqsave(&tty->ctrl_lock, flags); |
d9c1e9a8f [PATCH] tty: Fix ... |
3138 3139 |
put_pid(tty->session); put_pid(tty->pgrp); |
ab521dc0f [PATCH] tty: upda... |
3140 |
tty->pgrp = get_pid(task_pgrp(tsk)); |
47f86834b redo locking of t... |
3141 3142 |
spin_unlock_irqrestore(&tty->ctrl_lock, flags); tty->session = get_pid(task_session(tsk)); |
9c9f4ded9 tty: Add a kref c... |
3143 3144 3145 3146 3147 |
if (tsk->signal->tty) { printk(KERN_DEBUG "tty not NULL!! "); tty_kref_put(tsk->signal->tty); } |
24ec839c4 [PATCH] tty: ->si... |
3148 |
} |
2a65f1d9f tty: simplify cal... |
3149 |
put_pid(tsk->signal->tty_old_pgrp); |
9c9f4ded9 tty: Add a kref c... |
3150 |
tsk->signal->tty = tty_kref_get(tty); |
ab521dc0f [PATCH] tty: upda... |
3151 |
tsk->signal->tty_old_pgrp = NULL; |
24ec839c4 [PATCH] tty: ->si... |
3152 |
} |
98a27ba48 tty: introduce no... |
3153 |
static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) |
24ec839c4 [PATCH] tty: ->si... |
3154 3155 |
{ spin_lock_irq(&tsk->sighand->siglock); |
2a65f1d9f tty: simplify cal... |
3156 |
__proc_set_tty(tsk, tty); |
24ec839c4 [PATCH] tty: ->si... |
3157 3158 3159 3160 3161 3162 |
spin_unlock_irq(&tsk->sighand->siglock); } struct tty_struct *get_current_tty(void) { struct tty_struct *tty; |
934e6ebf9 tty: Redo current... |
3163 3164 3165 |
unsigned long flags; spin_lock_irqsave(¤t->sighand->siglock, flags); |
452a00d2e tty: Make get_cur... |
3166 |
tty = tty_kref_get(current->signal->tty); |
934e6ebf9 tty: Redo current... |
3167 |
spin_unlock_irqrestore(¤t->sighand->siglock, flags); |
24ec839c4 [PATCH] tty: ->si... |
3168 3169 |
return tty; } |
a311f7432 [PATCH] tty: expo... |
3170 |
EXPORT_SYMBOL_GPL(get_current_tty); |
1da177e4c Linux-2.6.12-rc2 |
3171 |
|
d81ed1030 tty: Remove more ... |
3172 3173 3174 3175 |
void tty_default_fops(struct file_operations *fops) { *fops = tty_fops; } |
1da177e4c Linux-2.6.12-rc2 |
3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 |
/* * Initialize the console device. This is called *early*, so * we can't necessarily depend on lots of kernel help here. * Just do some early initializations, and do the complex setup * later. */ void __init console_init(void) { initcall_t *call; /* Setup the default TTY line discipline. */ |
01e1abb2c tty: Split ldisc ... |
3187 |
tty_ldisc_begin(); |
1da177e4c Linux-2.6.12-rc2 |
3188 3189 |
/* |
37bdfb074 tty_io: drag scre... |
3190 |
* set up the console device so that later boot sequences can |
1da177e4c Linux-2.6.12-rc2 |
3191 3192 |
* inform about problems etc.. */ |
1da177e4c Linux-2.6.12-rc2 |
3193 3194 3195 3196 3197 3198 |
call = __con_initcall_start; while (call < __con_initcall_end) { (*call)(); call++; } } |
2c9ede55e switch device_get... |
3199 |
static char *tty_devnode(struct device *dev, umode_t *mode) |
e454cea20 Driver-Core: exte... |
3200 3201 3202 3203 3204 3205 3206 3207 |
{ if (!mode) return NULL; if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) || dev->devt == MKDEV(TTYAUX_MAJOR, 2)) *mode = 0666; return NULL; } |
1da177e4c Linux-2.6.12-rc2 |
3208 3209 |
static int __init tty_class_init(void) { |
7fe845d11 [PATCH] tty: move... |
3210 |
tty_class = class_create(THIS_MODULE, "tty"); |
1da177e4c Linux-2.6.12-rc2 |
3211 3212 |
if (IS_ERR(tty_class)) return PTR_ERR(tty_class); |
e454cea20 Driver-Core: exte... |
3213 |
tty_class->devnode = tty_devnode; |
1da177e4c Linux-2.6.12-rc2 |
3214 3215 3216 3217 3218 3219 |
return 0; } postcore_initcall(tty_class_init); /* 3/2004 jmc: why do these devices exist? */ |
1da177e4c Linux-2.6.12-rc2 |
3220 |
static struct cdev tty_cdev, console_cdev; |
1da177e4c Linux-2.6.12-rc2 |
3221 |
|
fbc92a345 tty: add 'active'... |
3222 3223 3224 3225 3226 3227 3228 |
static ssize_t show_cons_active(struct device *dev, struct device_attribute *attr, char *buf) { struct console *cs[16]; int i = 0; struct console *c; ssize_t count = 0; |
ac751efa6 console: rename a... |
3229 |
console_lock(); |
a2a6a822a tty: use for_each... |
3230 |
for_each_console(c) { |
fbc92a345 tty: add 'active'... |
3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 |
if (!c->device) continue; if (!c->write) continue; if ((c->flags & CON_ENABLED) == 0) continue; cs[i++] = c; if (i >= ARRAY_SIZE(cs)) break; } while (i--) count += sprintf(buf + count, "%s%d%c", cs[i]->name, cs[i]->index, i ? ' ':' '); |
ac751efa6 console: rename a... |
3245 |
console_unlock(); |
fbc92a345 tty: add 'active'... |
3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 |
return count; } static DEVICE_ATTR(active, S_IRUGO, show_cons_active, NULL); static struct device *consdev; void console_sysfs_notify(void) { if (consdev) sysfs_notify(&consdev->kobj, NULL, "active"); } |
1da177e4c Linux-2.6.12-rc2 |
3258 3259 3260 3261 |
/* * Ok, now we can initialize the rest of the tty devices and can count * on memory allocations, interrupts etc.. */ |
31d1d48e1 Fix init ordering... |
3262 |
int __init tty_init(void) |
1da177e4c Linux-2.6.12-rc2 |
3263 3264 3265 3266 3267 3268 |
{ cdev_init(&tty_cdev, &tty_fops); if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) panic("Couldn't register /dev/tty driver "); |
fbc92a345 tty: add 'active'... |
3269 |
device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); |
1da177e4c Linux-2.6.12-rc2 |
3270 3271 3272 3273 3274 3275 |
cdev_init(&console_cdev, &console_fops); if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) panic("Couldn't register /dev/console driver "); |
fbc92a345 tty: add 'active'... |
3276 |
consdev = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, |
47aa5793f device create: ch... |
3277 |
"console"); |
fbc92a345 tty: add 'active'... |
3278 3279 3280 |
if (IS_ERR(consdev)) consdev = NULL; else |
a2a6a822a tty: use for_each... |
3281 |
WARN_ON(device_create_file(consdev, &dev_attr_active) < 0); |
1da177e4c Linux-2.6.12-rc2 |
3282 |
|
1da177e4c Linux-2.6.12-rc2 |
3283 |
#ifdef CONFIG_VT |
d81ed1030 tty: Remove more ... |
3284 |
vty_init(&console_fops); |
1da177e4c Linux-2.6.12-rc2 |
3285 3286 3287 |
#endif return 0; } |
31d1d48e1 Fix init ordering... |
3288 |