blob: dc184d4b5638ef53403e59e429a570acfa4c2f64 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/char/tty_io.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7/*
8 * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
9 * or rs-channels. It also implements echoing, cooked mode etc.
10 *
11 * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
12 *
13 * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the
14 * tty_struct and tty_queue structures. Previously there was an array
15 * of 256 tty_struct's which was statically allocated, and the
16 * tty_queue structures were allocated at boot time. Both are now
17 * dynamically allocated only when the tty is open.
18 *
19 * Also restructured routines so that there is more of a separation
20 * between the high-level tty routines (tty_io.c and tty_ioctl.c) and
21 * the low-level tty routines (serial.c, pty.c, console.c). This
Alan Cox37bdfb02008-02-08 04:18:47 -080022 * makes for cleaner and more compact code. -TYT, 9/17/92
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 *
24 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
25 * which can be dynamically activated and de-activated by the line
26 * discipline handling modules (like SLIP).
27 *
28 * NOTE: pay no attention to the line discipline code (yet); its
29 * interface is still subject to change in this version...
30 * -- TYT, 1/31/92
31 *
32 * Added functionality to the OPOST tty handling. No delays, but all
33 * other bits should be there.
34 * -- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993.
35 *
36 * Rewrote canonical mode and added more termios flags.
37 * -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94
38 *
39 * Reorganized FASYNC support so mouse code can share it.
40 * -- ctm@ardi.com, 9Sep95
41 *
42 * New TIOCLINUX variants added.
43 * -- mj@k332.feld.cvut.cz, 19-Nov-95
Alan Cox37bdfb02008-02-08 04:18:47 -080044 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 * Restrict vt switching via ioctl()
46 * -- grif@cs.ucr.edu, 5-Dec-95
47 *
48 * Move console and virtual terminal code to more appropriate files,
49 * implement CONFIG_VT and generalize console device interface.
50 * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97
51 *
Alan Coxd81ed102008-10-13 10:41:42 +010052 * Rewrote tty_init_dev and tty_release_dev to eliminate races.
Linus Torvalds1da177e2005-04-16 15:20:36 -070053 * -- Bill Hawes <whawes@star.net>, June 97
54 *
55 * Added devfs support.
56 * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 13-Jan-1998
57 *
58 * Added support for a Unix98-style ptmx device.
59 * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
60 *
61 * Reduced memory usage for older ARM systems
62 * -- Russell King <rmk@arm.linux.org.uk>
63 *
64 * Move do_SAK() into process context. Less stack use in devfs functions.
Alan Cox37bdfb02008-02-08 04:18:47 -080065 * alloc_tty_struct() always uses kmalloc()
66 * -- Andrew Morton <andrewm@uow.edu.eu> 17Mar01
Linus Torvalds1da177e2005-04-16 15:20:36 -070067 */
68
Linus Torvalds1da177e2005-04-16 15:20:36 -070069#include <linux/types.h>
70#include <linux/major.h>
71#include <linux/errno.h>
72#include <linux/signal.h>
73#include <linux/fcntl.h>
74#include <linux/sched.h>
75#include <linux/interrupt.h>
76#include <linux/tty.h>
77#include <linux/tty_driver.h>
78#include <linux/tty_flip.h>
79#include <linux/devpts_fs.h>
80#include <linux/file.h>
Al Viro9f3acc32008-04-24 07:44:08 -040081#include <linux/fdtable.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070082#include <linux/console.h>
83#include <linux/timer.h>
84#include <linux/ctype.h>
85#include <linux/kd.h>
86#include <linux/mm.h>
87#include <linux/string.h>
88#include <linux/slab.h>
89#include <linux/poll.h>
90#include <linux/proc_fs.h>
91#include <linux/init.h>
92#include <linux/module.h>
93#include <linux/smp_lock.h>
94#include <linux/device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070095#include <linux/wait.h>
96#include <linux/bitops.h>
Domen Puncerb20f3ae2005-06-25 14:58:42 -070097#include <linux/delay.h>
Alan Coxa352def2008-07-16 21:53:12 +010098#include <linux/seq_file.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Alan Coxa352def2008-07-16 21:53:12 +0100100#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101#include <asm/system.h>
102
103#include <linux/kbd_kern.h>
104#include <linux/vt_kern.h>
105#include <linux/selection.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
107#include <linux/kmod.h>
Pavel Emelyanovb4888932007-10-18 23:40:14 -0700108#include <linux/nsproxy.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
110#undef TTY_DEBUG_HANGUP
111
112#define TTY_PARANOIA_CHECK 1
113#define CHECK_TTY_COUNT 1
114
Alan Coxedc6afc2006-12-08 02:38:44 -0800115struct ktermios tty_std_termios = { /* for the benefit of tty drivers */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 .c_iflag = ICRNL | IXON,
117 .c_oflag = OPOST | ONLCR,
118 .c_cflag = B38400 | CS8 | CREAD | HUPCL,
119 .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
120 ECHOCTL | ECHOKE | IEXTEN,
Alan Coxedc6afc2006-12-08 02:38:44 -0800121 .c_cc = INIT_C_CC,
122 .c_ispeed = 38400,
123 .c_ospeed = 38400
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124};
125
126EXPORT_SYMBOL(tty_std_termios);
127
128/* This list gets poked at by procfs and various bits of boot up code. This
129 could do with some rationalisation such as pulling the tty proc function
130 into this file */
Alan Cox37bdfb02008-02-08 04:18:47 -0800131
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132LIST_HEAD(tty_drivers); /* linked list of tty drivers */
133
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800134/* Mutex to protect creating and releasing a tty. This is shared with
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 vt.c for deeply disgusting hack reasons */
Ingo Molnar70522e12006-03-23 03:00:31 -0800136DEFINE_MUTEX(tty_mutex);
Alan Coxde2a84f2006-09-29 02:00:57 -0700137EXPORT_SYMBOL(tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
Nick Pigginee2ffa02010-08-18 04:37:35 +1000139/* Spinlock to protect the tty->tty_files list */
140DEFINE_SPINLOCK(tty_files_lock);
141
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
143static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
Alan Cox37bdfb02008-02-08 04:18:47 -0800144ssize_t redirected_tty_write(struct file *, const char __user *,
145 size_t, loff_t *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146static unsigned int tty_poll(struct file *, poll_table *);
147static int tty_open(struct inode *, struct file *);
Alan Cox04f378b2008-04-30 00:53:29 -0700148long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700149#ifdef CONFIG_COMPAT
Alan Cox37bdfb02008-02-08 04:18:47 -0800150static long tty_compat_ioctl(struct file *file, unsigned int cmd,
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700151 unsigned long arg);
152#else
153#define tty_compat_ioctl NULL
154#endif
Arnd Bergmannec79d602010-06-01 22:53:01 +0200155static int __tty_fasync(int fd, struct file *filp, int on);
Alan Cox37bdfb02008-02-08 04:18:47 -0800156static int tty_fasync(int fd, struct file *filp, int on);
Christoph Hellwigd5698c22007-02-10 01:46:46 -0800157static void release_tty(struct tty_struct *tty, int idx);
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -0700158static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
Eric W. Biederman98a27ba2007-05-08 00:26:56 -0700159static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160
Alan Coxaf9b8972006-08-27 01:24:01 -0700161/**
162 * alloc_tty_struct - allocate a tty object
163 *
164 * Return a new empty tty structure. The data fields have not
165 * been initialized in any way but has been zeroed
166 *
167 * Locking: none
Alan Coxaf9b8972006-08-27 01:24:01 -0700168 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169
Alan Coxbf970ee2008-10-13 10:42:39 +0100170struct tty_struct *alloc_tty_struct(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171{
Alan Cox1266b1e2006-09-29 02:00:40 -0700172 return kzalloc(sizeof(struct tty_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173}
174
Alan Coxaf9b8972006-08-27 01:24:01 -0700175/**
176 * free_tty_struct - free a disused tty
177 * @tty: tty struct to free
178 *
179 * Free the write buffers, tty queue and tty memory itself.
180 *
181 * Locking: none. Must be called after tty is definitely unused
182 */
183
Alan Coxbf970ee2008-10-13 10:42:39 +0100184void free_tty_struct(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185{
Dmitry Eremin-Solenikov30004ac2010-08-09 18:22:49 +0400186 if (tty->dev)
187 put_device(tty->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 kfree(tty->write_buf);
Alan Cox33f0f882006-01-09 20:54:13 -0800189 tty_buffer_free_all(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 kfree(tty);
191}
192
Nick Piggind996b622010-08-18 04:37:36 +1000193static inline struct tty_struct *file_tty(struct file *file)
194{
195 return ((struct tty_file_private *)file->private_data)->tty;
196}
197
198/* Associate a new file with the tty structure */
199void tty_add_file(struct tty_struct *tty, struct file *file)
200{
201 struct tty_file_private *priv;
202
203 /* XXX: must implement proper error handling in callers */
204 priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL);
205
206 priv->tty = tty;
207 priv->file = file;
208 file->private_data = priv;
209
210 spin_lock(&tty_files_lock);
211 list_add(&priv->list, &tty->tty_files);
212 spin_unlock(&tty_files_lock);
213}
214
215/* Delete file from its tty */
216void tty_del_file(struct file *file)
217{
218 struct tty_file_private *priv = file->private_data;
219
220 spin_lock(&tty_files_lock);
221 list_del(&priv->list);
222 spin_unlock(&tty_files_lock);
223 file->private_data = NULL;
224 kfree(priv);
225}
226
227
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)
229
Alan Coxaf9b8972006-08-27 01:24:01 -0700230/**
231 * tty_name - return tty naming
232 * @tty: tty structure
233 * @buf: buffer for output
234 *
235 * Convert a tty structure into a name. The name reflects the kernel
236 * naming policy and if udev is in use may not reflect user space
237 *
238 * Locking: none
239 */
240
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241char *tty_name(struct tty_struct *tty, char *buf)
242{
243 if (!tty) /* Hmm. NULL pointer. That's fun. */
244 strcpy(buf, "NULL tty");
245 else
246 strcpy(buf, tty->name);
247 return buf;
248}
249
250EXPORT_SYMBOL(tty_name);
251
Andrew Mortond769a662005-05-05 16:15:50 -0700252int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 const char *routine)
254{
255#ifdef TTY_PARANOIA_CHECK
256 if (!tty) {
257 printk(KERN_WARNING
258 "null TTY for (%d:%d) in %s\n",
259 imajor(inode), iminor(inode), routine);
260 return 1;
261 }
262 if (tty->magic != TTY_MAGIC) {
263 printk(KERN_WARNING
264 "bad magic number for tty struct (%d:%d) in %s\n",
265 imajor(inode), iminor(inode), routine);
266 return 1;
267 }
268#endif
269 return 0;
270}
271
272static int check_tty_count(struct tty_struct *tty, const char *routine)
273{
274#ifdef CHECK_TTY_COUNT
275 struct list_head *p;
276 int count = 0;
Alan Cox37bdfb02008-02-08 04:18:47 -0800277
Nick Pigginee2ffa02010-08-18 04:37:35 +1000278 spin_lock(&tty_files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 list_for_each(p, &tty->tty_files) {
280 count++;
281 }
Nick Pigginee2ffa02010-08-18 04:37:35 +1000282 spin_unlock(&tty_files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
284 tty->driver->subtype == PTY_TYPE_SLAVE &&
285 tty->link && tty->link->count)
286 count++;
287 if (tty->count != count) {
288 printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) "
289 "!= #fd's(%d) in %s\n",
290 tty->name, tty->count, count, routine);
291 return count;
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800292 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293#endif
294 return 0;
295}
296
Alan Coxaf9b8972006-08-27 01:24:01 -0700297/**
Alan Coxaf9b8972006-08-27 01:24:01 -0700298 * get_tty_driver - find device of a tty
299 * @dev_t: device identifier
300 * @index: returns the index of the tty
301 *
302 * This routine returns a tty driver structure, given a device number
303 * and also passes back the index number.
304 *
305 * Locking: caller must hold tty_mutex
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 */
Alan Coxaf9b8972006-08-27 01:24:01 -0700307
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308static struct tty_driver *get_tty_driver(dev_t device, int *index)
309{
310 struct tty_driver *p;
311
312 list_for_each_entry(p, &tty_drivers, tty_drivers) {
313 dev_t base = MKDEV(p->major, p->minor_start);
314 if (device < base || device >= base + p->num)
315 continue;
316 *index = device - base;
Alan Cox7d7b93c2008-10-13 10:42:09 +0100317 return tty_driver_kref_get(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 }
319 return NULL;
320}
321
Jason Wesself2d937f2008-04-17 20:05:37 +0200322#ifdef CONFIG_CONSOLE_POLL
323
324/**
325 * tty_find_polling_driver - find device of a polled tty
326 * @name: name string to match
327 * @line: pointer to resulting tty line nr
328 *
329 * This routine returns a tty driver structure, given a name
330 * and the condition that the tty driver is capable of polled
331 * operation.
332 */
333struct tty_driver *tty_find_polling_driver(char *name, int *line)
334{
335 struct tty_driver *p, *res = NULL;
336 int tty_line = 0;
Jason Wessel0dca0fd2008-09-26 10:36:42 -0500337 int len;
Alan Cox5f0878a2009-06-11 12:46:41 +0100338 char *str, *stp;
Jason Wesself2d937f2008-04-17 20:05:37 +0200339
Jason Wessel0dca0fd2008-09-26 10:36:42 -0500340 for (str = name; *str; str++)
341 if ((*str >= '0' && *str <= '9') || *str == ',')
342 break;
343 if (!*str)
344 return NULL;
345
346 len = str - name;
347 tty_line = simple_strtoul(str, &str, 10);
348
Jason Wesself2d937f2008-04-17 20:05:37 +0200349 mutex_lock(&tty_mutex);
350 /* Search through the tty devices to look for a match */
351 list_for_each_entry(p, &tty_drivers, tty_drivers) {
Jason Wessel0dca0fd2008-09-26 10:36:42 -0500352 if (strncmp(name, p->name, len) != 0)
353 continue;
Alan Cox5f0878a2009-06-11 12:46:41 +0100354 stp = str;
355 if (*stp == ',')
356 stp++;
357 if (*stp == '\0')
358 stp = NULL;
Jason Wesself2d937f2008-04-17 20:05:37 +0200359
Nathael Pajani6eb68d62010-09-02 16:06:16 +0200360 if (tty_line >= 0 && tty_line < p->num && p->ops &&
Alan Cox5f0878a2009-06-11 12:46:41 +0100361 p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
Alan Cox7d7b93c2008-10-13 10:42:09 +0100362 res = tty_driver_kref_get(p);
Jason Wesself2d937f2008-04-17 20:05:37 +0200363 *line = tty_line;
364 break;
365 }
366 }
367 mutex_unlock(&tty_mutex);
368
369 return res;
370}
371EXPORT_SYMBOL_GPL(tty_find_polling_driver);
372#endif
373
Alan Coxaf9b8972006-08-27 01:24:01 -0700374/**
375 * tty_check_change - check for POSIX terminal changes
376 * @tty: tty to check
377 *
378 * If we try to write to, or set the state of, a terminal and we're
379 * not in the foreground, send a SIGTTOU. If the signal is blocked or
380 * ignored, go ahead and perform the operation. (POSIX 7.2)
381 *
Alan Cox978e5952008-04-30 00:53:59 -0700382 * Locking: ctrl_lock
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 */
Alan Coxaf9b8972006-08-27 01:24:01 -0700384
Alan Cox37bdfb02008-02-08 04:18:47 -0800385int tty_check_change(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386{
Alan Cox47f86832008-04-30 00:53:30 -0700387 unsigned long flags;
388 int ret = 0;
389
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 if (current->signal->tty != tty)
391 return 0;
Alan Cox47f86832008-04-30 00:53:30 -0700392
393 spin_lock_irqsave(&tty->ctrl_lock, flags);
394
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800395 if (!tty->pgrp) {
396 printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
Andrew Morton9ffee4c2008-05-14 16:05:58 -0700397 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 }
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800399 if (task_pgrp(current) == tty->pgrp)
Andrew Morton9ffee4c2008-05-14 16:05:58 -0700400 goto out_unlock;
401 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 if (is_ignored(SIGTTOU))
Alan Cox47f86832008-04-30 00:53:30 -0700403 goto out;
404 if (is_current_pgrp_orphaned()) {
405 ret = -EIO;
406 goto out;
407 }
Oleg Nesterov040b6362007-06-01 00:46:53 -0700408 kill_pgrp(task_pgrp(current), SIGTTOU, 1);
409 set_thread_flag(TIF_SIGPENDING);
Alan Cox47f86832008-04-30 00:53:30 -0700410 ret = -ERESTARTSYS;
411out:
Andrew Morton9ffee4c2008-05-14 16:05:58 -0700412 return ret;
413out_unlock:
Alan Cox47f86832008-04-30 00:53:30 -0700414 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
415 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416}
417
418EXPORT_SYMBOL(tty_check_change);
419
Alan Cox37bdfb02008-02-08 04:18:47 -0800420static ssize_t hung_up_tty_read(struct file *file, char __user *buf,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 size_t count, loff_t *ppos)
422{
423 return 0;
424}
425
Alan Cox37bdfb02008-02-08 04:18:47 -0800426static ssize_t hung_up_tty_write(struct file *file, const char __user *buf,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 size_t count, loff_t *ppos)
428{
429 return -EIO;
430}
431
432/* No kernel lock held - none needed ;) */
Alan Cox37bdfb02008-02-08 04:18:47 -0800433static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434{
435 return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
436}
437
Alan Cox04f378b2008-04-30 00:53:29 -0700438static long hung_up_tty_ioctl(struct file *file, unsigned int cmd,
439 unsigned long arg)
Paul Fulghum38ad2ed2007-06-16 10:15:55 -0700440{
441 return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
442}
443
Alan Cox37bdfb02008-02-08 04:18:47 -0800444static long hung_up_tty_compat_ioctl(struct file *file,
Paul Fulghum38ad2ed2007-06-16 10:15:55 -0700445 unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446{
447 return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
448}
449
Arjan van de Ven62322d22006-07-03 00:24:21 -0700450static const struct file_operations tty_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 .llseek = no_llseek,
452 .read = tty_read,
453 .write = tty_write,
454 .poll = tty_poll,
Alan Cox04f378b2008-04-30 00:53:29 -0700455 .unlocked_ioctl = tty_ioctl,
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700456 .compat_ioctl = tty_compat_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 .open = tty_open,
458 .release = tty_release,
459 .fasync = tty_fasync,
460};
461
Arjan van de Ven62322d22006-07-03 00:24:21 -0700462static const struct file_operations console_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 .llseek = no_llseek,
464 .read = tty_read,
465 .write = redirected_tty_write,
466 .poll = tty_poll,
Alan Cox04f378b2008-04-30 00:53:29 -0700467 .unlocked_ioctl = tty_ioctl,
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700468 .compat_ioctl = tty_compat_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 .open = tty_open,
470 .release = tty_release,
471 .fasync = tty_fasync,
472};
473
Arjan van de Ven62322d22006-07-03 00:24:21 -0700474static const struct file_operations hung_up_tty_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 .llseek = no_llseek,
476 .read = hung_up_tty_read,
477 .write = hung_up_tty_write,
478 .poll = hung_up_tty_poll,
Alan Cox04f378b2008-04-30 00:53:29 -0700479 .unlocked_ioctl = hung_up_tty_ioctl,
Paul Fulghum38ad2ed2007-06-16 10:15:55 -0700480 .compat_ioctl = hung_up_tty_compat_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 .release = tty_release,
482};
483
484static DEFINE_SPINLOCK(redirect_lock);
485static struct file *redirect;
486
487/**
488 * tty_wakeup - request more data
489 * @tty: terminal
490 *
491 * Internal and external helper for wakeups of tty. This function
492 * informs the line discipline if present that the driver is ready
493 * to receive more output data.
494 */
Alan Cox37bdfb02008-02-08 04:18:47 -0800495
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496void tty_wakeup(struct tty_struct *tty)
497{
498 struct tty_ldisc *ld;
Alan Cox37bdfb02008-02-08 04:18:47 -0800499
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
501 ld = tty_ldisc_ref(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -0800502 if (ld) {
Alan Coxa352def2008-07-16 21:53:12 +0100503 if (ld->ops->write_wakeup)
504 ld->ops->write_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 tty_ldisc_deref(ld);
506 }
507 }
Davide Libenzi4b194492009-03-31 15:24:24 -0700508 wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509}
510
511EXPORT_SYMBOL_GPL(tty_wakeup);
512
513/**
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200514 * __tty_hangup - actual handler for hangup events
David Howells65f27f32006-11-22 14:55:48 +0000515 * @work: tty device
Alan Coxaf9b8972006-08-27 01:24:01 -0700516 *
Alan Cox1bad8792008-07-22 23:38:04 +0100517 * This can be called by the "eventd" kernel thread. That is process
Alan Coxaf9b8972006-08-27 01:24:01 -0700518 * synchronous but doesn't hold any locks, so we need to make sure we
519 * have the appropriate locks for what we're doing.
520 *
521 * The hangup event clears any pending redirections onto the hung up
522 * device. It ensures future writes will error and it does the needed
523 * line discipline hangup and signal delivery. The tty object itself
524 * remains intact.
525 *
526 * Locking:
Arnd Bergmannec79d602010-06-01 22:53:01 +0200527 * BTM
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800528 * redirect lock for undoing redirection
529 * file list lock for manipulating list of ttys
530 * tty_ldisc_lock from called functions
531 * termios_mutex resetting termios data
532 * tasklist_lock to walk task list for hangup event
533 * ->siglock to protect ->signal/->sighand
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 */
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200535void __tty_hangup(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536{
Alan Cox37bdfb02008-02-08 04:18:47 -0800537 struct file *cons_filp = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 struct file *filp, *f = NULL;
539 struct task_struct *p;
Nick Piggind996b622010-08-18 04:37:36 +1000540 struct tty_file_private *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 int closecount = 0, n;
Alan Cox47f86832008-04-30 00:53:30 -0700542 unsigned long flags;
Alan Cox9c9f4de2008-10-13 10:37:26 +0100543 int refs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
545 if (!tty)
546 return;
547
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
549 spin_lock(&redirect_lock);
Nick Piggind996b622010-08-18 04:37:36 +1000550 if (redirect && file_tty(redirect) == tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 f = redirect;
552 redirect = NULL;
553 }
554 spin_unlock(&redirect_lock);
Alan Cox37bdfb02008-02-08 04:18:47 -0800555
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200556 tty_lock();
557
Arnd Bergmannec79d602010-06-01 22:53:01 +0200558 /* inuse_filps is protected by the single tty lock,
559 this really needs to change if we want to flush the
560 workqueue with the lock held */
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200561 check_tty_count(tty, "tty_hangup");
Alan Cox36ba7822009-11-30 13:18:51 +0000562
Nick Pigginee2ffa02010-08-18 04:37:35 +1000563 spin_lock(&tty_files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 /* This breaks for file handles being sent over AF_UNIX sockets ? */
Nick Piggind996b622010-08-18 04:37:36 +1000565 list_for_each_entry(priv, &tty->tty_files, list) {
566 filp = priv->file;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 if (filp->f_op->write == redirected_tty_write)
568 cons_filp = filp;
569 if (filp->f_op->write != tty_write)
570 continue;
571 closecount++;
Arnd Bergmannec79d602010-06-01 22:53:01 +0200572 __tty_fasync(-1, filp, 0); /* can't block */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 filp->f_op = &hung_up_tty_fops;
574 }
Nick Pigginee2ffa02010-08-18 04:37:35 +1000575 spin_unlock(&tty_files_lock);
Alan Cox37bdfb02008-02-08 04:18:47 -0800576
Alan Coxc65c9bc2009-06-11 12:50:12 +0100577 tty_ldisc_hangup(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -0800578
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 read_lock(&tasklist_lock);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800580 if (tty->session) {
581 do_each_pid_task(tty->session, PIDTYPE_SID, p) {
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800582 spin_lock_irq(&p->sighand->siglock);
Alan Cox9c9f4de2008-10-13 10:37:26 +0100583 if (p->signal->tty == tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 p->signal->tty = NULL;
Alan Cox9c9f4de2008-10-13 10:37:26 +0100585 /* We defer the dereferences outside fo
586 the tasklist lock */
587 refs++;
588 }
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800589 if (!p->signal->leader) {
590 spin_unlock_irq(&p->sighand->siglock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 continue;
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800592 }
593 __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
594 __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800595 put_pid(p->signal->tty_old_pgrp); /* A noop */
Alan Cox47f86832008-04-30 00:53:30 -0700596 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800597 if (tty->pgrp)
598 p->signal->tty_old_pgrp = get_pid(tty->pgrp);
Alan Cox47f86832008-04-30 00:53:30 -0700599 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800600 spin_unlock_irq(&p->sighand->siglock);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800601 } while_each_pid_task(tty->session, PIDTYPE_SID, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 }
603 read_unlock(&tasklist_lock);
604
Alan Cox47f86832008-04-30 00:53:30 -0700605 spin_lock_irqsave(&tty->ctrl_lock, flags);
Alan Coxc65c9bc2009-06-11 12:50:12 +0100606 clear_bit(TTY_THROTTLED, &tty->flags);
607 clear_bit(TTY_PUSH, &tty->flags);
608 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
Eric W. Biedermand9c1e9a2007-03-18 12:45:44 -0600609 put_pid(tty->session);
610 put_pid(tty->pgrp);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800611 tty->session = NULL;
612 tty->pgrp = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 tty->ctrl_status = 0;
Alan Coxc65c9bc2009-06-11 12:50:12 +0100614 set_bit(TTY_HUPPED, &tty->flags);
Alan Cox47f86832008-04-30 00:53:30 -0700615 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
616
Alan Cox9c9f4de2008-10-13 10:37:26 +0100617 /* Account for the p->signal references we killed */
618 while (refs--)
619 tty_kref_put(tty);
620
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 /*
Alan Cox37bdfb02008-02-08 04:18:47 -0800622 * If one of the devices matches a console pointer, we
623 * cannot just call hangup() because that will cause
624 * tty->count and state->count to go out of sync.
625 * So we just call close() the right number of times.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 */
627 if (cons_filp) {
Alan Coxf34d7a52008-04-30 00:54:13 -0700628 if (tty->ops->close)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 for (n = 0; n < closecount; n++)
Alan Coxf34d7a52008-04-30 00:54:13 -0700630 tty->ops->close(tty, cons_filp);
631 } else if (tty->ops->hangup)
632 (tty->ops->hangup)(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -0800633 /*
634 * We don't want to have driver/ldisc interactions beyond
635 * the ones we did here. The driver layer expects no
636 * calls after ->hangup() from the ldisc side. However we
637 * can't yet guarantee all that.
638 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 set_bit(TTY_HUPPED, &tty->flags);
Alan Coxc65c9bc2009-06-11 12:50:12 +0100640 tty_ldisc_enable(tty);
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200641
642 tty_unlock();
643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 if (f)
645 fput(f);
646}
647
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200648static void do_tty_hangup(struct work_struct *work)
649{
650 struct tty_struct *tty =
651 container_of(work, struct tty_struct, hangup_work);
652
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200653 __tty_hangup(tty);
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200654}
655
Alan Coxaf9b8972006-08-27 01:24:01 -0700656/**
657 * tty_hangup - trigger a hangup event
658 * @tty: tty to hangup
659 *
660 * A carrier loss (virtual or otherwise) has occurred on this like
661 * schedule a hangup sequence to run after this event.
662 */
663
Alan Cox37bdfb02008-02-08 04:18:47 -0800664void tty_hangup(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665{
666#ifdef TTY_DEBUG_HANGUP
667 char buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf));
669#endif
670 schedule_work(&tty->hangup_work);
671}
672
673EXPORT_SYMBOL(tty_hangup);
674
Alan Coxaf9b8972006-08-27 01:24:01 -0700675/**
676 * tty_vhangup - process vhangup
677 * @tty: tty to hangup
678 *
679 * The user has asked via system call for the terminal to be hung up.
680 * We do this synchronously so that when the syscall returns the process
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +0200681 * is complete. That guarantee is necessary for security reasons.
Alan Coxaf9b8972006-08-27 01:24:01 -0700682 */
683
Alan Cox37bdfb02008-02-08 04:18:47 -0800684void tty_vhangup(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685{
686#ifdef TTY_DEBUG_HANGUP
687 char buf[64];
688
689 printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
690#endif
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200691 __tty_hangup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692}
Alan Cox37bdfb02008-02-08 04:18:47 -0800693
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694EXPORT_SYMBOL(tty_vhangup);
695
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200696
Alan Coxaf9b8972006-08-27 01:24:01 -0700697/**
Alan Cox2cb59982008-10-13 10:40:30 +0100698 * tty_vhangup_self - process vhangup for own ctty
699 *
700 * Perform a vhangup on the current controlling tty
701 */
702
703void tty_vhangup_self(void)
704{
705 struct tty_struct *tty;
706
Alan Cox2cb59982008-10-13 10:40:30 +0100707 tty = get_current_tty();
708 if (tty) {
709 tty_vhangup(tty);
710 tty_kref_put(tty);
711 }
Alan Cox2cb59982008-10-13 10:40:30 +0100712}
713
714/**
Alan Coxaf9b8972006-08-27 01:24:01 -0700715 * tty_hung_up_p - was tty hung up
716 * @filp: file pointer of tty
717 *
718 * Return true if the tty has been subject to a vhangup or a carrier
719 * loss
720 */
721
Alan Cox37bdfb02008-02-08 04:18:47 -0800722int tty_hung_up_p(struct file *filp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723{
724 return (filp->f_op == &hung_up_tty_fops);
725}
726
727EXPORT_SYMBOL(tty_hung_up_p);
728
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800729static void session_clear_tty(struct pid *session)
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800730{
731 struct task_struct *p;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800732 do_each_pid_task(session, PIDTYPE_SID, p) {
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800733 proc_clear_tty(p);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800734 } while_each_pid_task(session, PIDTYPE_SID, p);
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800735}
736
Alan Coxaf9b8972006-08-27 01:24:01 -0700737/**
738 * disassociate_ctty - disconnect controlling tty
739 * @on_exit: true if exiting so need to "hang up" the session
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 *
Alan Coxaf9b8972006-08-27 01:24:01 -0700741 * This function is typically called only by the session leader, when
742 * it wants to disassociate itself from its controlling tty.
743 *
744 * It performs the following functions:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 * (1) Sends a SIGHUP and SIGCONT to the foreground process group
746 * (2) Clears the tty from being controlling the session
747 * (3) Clears the controlling tty for all processes in the
748 * session group.
749 *
Alan Coxaf9b8972006-08-27 01:24:01 -0700750 * The argument on_exit is set to 1 if called when a process is
751 * exiting; it is 0 if called by the ioctl TIOCNOTTY.
752 *
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800753 * Locking:
Arnd Bergmannec79d602010-06-01 22:53:01 +0200754 * BTM is taken for hysterical raisins, and held when
755 * called from no_tty().
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800756 * tty_mutex is taken to protect tty
757 * ->siglock is taken to protect ->signal/->sighand
758 * tasklist_lock is taken to walk process list for sessions
759 * ->siglock is taken to protect ->signal/->sighand
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 */
Alan Coxaf9b8972006-08-27 01:24:01 -0700761
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762void disassociate_ctty(int on_exit)
763{
764 struct tty_struct *tty;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800765 struct pid *tty_pgrp = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766
Alan Cox5ec93d12009-11-30 13:18:45 +0000767 if (!current->signal->leader)
768 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800770 tty = get_current_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 if (tty) {
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800772 tty_pgrp = get_pid(tty->pgrp);
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200773 if (on_exit) {
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200774 if (tty->driver->type != TTY_DRIVER_TYPE_PTY)
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200775 tty_vhangup(tty);
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200776 }
Alan Cox452a00d2008-10-13 10:39:13 +0100777 tty_kref_put(tty);
Eric W. Biederman680a9672007-02-12 00:52:52 -0800778 } else if (on_exit) {
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800779 struct pid *old_pgrp;
Eric W. Biederman680a9672007-02-12 00:52:52 -0800780 spin_lock_irq(&current->sighand->siglock);
781 old_pgrp = current->signal->tty_old_pgrp;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800782 current->signal->tty_old_pgrp = NULL;
Eric W. Biederman680a9672007-02-12 00:52:52 -0800783 spin_unlock_irq(&current->sighand->siglock);
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800784 if (old_pgrp) {
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800785 kill_pgrp(old_pgrp, SIGHUP, on_exit);
786 kill_pgrp(old_pgrp, SIGCONT, on_exit);
787 put_pid(old_pgrp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 return;
790 }
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800791 if (tty_pgrp) {
792 kill_pgrp(tty_pgrp, SIGHUP, on_exit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 if (!on_exit)
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800794 kill_pgrp(tty_pgrp, SIGCONT, on_exit);
795 put_pid(tty_pgrp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 }
797
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800798 spin_lock_irq(&current->sighand->siglock);
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -0700799 put_pid(current->signal->tty_old_pgrp);
Randy Dunlap23cac8d2007-02-20 13:58:05 -0800800 current->signal->tty_old_pgrp = NULL;
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800801 spin_unlock_irq(&current->sighand->siglock);
802
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800803 tty = get_current_tty();
804 if (tty) {
Alan Cox47f86832008-04-30 00:53:30 -0700805 unsigned long flags;
806 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800807 put_pid(tty->session);
808 put_pid(tty->pgrp);
809 tty->session = NULL;
810 tty->pgrp = NULL;
Alan Cox47f86832008-04-30 00:53:30 -0700811 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Alan Cox452a00d2008-10-13 10:39:13 +0100812 tty_kref_put(tty);
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800813 } else {
814#ifdef TTY_DEBUG_HANGUP
815 printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
816 " = NULL", tty);
817#endif
818 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819
820 /* Now clear signal->tty under the lock */
821 read_lock(&tasklist_lock);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800822 session_clear_tty(task_session(current));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824}
825
Eric W. Biederman98a27ba2007-05-08 00:26:56 -0700826/**
827 *
828 * no_tty - Ensure the current process does not have a controlling tty
829 */
830void no_tty(void)
831{
832 struct task_struct *tsk = current;
Arnd Bergmannec79d602010-06-01 22:53:01 +0200833 tty_lock();
Alan Cox5ec93d12009-11-30 13:18:45 +0000834 disassociate_ctty(0);
Arnd Bergmannec79d602010-06-01 22:53:01 +0200835 tty_unlock();
Eric W. Biederman98a27ba2007-05-08 00:26:56 -0700836 proc_clear_tty(tsk);
837}
838
Alan Coxaf9b8972006-08-27 01:24:01 -0700839
840/**
Robert P. J. Daybeb7dd82007-05-09 07:14:03 +0200841 * stop_tty - propagate flow control
Alan Coxaf9b8972006-08-27 01:24:01 -0700842 * @tty: tty to stop
843 *
844 * Perform flow control to the driver. For PTY/TTY pairs we
Robert P. J. Daybeb7dd82007-05-09 07:14:03 +0200845 * must also propagate the TIOCKPKT status. May be called
Alan Coxaf9b8972006-08-27 01:24:01 -0700846 * on an already stopped device and will not re-call the driver
847 * method.
848 *
849 * This functionality is used by both the line disciplines for
850 * halting incoming flow and by the driver. It may therefore be
851 * called from any context, may be under the tty atomic_write_lock
852 * but not always.
853 *
854 * Locking:
Alan Cox04f378b2008-04-30 00:53:29 -0700855 * Uses the tty control lock internally
Alan Coxaf9b8972006-08-27 01:24:01 -0700856 */
857
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858void stop_tty(struct tty_struct *tty)
859{
Alan Cox04f378b2008-04-30 00:53:29 -0700860 unsigned long flags;
861 spin_lock_irqsave(&tty->ctrl_lock, flags);
862 if (tty->stopped) {
863 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 return;
Alan Cox04f378b2008-04-30 00:53:29 -0700865 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 tty->stopped = 1;
867 if (tty->link && tty->link->packet) {
868 tty->ctrl_status &= ~TIOCPKT_START;
869 tty->ctrl_status |= TIOCPKT_STOP;
Davide Libenzi4b194492009-03-31 15:24:24 -0700870 wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 }
Alan Cox04f378b2008-04-30 00:53:29 -0700872 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Alan Coxf34d7a52008-04-30 00:54:13 -0700873 if (tty->ops->stop)
874 (tty->ops->stop)(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875}
876
877EXPORT_SYMBOL(stop_tty);
878
Alan Coxaf9b8972006-08-27 01:24:01 -0700879/**
Robert P. J. Daybeb7dd82007-05-09 07:14:03 +0200880 * start_tty - propagate flow control
Alan Coxaf9b8972006-08-27 01:24:01 -0700881 * @tty: tty to start
882 *
883 * Start a tty that has been stopped if at all possible. Perform
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +0200884 * any necessary wakeups and propagate the TIOCPKT status. If this
Alan Coxaf9b8972006-08-27 01:24:01 -0700885 * is the tty was previous stopped and is being started then the
886 * driver start method is invoked and the line discipline woken.
887 *
888 * Locking:
Alan Cox04f378b2008-04-30 00:53:29 -0700889 * ctrl_lock
Alan Coxaf9b8972006-08-27 01:24:01 -0700890 */
891
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892void start_tty(struct tty_struct *tty)
893{
Alan Cox04f378b2008-04-30 00:53:29 -0700894 unsigned long flags;
895 spin_lock_irqsave(&tty->ctrl_lock, flags);
896 if (!tty->stopped || tty->flow_stopped) {
897 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 return;
Alan Cox04f378b2008-04-30 00:53:29 -0700899 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 tty->stopped = 0;
901 if (tty->link && tty->link->packet) {
902 tty->ctrl_status &= ~TIOCPKT_STOP;
903 tty->ctrl_status |= TIOCPKT_START;
Davide Libenzi4b194492009-03-31 15:24:24 -0700904 wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 }
Alan Cox04f378b2008-04-30 00:53:29 -0700906 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Alan Coxf34d7a52008-04-30 00:54:13 -0700907 if (tty->ops->start)
908 (tty->ops->start)(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 /* If we have a running line discipline it may need kicking */
910 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911}
912
913EXPORT_SYMBOL(start_tty);
914
Alan Coxaf9b8972006-08-27 01:24:01 -0700915/**
916 * tty_read - read method for tty device files
917 * @file: pointer to tty file
918 * @buf: user buffer
919 * @count: size of user buffer
920 * @ppos: unused
921 *
922 * Perform the read system call function on this terminal device. Checks
923 * for hung up devices before calling the line discipline method.
924 *
925 * Locking:
Alan Cox47f86832008-04-30 00:53:30 -0700926 * Locks the line discipline internally while needed. Multiple
927 * read calls may be outstanding in parallel.
Alan Coxaf9b8972006-08-27 01:24:01 -0700928 */
929
Alan Cox37bdfb02008-02-08 04:18:47 -0800930static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 loff_t *ppos)
932{
933 int i;
Nick Piggind996b622010-08-18 04:37:36 +1000934 struct inode *inode = file->f_path.dentry->d_inode;
935 struct tty_struct *tty = file_tty(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 struct tty_ldisc *ld;
937
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 if (tty_paranoia_check(tty, inode, "tty_read"))
939 return -EIO;
940 if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
941 return -EIO;
942
943 /* We want to wait for the line discipline to sort out in this
944 situation */
945 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +0100946 if (ld->ops->read)
947 i = (ld->ops->read)(tty, file, buf, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 else
949 i = -EIO;
950 tty_ldisc_deref(ld);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 if (i > 0)
952 inode->i_atime = current_fs_time(inode->i_sb);
953 return i;
954}
955
Alan Cox9c1729d2007-07-15 23:39:43 -0700956void tty_write_unlock(struct tty_struct *tty)
957{
958 mutex_unlock(&tty->atomic_write_lock);
Davide Libenzi4b194492009-03-31 15:24:24 -0700959 wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
Alan Cox9c1729d2007-07-15 23:39:43 -0700960}
961
962int tty_write_lock(struct tty_struct *tty, int ndelay)
963{
964 if (!mutex_trylock(&tty->atomic_write_lock)) {
965 if (ndelay)
966 return -EAGAIN;
967 if (mutex_lock_interruptible(&tty->atomic_write_lock))
968 return -ERESTARTSYS;
969 }
970 return 0;
971}
972
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973/*
974 * Split writes up in sane blocksizes to avoid
975 * denial-of-service type attacks
976 */
977static inline ssize_t do_tty_write(
978 ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),
979 struct tty_struct *tty,
980 struct file *file,
981 const char __user *buf,
982 size_t count)
983{
Alan Cox9c1729d2007-07-15 23:39:43 -0700984 ssize_t ret, written = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 unsigned int chunk;
Alan Cox37bdfb02008-02-08 04:18:47 -0800986
Alan Cox9c1729d2007-07-15 23:39:43 -0700987 ret = tty_write_lock(tty, file->f_flags & O_NDELAY);
988 if (ret < 0)
989 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
991 /*
992 * We chunk up writes into a temporary buffer. This
993 * simplifies low-level drivers immensely, since they
994 * don't have locking issues and user mode accesses.
995 *
996 * But if TTY_NO_WRITE_SPLIT is set, we should use a
997 * big chunk-size..
998 *
999 * The default chunk-size is 2kB, because the NTTY
1000 * layer has problems with bigger chunks. It will
1001 * claim to be able to handle more characters than
1002 * it actually does.
Alan Coxaf9b8972006-08-27 01:24:01 -07001003 *
1004 * FIXME: This can probably go away now except that 64K chunks
1005 * are too likely to fail unless switched to vmalloc...
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 */
1007 chunk = 2048;
1008 if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags))
1009 chunk = 65536;
1010 if (count < chunk)
1011 chunk = count;
1012
Ingo Molnar70522e12006-03-23 03:00:31 -08001013 /* write_buf/write_cnt is protected by the atomic_write_lock mutex */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 if (tty->write_cnt < chunk) {
Jason Wessel402fda92008-10-13 10:45:36 +01001015 unsigned char *buf_chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016
1017 if (chunk < 1024)
1018 chunk = 1024;
1019
Jason Wessel402fda92008-10-13 10:45:36 +01001020 buf_chunk = kmalloc(chunk, GFP_KERNEL);
1021 if (!buf_chunk) {
Alan Cox9c1729d2007-07-15 23:39:43 -07001022 ret = -ENOMEM;
1023 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 }
1025 kfree(tty->write_buf);
1026 tty->write_cnt = chunk;
Jason Wessel402fda92008-10-13 10:45:36 +01001027 tty->write_buf = buf_chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 }
1029
1030 /* Do the write .. */
1031 for (;;) {
1032 size_t size = count;
1033 if (size > chunk)
1034 size = chunk;
1035 ret = -EFAULT;
1036 if (copy_from_user(tty->write_buf, buf, size))
1037 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 ret = write(tty, file, tty->write_buf, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 if (ret <= 0)
1040 break;
1041 written += ret;
1042 buf += ret;
1043 count -= ret;
1044 if (!count)
1045 break;
1046 ret = -ERESTARTSYS;
1047 if (signal_pending(current))
1048 break;
1049 cond_resched();
1050 }
1051 if (written) {
Josef Sipeka7113a92006-12-08 02:36:55 -08001052 struct inode *inode = file->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 inode->i_mtime = current_fs_time(inode->i_sb);
1054 ret = written;
1055 }
Alan Cox9c1729d2007-07-15 23:39:43 -07001056out:
1057 tty_write_unlock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 return ret;
1059}
1060
Alan Cox95f9bfc62008-10-13 10:39:23 +01001061/**
1062 * tty_write_message - write a message to a certain tty, not just the console.
1063 * @tty: the destination tty_struct
1064 * @msg: the message to write
1065 *
1066 * This is used for messages that need to be redirected to a specific tty.
1067 * We don't put it into the syslog queue right now maybe in the future if
1068 * really needed.
1069 *
Arnd Bergmannec79d602010-06-01 22:53:01 +02001070 * We must still hold the BTM and test the CLOSING flag for the moment.
Alan Cox95f9bfc62008-10-13 10:39:23 +01001071 */
1072
1073void tty_write_message(struct tty_struct *tty, char *msg)
1074{
Alan Cox95f9bfc62008-10-13 10:39:23 +01001075 if (tty) {
1076 mutex_lock(&tty->atomic_write_lock);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001077 tty_lock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001078 if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001079 tty_unlock();
Alan Cox95f9bfc62008-10-13 10:39:23 +01001080 tty->ops->write(tty, msg, strlen(msg));
Alan Coxeeb89d92009-11-30 13:18:29 +00001081 } else
Arnd Bergmannec79d602010-06-01 22:53:01 +02001082 tty_unlock();
Alan Cox95f9bfc62008-10-13 10:39:23 +01001083 tty_write_unlock(tty);
1084 }
Alan Cox95f9bfc62008-10-13 10:39:23 +01001085 return;
1086}
1087
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
Alan Coxaf9b8972006-08-27 01:24:01 -07001089/**
1090 * tty_write - write method for tty device file
1091 * @file: tty file pointer
1092 * @buf: user data to write
1093 * @count: bytes to write
1094 * @ppos: unused
1095 *
1096 * Write data to a tty device via the line discipline.
1097 *
1098 * Locking:
1099 * Locks the line discipline as required
1100 * Writes to the tty driver are serialized by the atomic_write_lock
1101 * and are then processed in chunks to the device. The line discipline
Joe Petersona88a69c2009-01-02 13:40:53 +00001102 * write method will not be invoked in parallel for each device.
Alan Coxaf9b8972006-08-27 01:24:01 -07001103 */
1104
Alan Cox37bdfb02008-02-08 04:18:47 -08001105static ssize_t tty_write(struct file *file, const char __user *buf,
1106 size_t count, loff_t *ppos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107{
Josef Sipeka7113a92006-12-08 02:36:55 -08001108 struct inode *inode = file->f_path.dentry->d_inode;
Nick Piggind996b622010-08-18 04:37:36 +10001109 struct tty_struct *tty = file_tty(file);
1110 struct tty_ldisc *ld;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 ssize_t ret;
Alan Cox37bdfb02008-02-08 04:18:47 -08001112
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 if (tty_paranoia_check(tty, inode, "tty_write"))
1114 return -EIO;
Alan Coxf34d7a52008-04-30 00:54:13 -07001115 if (!tty || !tty->ops->write ||
Alan Cox37bdfb02008-02-08 04:18:47 -08001116 (test_bit(TTY_IO_ERROR, &tty->flags)))
1117 return -EIO;
Alan Coxf34d7a52008-04-30 00:54:13 -07001118 /* Short term debug to catch buggy drivers */
1119 if (tty->ops->write_room == NULL)
1120 printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
1121 tty->driver->name);
Alan Cox37bdfb02008-02-08 04:18:47 -08001122 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +01001123 if (!ld->ops->write)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 ret = -EIO;
1125 else
Alan Coxa352def2008-07-16 21:53:12 +01001126 ret = do_tty_write(ld->ops->write, tty, file, buf, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 tty_ldisc_deref(ld);
1128 return ret;
1129}
1130
Alan Cox37bdfb02008-02-08 04:18:47 -08001131ssize_t redirected_tty_write(struct file *file, const char __user *buf,
1132 size_t count, loff_t *ppos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133{
1134 struct file *p = NULL;
1135
1136 spin_lock(&redirect_lock);
1137 if (redirect) {
1138 get_file(redirect);
1139 p = redirect;
1140 }
1141 spin_unlock(&redirect_lock);
1142
1143 if (p) {
1144 ssize_t res;
1145 res = vfs_write(p, buf, count, &p->f_pos);
1146 fput(p);
1147 return res;
1148 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 return tty_write(file, buf, count, ppos);
1150}
1151
1152static char ptychar[] = "pqrstuvwxyzabcde";
1153
Alan Coxaf9b8972006-08-27 01:24:01 -07001154/**
1155 * pty_line_name - generate name for a pty
1156 * @driver: the tty driver in use
1157 * @index: the minor number
1158 * @p: output buffer of at least 6 bytes
1159 *
1160 * Generate a name from a driver reference and write it to the output
1161 * buffer.
1162 *
1163 * Locking: None
1164 */
1165static void pty_line_name(struct tty_driver *driver, int index, char *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166{
1167 int i = index + driver->name_base;
1168 /* ->name is initialized to "ttyp", but "tty" is expected */
1169 sprintf(p, "%s%c%x",
Alan Cox37bdfb02008-02-08 04:18:47 -08001170 driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name,
1171 ptychar[i >> 4 & 0xf], i & 0xf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172}
1173
Alan Coxaf9b8972006-08-27 01:24:01 -07001174/**
Alan Cox8b0a88d2008-10-13 10:42:19 +01001175 * tty_line_name - generate name for a tty
Alan Coxaf9b8972006-08-27 01:24:01 -07001176 * @driver: the tty driver in use
1177 * @index: the minor number
1178 * @p: output buffer of at least 7 bytes
1179 *
1180 * Generate a name from a driver reference and write it to the output
1181 * buffer.
1182 *
1183 * Locking: None
1184 */
1185static void tty_line_name(struct tty_driver *driver, int index, char *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186{
1187 sprintf(p, "%s%d", driver->name, index + driver->name_base);
1188}
1189
Alan Cox99f1fe12008-10-13 10:42:00 +01001190/**
1191 * tty_driver_lookup_tty() - find an existing tty, if any
1192 * @driver: the driver for the tty
1193 * @idx: the minor number
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001194 *
Alan Cox99f1fe12008-10-13 10:42:00 +01001195 * Return the tty, if found or ERR_PTR() otherwise.
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001196 *
Alan Cox99f1fe12008-10-13 10:42:00 +01001197 * Locking: tty_mutex must be held. If tty is found, the mutex must
1198 * be held until the 'fast-open' is also done. Will change once we
1199 * have refcounting in the driver and per driver locking
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001200 */
Jason Wessela47d5452009-01-02 13:43:04 +00001201static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001202 struct inode *inode, int idx)
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001203{
1204 struct tty_struct *tty;
1205
Alan Cox99f1fe12008-10-13 10:42:00 +01001206 if (driver->ops->lookup)
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001207 return driver->ops->lookup(driver, inode, idx);
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001208
Alan Cox8b0a88d2008-10-13 10:42:19 +01001209 tty = driver->ttys[idx];
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001210 return tty;
1211}
1212
Alan Cox99f1fe12008-10-13 10:42:00 +01001213/**
Alan Coxbf970ee2008-10-13 10:42:39 +01001214 * tty_init_termios - helper for termios setup
1215 * @tty: the tty to set up
1216 *
1217 * Initialise the termios structures for this tty. Thus runs under
1218 * the tty_mutex currently so we can be relaxed about ordering.
1219 */
1220
1221int tty_init_termios(struct tty_struct *tty)
1222{
Alan Coxfe6e29f2008-10-13 10:44:08 +01001223 struct ktermios *tp;
Alan Coxbf970ee2008-10-13 10:42:39 +01001224 int idx = tty->index;
1225
1226 tp = tty->driver->termios[idx];
Alan Coxbf970ee2008-10-13 10:42:39 +01001227 if (tp == NULL) {
Alan Coxfe6e29f2008-10-13 10:44:08 +01001228 tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
1229 if (tp == NULL)
Alan Coxbf970ee2008-10-13 10:42:39 +01001230 return -ENOMEM;
Alan Coxbf970ee2008-10-13 10:42:39 +01001231 memcpy(tp, &tty->driver->init_termios,
1232 sizeof(struct ktermios));
1233 tty->driver->termios[idx] = tp;
Alan Coxbf970ee2008-10-13 10:42:39 +01001234 }
1235 tty->termios = tp;
Alan Coxfe6e29f2008-10-13 10:44:08 +01001236 tty->termios_locked = tp + 1;
Alan Coxbf970ee2008-10-13 10:42:39 +01001237
1238 /* Compatibility until drivers always set this */
1239 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
1240 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
1241 return 0;
1242}
Alan Coxfe1ae7f2009-09-19 13:13:33 -07001243EXPORT_SYMBOL_GPL(tty_init_termios);
Alan Coxbf970ee2008-10-13 10:42:39 +01001244
1245/**
Alan Cox8b0a88d2008-10-13 10:42:19 +01001246 * tty_driver_install_tty() - install a tty entry in the driver
1247 * @driver: the driver for the tty
1248 * @tty: the tty
1249 *
1250 * Install a tty object into the driver tables. The tty->index field
Alan Coxbf970ee2008-10-13 10:42:39 +01001251 * will be set by the time this is called. This method is responsible
1252 * for ensuring any need additional structures are allocated and
1253 * configured.
Alan Cox8b0a88d2008-10-13 10:42:19 +01001254 *
1255 * Locking: tty_mutex for now
1256 */
1257static int tty_driver_install_tty(struct tty_driver *driver,
1258 struct tty_struct *tty)
1259{
Alan Coxbf970ee2008-10-13 10:42:39 +01001260 int idx = tty->index;
Alan Coxeeb89d92009-11-30 13:18:29 +00001261 int ret;
Alan Coxbf970ee2008-10-13 10:42:39 +01001262
Alan Coxeeb89d92009-11-30 13:18:29 +00001263 if (driver->ops->install) {
Alan Coxeeb89d92009-11-30 13:18:29 +00001264 ret = driver->ops->install(driver, tty);
Alan Coxeeb89d92009-11-30 13:18:29 +00001265 return ret;
1266 }
Alan Coxbf970ee2008-10-13 10:42:39 +01001267
1268 if (tty_init_termios(tty) == 0) {
1269 tty_driver_kref_get(driver);
1270 tty->count++;
1271 driver->ttys[idx] = tty;
1272 return 0;
1273 }
1274 return -ENOMEM;
Alan Cox8b0a88d2008-10-13 10:42:19 +01001275}
1276
1277/**
1278 * tty_driver_remove_tty() - remove a tty from the driver tables
1279 * @driver: the driver for the tty
1280 * @idx: the minor number
1281 *
1282 * Remvoe a tty object from the driver tables. The tty->index field
1283 * will be set by the time this is called.
1284 *
1285 * Locking: tty_mutex for now
1286 */
1287static void tty_driver_remove_tty(struct tty_driver *driver,
1288 struct tty_struct *tty)
1289{
1290 if (driver->ops->remove)
1291 driver->ops->remove(driver, tty);
1292 else
1293 driver->ttys[tty->index] = NULL;
1294}
1295
1296/*
1297 * tty_reopen() - fast re-open of an open tty
1298 * @tty - the tty to open
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001299 *
Alan Cox99f1fe12008-10-13 10:42:00 +01001300 * Return 0 on success, -errno on error.
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001301 *
Alan Cox99f1fe12008-10-13 10:42:00 +01001302 * Locking: tty_mutex must be held from the time the tty was found
1303 * till this open completes.
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001304 */
Alan Cox99f1fe12008-10-13 10:42:00 +01001305static int tty_reopen(struct tty_struct *tty)
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001306{
1307 struct tty_driver *driver = tty->driver;
1308
1309 if (test_bit(TTY_CLOSING, &tty->flags))
1310 return -EIO;
1311
1312 if (driver->type == TTY_DRIVER_TYPE_PTY &&
1313 driver->subtype == PTY_TYPE_MASTER) {
1314 /*
1315 * special case for PTY masters: only one open permitted,
1316 * and the slave side open count is incremented as well.
1317 */
1318 if (tty->count)
1319 return -EIO;
1320
1321 tty->link->count++;
1322 }
1323 tty->count++;
1324 tty->driver = driver; /* N.B. why do this every time?? */
1325
Alan Cox1aa4bed2009-06-16 17:01:33 +01001326 mutex_lock(&tty->ldisc_mutex);
Alan Cox99f1fe12008-10-13 10:42:00 +01001327 WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
Alan Cox1aa4bed2009-06-16 17:01:33 +01001328 mutex_unlock(&tty->ldisc_mutex);
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001329
1330 return 0;
1331}
1332
Alan Coxaf9b8972006-08-27 01:24:01 -07001333/**
Alan Coxd81ed102008-10-13 10:41:42 +01001334 * tty_init_dev - initialise a tty device
Alan Coxaf9b8972006-08-27 01:24:01 -07001335 * @driver: tty driver we are opening a device on
1336 * @idx: device index
Alan Cox15582d32008-10-13 10:41:03 +01001337 * @ret_tty: returned tty structure
1338 * @first_ok: ok to open a new device (used by ptmx)
Alan Coxaf9b8972006-08-27 01:24:01 -07001339 *
1340 * Prepare a tty device. This may not be a "new" clean device but
1341 * could also be an active device. The pty drivers require special
1342 * handling because of this.
1343 *
1344 * Locking:
1345 * The function is called under the tty_mutex, which
1346 * protects us from the tty struct or driver itself going away.
1347 *
1348 * On exit the tty device has the line discipline attached and
1349 * a reference count of 1. If a pair was created for pty/tty use
1350 * and the other was a pty master then it too has a reference count of 1.
1351 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 * WSH 06/09/97: Rewritten to remove races and properly clean up after a
Ingo Molnar70522e12006-03-23 03:00:31 -08001353 * failed open. The new code protects the open with a mutex, so it's
1354 * really quite straightforward. The mutex locking can probably be
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 * relaxed for the (most common) case of reopening a tty.
1356 */
Alan Coxaf9b8972006-08-27 01:24:01 -07001357
Alan Cox73ec06f2008-10-13 10:42:29 +01001358struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
1359 int first_ok)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360{
Alan Coxbf970ee2008-10-13 10:42:39 +01001361 struct tty_struct *tty;
Alan Cox73ec06f2008-10-13 10:42:29 +01001362 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001364 /* Check if pty master is being opened multiple times */
Alan Cox15582d32008-10-13 10:41:03 +01001365 if (driver->subtype == PTY_TYPE_MASTER &&
Alan Coxeeb89d92009-11-30 13:18:29 +00001366 (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
Alan Cox73ec06f2008-10-13 10:42:29 +01001367 return ERR_PTR(-EIO);
Alan Coxeeb89d92009-11-30 13:18:29 +00001368 }
Alan Cox73ec06f2008-10-13 10:42:29 +01001369
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 /*
1371 * First time open is complex, especially for PTY devices.
1372 * This code guarantees that either everything succeeds and the
1373 * TTY is ready for operation, or else the table slots are vacated
Alan Cox37bdfb02008-02-08 04:18:47 -08001374 * and the allocated memory released. (Except that the termios
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 * and locked termios may be retained.)
1376 */
1377
Alan Cox73ec06f2008-10-13 10:42:29 +01001378 if (!try_module_get(driver->owner))
1379 return ERR_PTR(-ENODEV);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 tty = alloc_tty_struct();
Alan Cox37bdfb02008-02-08 04:18:47 -08001382 if (!tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 goto fail_no_mem;
Alan Coxbf970ee2008-10-13 10:42:39 +01001384 initialize_tty_struct(tty, driver, idx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385
Alan Cox73ec06f2008-10-13 10:42:29 +01001386 retval = tty_driver_install_tty(driver, tty);
Alan Coxbf970ee2008-10-13 10:42:39 +01001387 if (retval < 0) {
1388 free_tty_struct(tty);
1389 module_put(driver->owner);
1390 return ERR_PTR(retval);
1391 }
Alan Cox8b0a88d2008-10-13 10:42:19 +01001392
Alan Cox37bdfb02008-02-08 04:18:47 -08001393 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 * Structures all installed ... call the ldisc open routines.
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001395 * If we fail here just call release_tty to clean up. No need
1396 * to decrement the use counts, as release_tty doesn't care.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 */
Alan Coxbf970ee2008-10-13 10:42:39 +01001398 retval = tty_ldisc_setup(tty, tty->link);
Alan Cox01e1abb2008-07-22 11:16:55 +01001399 if (retval)
1400 goto release_mem_out;
Alan Cox73ec06f2008-10-13 10:42:29 +01001401 return tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403fail_no_mem:
1404 module_put(driver->owner);
Alan Cox73ec06f2008-10-13 10:42:29 +01001405 return ERR_PTR(-ENOMEM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001407 /* call the tty release_tty routine to clean out this slot */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408release_mem_out:
Akinobu Mita40509142006-09-29 02:01:27 -07001409 if (printk_ratelimit())
Alan Coxd81ed102008-10-13 10:41:42 +01001410 printk(KERN_INFO "tty_init_dev: ldisc open failed, "
Akinobu Mita40509142006-09-29 02:01:27 -07001411 "clearing slot %d\n", idx);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001412 release_tty(tty, idx);
Alan Cox73ec06f2008-10-13 10:42:29 +01001413 return ERR_PTR(retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414}
1415
Alan Coxfeebed62008-10-13 10:41:30 +01001416void tty_free_termios(struct tty_struct *tty)
1417{
1418 struct ktermios *tp;
1419 int idx = tty->index;
1420 /* Kill this flag and push into drivers for locking etc */
1421 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
1422 /* FIXME: Locking on ->termios array */
1423 tp = tty->termios;
1424 tty->driver->termios[idx] = NULL;
1425 kfree(tp);
Alan Coxfeebed62008-10-13 10:41:30 +01001426 }
1427}
1428EXPORT_SYMBOL(tty_free_termios);
1429
1430void tty_shutdown(struct tty_struct *tty)
1431{
Alan Cox8b0a88d2008-10-13 10:42:19 +01001432 tty_driver_remove_tty(tty->driver, tty);
Alan Coxfeebed62008-10-13 10:41:30 +01001433 tty_free_termios(tty);
1434}
1435EXPORT_SYMBOL(tty_shutdown);
1436
Alan Coxaf9b8972006-08-27 01:24:01 -07001437/**
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001438 * release_one_tty - release tty structure memory
Alan Cox9c9f4de2008-10-13 10:37:26 +01001439 * @kref: kref of tty we are obliterating
Alan Coxaf9b8972006-08-27 01:24:01 -07001440 *
1441 * Releases memory associated with a tty structure, and clears out the
1442 * driver table slots. This function is called when a device is no longer
1443 * in use. It also gets called when setup of a device fails.
1444 *
1445 * Locking:
1446 * tty_mutex - sometimes only
1447 * takes the file list lock internally when working on the list
1448 * of ttys that the driver keeps.
Alan Coxb50989d2009-09-19 13:13:22 -07001449 *
1450 * This method gets called from a work queue so that the driver private
Dave Youngf278a2f2009-09-27 16:00:42 +00001451 * cleanup ops can sleep (needed for USB at least)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 */
Alan Coxb50989d2009-09-19 13:13:22 -07001453static void release_one_tty(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454{
Alan Coxb50989d2009-09-19 13:13:22 -07001455 struct tty_struct *tty =
1456 container_of(work, struct tty_struct, hangup_work);
Alan Cox6f967f72008-10-13 10:37:36 +01001457 struct tty_driver *driver = tty->driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458
Dave Youngf278a2f2009-09-27 16:00:42 +00001459 if (tty->ops->cleanup)
1460 tty->ops->cleanup(tty);
1461
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 tty->magic = 0;
Alan Cox7d7b93c2008-10-13 10:42:09 +01001463 tty_driver_kref_put(driver);
Alan Cox6f967f72008-10-13 10:37:36 +01001464 module_put(driver->owner);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001465
Nick Pigginee2ffa02010-08-18 04:37:35 +10001466 spin_lock(&tty_files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 list_del_init(&tty->tty_files);
Nick Pigginee2ffa02010-08-18 04:37:35 +10001468 spin_unlock(&tty_files_lock);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001469
Oleg Nesterov6da8d862010-04-02 18:05:12 +02001470 put_pid(tty->pgrp);
1471 put_pid(tty->session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 free_tty_struct(tty);
1473}
1474
Alan Coxb50989d2009-09-19 13:13:22 -07001475static void queue_release_one_tty(struct kref *kref)
1476{
1477 struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
Dave Youngf278a2f2009-09-27 16:00:42 +00001478
1479 if (tty->ops->shutdown)
1480 tty->ops->shutdown(tty);
1481 else
1482 tty_shutdown(tty);
1483
Alan Coxb50989d2009-09-19 13:13:22 -07001484 /* The hangup queue is now free so we can reuse it rather than
1485 waste a chunk of memory for each port */
1486 INIT_WORK(&tty->hangup_work, release_one_tty);
1487 schedule_work(&tty->hangup_work);
1488}
1489
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001490/**
Alan Cox9c9f4de2008-10-13 10:37:26 +01001491 * tty_kref_put - release a tty kref
1492 * @tty: tty device
1493 *
1494 * Release a reference to a tty device and if need be let the kref
1495 * layer destruct the object for us
1496 */
1497
1498void tty_kref_put(struct tty_struct *tty)
1499{
1500 if (tty)
Alan Coxb50989d2009-09-19 13:13:22 -07001501 kref_put(&tty->kref, queue_release_one_tty);
Alan Cox9c9f4de2008-10-13 10:37:26 +01001502}
1503EXPORT_SYMBOL(tty_kref_put);
1504
1505/**
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001506 * release_tty - release tty structure memory
1507 *
1508 * Release both @tty and a possible linked partner (think pty pair),
1509 * and decrement the refcount of the backing module.
1510 *
1511 * Locking:
1512 * tty_mutex - sometimes only
1513 * takes the file list lock internally when working on the list
1514 * of ttys that the driver keeps.
1515 * FIXME: should we require tty_mutex is held here ??
Alan Cox9c9f4de2008-10-13 10:37:26 +01001516 *
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001517 */
1518static void release_tty(struct tty_struct *tty, int idx)
1519{
Alan Cox9c9f4de2008-10-13 10:37:26 +01001520 /* This should always be true but check for the moment */
1521 WARN_ON(tty->index != idx);
1522
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001523 if (tty->link)
Alan Cox9c9f4de2008-10-13 10:37:26 +01001524 tty_kref_put(tty->link);
1525 tty_kref_put(tty);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001526}
1527
Alan Coxeeb89d92009-11-30 13:18:29 +00001528/**
1529 * tty_release - vfs callback for close
1530 * @inode: inode of tty
1531 * @filp: file pointer for handle to tty
1532 *
1533 * Called the last time each file handle is closed that references
1534 * this tty. There may however be several such references.
1535 *
1536 * Locking:
1537 * Takes bkl. See tty_release_dev
1538 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 * Even releasing the tty structures is a tricky business.. We have
1540 * to be very careful that the structures are all released at the
1541 * same time, as interrupts might otherwise get the wrong pointers.
1542 *
1543 * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
1544 * lead to double frees or releasing memory still in use.
1545 */
Alan Coxeeb89d92009-11-30 13:18:29 +00001546
1547int tty_release(struct inode *inode, struct file *filp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548{
Nick Piggind996b622010-08-18 04:37:36 +10001549 struct tty_struct *tty = file_tty(filp);
1550 struct tty_struct *o_tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 int pty_master, tty_closing, o_tty_closing, do_sleep;
Paul Fulghum14a62832006-04-10 22:54:19 -07001552 int devpts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 int idx;
1554 char buf[64];
Alan Cox37bdfb02008-02-08 04:18:47 -08001555
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001556 if (tty_paranoia_check(tty, inode, "tty_release_dev"))
Alan Coxeeb89d92009-11-30 13:18:29 +00001557 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558
Arnd Bergmannec79d602010-06-01 22:53:01 +02001559 tty_lock();
Alan Coxd81ed102008-10-13 10:41:42 +01001560 check_tty_count(tty, "tty_release_dev");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561
Arnd Bergmannec79d602010-06-01 22:53:01 +02001562 __tty_fasync(-1, filp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563
1564 idx = tty->index;
1565 pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1566 tty->driver->subtype == PTY_TYPE_MASTER);
1567 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 o_tty = tty->link;
1569
1570#ifdef TTY_PARANOIA_CHECK
1571 if (idx < 0 || idx >= tty->driver->num) {
Alan Coxd81ed102008-10-13 10:41:42 +01001572 printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 "free (%s)\n", tty->name);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001574 tty_unlock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001575 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 }
Alan Cox8b0a88d2008-10-13 10:42:19 +01001577 if (!devpts) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 if (tty != tty->driver->ttys[idx]) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001579 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001580 printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 "for (%s)\n", idx, tty->name);
Alan Coxeeb89d92009-11-30 13:18:29 +00001582 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 }
1584 if (tty->termios != tty->driver->termios[idx]) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001585 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001586 printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 "for (%s)\n",
1588 idx, tty->name);
Alan Coxeeb89d92009-11-30 13:18:29 +00001589 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 }
1592#endif
1593
1594#ifdef TTY_DEBUG_HANGUP
Alan Coxd81ed102008-10-13 10:41:42 +01001595 printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 tty_name(tty, buf), tty->count);
1597#endif
1598
1599#ifdef TTY_PARANOIA_CHECK
1600 if (tty->driver->other &&
1601 !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
1602 if (o_tty != tty->driver->other->ttys[idx]) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001603 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001604 printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 "not o_tty for (%s)\n",
1606 idx, tty->name);
Alan Coxeeb89d92009-11-30 13:18:29 +00001607 return 0 ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 }
1609 if (o_tty->termios != tty->driver->other->termios[idx]) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001610 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001611 printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 "not o_termios for (%s)\n",
1613 idx, tty->name);
Alan Coxeeb89d92009-11-30 13:18:29 +00001614 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 if (o_tty->link != tty) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001617 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001618 printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
Alan Coxeeb89d92009-11-30 13:18:29 +00001619 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 }
1621 }
1622#endif
Alan Coxf34d7a52008-04-30 00:54:13 -07001623 if (tty->ops->close)
1624 tty->ops->close(tty, filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625
Arnd Bergmannec79d602010-06-01 22:53:01 +02001626 tty_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 /*
1628 * Sanity check: if tty->count is going to zero, there shouldn't be
1629 * any waiters on tty->read_wait or tty->write_wait. We test the
1630 * wait queues and kick everyone out _before_ actually starting to
1631 * close. This ensures that we won't block while releasing the tty
1632 * structure.
1633 *
1634 * The test for the o_tty closing is necessary, since the master and
1635 * slave sides may close in any order. If the slave side closes out
1636 * first, its count will be one, since the master side holds an open.
1637 * Thus this test wouldn't be triggered at the time the slave closes,
1638 * so we do it now.
1639 *
1640 * Note that it's possible for the tty to be opened again while we're
1641 * flushing out waiters. By recalculating the closing flags before
1642 * each iteration we avoid any problems.
1643 */
1644 while (1) {
1645 /* Guard against races with tty->count changes elsewhere and
1646 opens on /dev/tty */
Alan Cox37bdfb02008-02-08 04:18:47 -08001647
Ingo Molnar70522e12006-03-23 03:00:31 -08001648 mutex_lock(&tty_mutex);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001649 tty_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 tty_closing = tty->count <= 1;
1651 o_tty_closing = o_tty &&
1652 (o_tty->count <= (pty_master ? 1 : 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653 do_sleep = 0;
1654
1655 if (tty_closing) {
1656 if (waitqueue_active(&tty->read_wait)) {
Davide Libenzi4b194492009-03-31 15:24:24 -07001657 wake_up_poll(&tty->read_wait, POLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 do_sleep++;
1659 }
1660 if (waitqueue_active(&tty->write_wait)) {
Davide Libenzi4b194492009-03-31 15:24:24 -07001661 wake_up_poll(&tty->write_wait, POLLOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 do_sleep++;
1663 }
1664 }
1665 if (o_tty_closing) {
1666 if (waitqueue_active(&o_tty->read_wait)) {
Davide Libenzi4b194492009-03-31 15:24:24 -07001667 wake_up_poll(&o_tty->read_wait, POLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 do_sleep++;
1669 }
1670 if (waitqueue_active(&o_tty->write_wait)) {
Davide Libenzi4b194492009-03-31 15:24:24 -07001671 wake_up_poll(&o_tty->write_wait, POLLOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 do_sleep++;
1673 }
1674 }
1675 if (!do_sleep)
1676 break;
1677
Alan Coxd81ed102008-10-13 10:41:42 +01001678 printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 "active!\n", tty_name(tty, buf));
Arnd Bergmannec79d602010-06-01 22:53:01 +02001680 tty_unlock();
Ingo Molnar70522e12006-03-23 03:00:31 -08001681 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 schedule();
Alan Cox37bdfb02008-02-08 04:18:47 -08001683 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
1685 /*
Alan Cox37bdfb02008-02-08 04:18:47 -08001686 * The closing flags are now consistent with the open counts on
1687 * both sides, and we've completed the last operation that could
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 * block, so it's safe to proceed with closing.
1689 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 if (pty_master) {
1691 if (--o_tty->count < 0) {
Alan Coxd81ed102008-10-13 10:41:42 +01001692 printk(KERN_WARNING "tty_release_dev: bad pty slave count "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 "(%d) for %s\n",
1694 o_tty->count, tty_name(o_tty, buf));
1695 o_tty->count = 0;
1696 }
1697 }
1698 if (--tty->count < 0) {
Alan Coxd81ed102008-10-13 10:41:42 +01001699 printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 tty->count, tty_name(tty, buf));
1701 tty->count = 0;
1702 }
Alan Cox37bdfb02008-02-08 04:18:47 -08001703
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 /*
1705 * We've decremented tty->count, so we need to remove this file
1706 * descriptor off the tty->tty_files list; this serves two
1707 * purposes:
1708 * - check_tty_count sees the correct number of file descriptors
1709 * associated with this tty.
1710 * - do_tty_hangup no longer sees this file descriptor as
1711 * something that needs to be handled for hangups.
1712 */
Nick Piggind996b622010-08-18 04:37:36 +10001713 tty_del_file(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
1715 /*
1716 * Perform some housekeeping before deciding whether to return.
1717 *
1718 * Set the TTY_CLOSING flag if this was the last open. In the
1719 * case of a pty we may have to wait around for the other side
1720 * to close, and TTY_CLOSING makes sure we can't be reopened.
1721 */
Alan Cox37bdfb02008-02-08 04:18:47 -08001722 if (tty_closing)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 set_bit(TTY_CLOSING, &tty->flags);
Alan Cox37bdfb02008-02-08 04:18:47 -08001724 if (o_tty_closing)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 set_bit(TTY_CLOSING, &o_tty->flags);
1726
1727 /*
1728 * If _either_ side is closing, make sure there aren't any
1729 * processes that still think tty or o_tty is their controlling
1730 * tty.
1731 */
1732 if (tty_closing || o_tty_closing) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 read_lock(&tasklist_lock);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001734 session_clear_tty(tty->session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 if (o_tty)
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001736 session_clear_tty(o_tty->session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 read_unlock(&tasklist_lock);
1738 }
1739
Ingo Molnar70522e12006-03-23 03:00:31 -08001740 mutex_unlock(&tty_mutex);
Paul Fulghumda965822006-02-14 13:53:00 -08001741
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 /* check whether both sides are closing ... */
Alan Coxeeb89d92009-11-30 13:18:29 +00001743 if (!tty_closing || (o_tty && !o_tty_closing)) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001744 tty_unlock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001745 return 0;
1746 }
Alan Cox37bdfb02008-02-08 04:18:47 -08001747
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748#ifdef TTY_DEBUG_HANGUP
1749 printk(KERN_DEBUG "freeing tty structure...");
1750#endif
1751 /*
Alan Cox01e1abb2008-07-22 11:16:55 +01001752 * Ask the line discipline code to release its structures
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 */
Alan Cox01e1abb2008-07-22 11:16:55 +01001754 tty_ldisc_release(tty, o_tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 /*
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001756 * The release_tty function takes care of the details of clearing
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 * the slots and preserving the termios structure.
1758 */
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001759 release_tty(tty, idx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 /* Make this pty number available for reallocation */
Sukadev Bhattiprolu718a9162008-04-30 00:54:21 -07001762 if (devpts)
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001763 devpts_kill_index(inode, idx);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001764 tty_unlock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001765 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766}
1767
Alan Coxaf9b8972006-08-27 01:24:01 -07001768/**
Alan Coxeeb89d92009-11-30 13:18:29 +00001769 * tty_open - open a tty device
Alan Coxaf9b8972006-08-27 01:24:01 -07001770 * @inode: inode of device file
1771 * @filp: file pointer to tty
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 *
Alan Coxaf9b8972006-08-27 01:24:01 -07001773 * tty_open and tty_release keep up the tty count that contains the
1774 * number of opens done on a tty. We cannot use the inode-count, as
1775 * different inodes might point to the same tty.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 *
Alan Coxaf9b8972006-08-27 01:24:01 -07001777 * Open-counting is needed for pty masters, as well as for keeping
1778 * track of serial lines: DTR is dropped when the last close happens.
1779 * (This is not done solely through tty->count, now. - Ted 1/27/92)
1780 *
1781 * The termios state of a pty is reset on first open so that
1782 * settings don't persist across reuse.
1783 *
Alan Coxd81ed102008-10-13 10:41:42 +01001784 * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work.
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001785 * tty->count should protect the rest.
1786 * ->siglock protects ->signal/->sighand
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 */
Alan Coxaf9b8972006-08-27 01:24:01 -07001788
Alan Coxeeb89d92009-11-30 13:18:29 +00001789static int tty_open(struct inode *inode, struct file *filp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790{
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001791 struct tty_struct *tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 int noctty, retval;
1793 struct tty_driver *driver;
1794 int index;
1795 dev_t device = inode->i_rdev;
Andrew Morton846c1512009-04-02 16:56:36 -07001796 unsigned saved_flags = filp->f_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
1798 nonseekable_open(inode, filp);
Alan Cox37bdfb02008-02-08 04:18:47 -08001799
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800retry_open:
1801 noctty = filp->f_flags & O_NOCTTY;
1802 index = -1;
1803 retval = 0;
Alan Cox37bdfb02008-02-08 04:18:47 -08001804
Ingo Molnar70522e12006-03-23 03:00:31 -08001805 mutex_lock(&tty_mutex);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001806 tty_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807
Alan Cox37bdfb02008-02-08 04:18:47 -08001808 if (device == MKDEV(TTYAUX_MAJOR, 0)) {
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001809 tty = get_current_tty();
1810 if (!tty) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001811 tty_unlock();
Ingo Molnar70522e12006-03-23 03:00:31 -08001812 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 return -ENXIO;
1814 }
Alan Cox7d7b93c2008-10-13 10:42:09 +01001815 driver = tty_driver_kref_get(tty->driver);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001816 index = tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
1818 /* noctty = 1; */
Alan Cox452a00d2008-10-13 10:39:13 +01001819 /* FIXME: Should we take a driver reference ? */
1820 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 goto got_driver;
1822 }
1823#ifdef CONFIG_VT
Alan Cox37bdfb02008-02-08 04:18:47 -08001824 if (device == MKDEV(TTY_MAJOR, 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 extern struct tty_driver *console_driver;
Alan Cox7d7b93c2008-10-13 10:42:09 +01001826 driver = tty_driver_kref_get(console_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 index = fg_console;
1828 noctty = 1;
1829 goto got_driver;
1830 }
1831#endif
Alan Cox37bdfb02008-02-08 04:18:47 -08001832 if (device == MKDEV(TTYAUX_MAJOR, 1)) {
Will Newton296fa7f2008-12-01 11:36:06 +00001833 struct tty_driver *console_driver = console_device(&index);
1834 if (console_driver) {
1835 driver = tty_driver_kref_get(console_driver);
1836 if (driver) {
1837 /* Don't let /dev/console block */
1838 filp->f_flags |= O_NONBLOCK;
1839 noctty = 1;
1840 goto got_driver;
1841 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 }
Arnd Bergmannec79d602010-06-01 22:53:01 +02001843 tty_unlock();
Ingo Molnar70522e12006-03-23 03:00:31 -08001844 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 return -ENODEV;
1846 }
1847
1848 driver = get_tty_driver(device, &index);
1849 if (!driver) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001850 tty_unlock();
Ingo Molnar70522e12006-03-23 03:00:31 -08001851 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 return -ENODEV;
1853 }
1854got_driver:
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001855 if (!tty) {
1856 /* check whether we're reopening an existing tty */
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001857 tty = tty_driver_lookup_tty(driver, inode, index);
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001858
Eric Paris808ffa32009-01-27 11:50:37 +00001859 if (IS_ERR(tty)) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001860 tty_unlock();
Eric Paris808ffa32009-01-27 11:50:37 +00001861 mutex_unlock(&tty_mutex);
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001862 return PTR_ERR(tty);
Eric Paris808ffa32009-01-27 11:50:37 +00001863 }
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001864 }
1865
1866 if (tty) {
1867 retval = tty_reopen(tty);
1868 if (retval)
1869 tty = ERR_PTR(retval);
1870 } else
1871 tty = tty_init_dev(driver, index, 0);
1872
Ingo Molnar70522e12006-03-23 03:00:31 -08001873 mutex_unlock(&tty_mutex);
Alan Cox7d7b93c2008-10-13 10:42:09 +01001874 tty_driver_kref_put(driver);
Alan Coxeeb89d92009-11-30 13:18:29 +00001875 if (IS_ERR(tty)) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001876 tty_unlock();
Alan Cox73ec06f2008-10-13 10:42:29 +01001877 return PTR_ERR(tty);
Alan Coxeeb89d92009-11-30 13:18:29 +00001878 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879
Nick Piggind996b622010-08-18 04:37:36 +10001880 tty_add_file(tty, filp);
1881
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 check_tty_count(tty, "tty_open");
1883 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1884 tty->driver->subtype == PTY_TYPE_MASTER)
1885 noctty = 1;
1886#ifdef TTY_DEBUG_HANGUP
1887 printk(KERN_DEBUG "opening %s...", tty->name);
1888#endif
1889 if (!retval) {
Alan Coxf34d7a52008-04-30 00:54:13 -07001890 if (tty->ops->open)
1891 retval = tty->ops->open(tty, filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 else
1893 retval = -ENODEV;
1894 }
1895 filp->f_flags = saved_flags;
1896
Alan Cox37bdfb02008-02-08 04:18:47 -08001897 if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) &&
1898 !capable(CAP_SYS_ADMIN))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 retval = -EBUSY;
1900
1901 if (retval) {
1902#ifdef TTY_DEBUG_HANGUP
1903 printk(KERN_DEBUG "error %d in opening %s...", retval,
1904 tty->name);
1905#endif
Arnd Bergmann64ba3dc32010-06-01 22:53:02 +02001906 tty_unlock(); /* need to call tty_release without BTM */
Alan Coxeeb89d92009-11-30 13:18:29 +00001907 tty_release(inode, filp);
Arnd Bergmann64ba3dc32010-06-01 22:53:02 +02001908 if (retval != -ERESTARTSYS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 return retval;
Arnd Bergmann64ba3dc32010-06-01 22:53:02 +02001910
1911 if (signal_pending(current))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 return retval;
Arnd Bergmann64ba3dc32010-06-01 22:53:02 +02001913
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 schedule();
1915 /*
1916 * Need to reset f_op in case a hangup happened.
1917 */
Arnd Bergmann64ba3dc32010-06-01 22:53:02 +02001918 tty_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 if (filp->f_op == &hung_up_tty_fops)
1920 filp->f_op = &tty_fops;
Arnd Bergmannec79d602010-06-01 22:53:01 +02001921 tty_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 goto retry_open;
1923 }
Arnd Bergmannec79d602010-06-01 22:53:01 +02001924 tty_unlock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001925
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001926
1927 mutex_lock(&tty_mutex);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001928 tty_lock();
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001929 spin_lock_irq(&current->sighand->siglock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 if (!noctty &&
1931 current->signal->leader &&
1932 !current->signal->tty &&
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08001933 tty->session == NULL)
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -07001934 __proc_set_tty(current, tty);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001935 spin_unlock_irq(&current->sighand->siglock);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001936 tty_unlock();
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001937 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 return 0;
1939}
1940
Jonathan Corbet39d95b92008-05-16 09:10:50 -06001941
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942
Alan Coxaf9b8972006-08-27 01:24:01 -07001943/**
1944 * tty_poll - check tty status
1945 * @filp: file being polled
1946 * @wait: poll wait structures to update
1947 *
1948 * Call the line discipline polling method to obtain the poll
1949 * status of the device.
1950 *
1951 * Locking: locks called line discipline but ldisc poll method
1952 * may be re-entered freely by other callers.
1953 */
1954
Alan Cox37bdfb02008-02-08 04:18:47 -08001955static unsigned int tty_poll(struct file *filp, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956{
Nick Piggind996b622010-08-18 04:37:36 +10001957 struct tty_struct *tty = file_tty(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 struct tty_ldisc *ld;
1959 int ret = 0;
1960
Josef Sipeka7113a92006-12-08 02:36:55 -08001961 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 return 0;
Alan Cox37bdfb02008-02-08 04:18:47 -08001963
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +01001965 if (ld->ops->poll)
1966 ret = (ld->ops->poll)(tty, filp, wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 tty_ldisc_deref(ld);
1968 return ret;
1969}
1970
Arnd Bergmannec79d602010-06-01 22:53:01 +02001971static int __tty_fasync(int fd, struct file *filp, int on)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972{
Nick Piggind996b622010-08-18 04:37:36 +10001973 struct tty_struct *tty = file_tty(filp);
Alan Cox47f86832008-04-30 00:53:30 -07001974 unsigned long flags;
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06001975 int retval = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976
Josef Sipeka7113a92006-12-08 02:36:55 -08001977 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06001978 goto out;
Alan Cox37bdfb02008-02-08 04:18:47 -08001979
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980 retval = fasync_helper(fd, filp, on, &tty->fasync);
1981 if (retval <= 0)
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06001982 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983
1984 if (on) {
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08001985 enum pid_type type;
1986 struct pid *pid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987 if (!waitqueue_active(&tty->read_wait))
1988 tty->minimum_to_wake = 1;
Alan Cox47f86832008-04-30 00:53:30 -07001989 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08001990 if (tty->pgrp) {
1991 pid = tty->pgrp;
1992 type = PIDTYPE_PGID;
1993 } else {
1994 pid = task_pid(current);
1995 type = PIDTYPE_PID;
1996 }
Linus Torvalds80e1e822010-02-07 10:11:23 -08001997 get_pid(pid);
Greg Kroah-Hartman70362512009-12-17 07:07:19 -08001998 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds80e1e822010-02-07 10:11:23 -08001999 retval = __f_setown(filp, pid, type, 0);
2000 put_pid(pid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001 if (retval)
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002002 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003 } else {
2004 if (!tty->fasync && !waitqueue_active(&tty->read_wait))
2005 tty->minimum_to_wake = N_TTY_BUF_SIZE;
2006 }
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002007 retval = 0;
2008out:
Arnd Bergmannec79d602010-06-01 22:53:01 +02002009 return retval;
2010}
2011
2012static int tty_fasync(int fd, struct file *filp, int on)
2013{
2014 int retval;
2015 tty_lock();
2016 retval = __tty_fasync(fd, filp, on);
2017 tty_unlock();
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002018 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019}
2020
Alan Coxaf9b8972006-08-27 01:24:01 -07002021/**
2022 * tiocsti - fake input character
2023 * @tty: tty to fake input into
2024 * @p: pointer to character
2025 *
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +02002026 * Fake input to a tty device. Does the necessary locking and
Alan Coxaf9b8972006-08-27 01:24:01 -07002027 * input management.
2028 *
2029 * FIXME: does not honour flow control ??
2030 *
2031 * Locking:
2032 * Called functions take tty_ldisc_lock
2033 * current->signal->tty check is safe without locks
Alan Cox28298232006-09-29 02:00:58 -07002034 *
2035 * FIXME: may race normal receive processing
Alan Coxaf9b8972006-08-27 01:24:01 -07002036 */
2037
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038static int tiocsti(struct tty_struct *tty, char __user *p)
2039{
2040 char ch, mbz = 0;
2041 struct tty_ldisc *ld;
Alan Cox37bdfb02008-02-08 04:18:47 -08002042
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
2044 return -EPERM;
2045 if (get_user(ch, p))
2046 return -EFAULT;
Al Viro1e641742008-12-09 09:23:33 +00002047 tty_audit_tiocsti(tty, ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +01002049 ld->ops->receive_buf(tty, &ch, &mbz, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 tty_ldisc_deref(ld);
2051 return 0;
2052}
2053
Alan Coxaf9b8972006-08-27 01:24:01 -07002054/**
2055 * tiocgwinsz - implement window query ioctl
2056 * @tty; tty
2057 * @arg: user buffer for result
2058 *
Alan Cox808a0d32006-09-29 02:00:40 -07002059 * Copies the kernel idea of the window size into the user buffer.
Alan Coxaf9b8972006-08-27 01:24:01 -07002060 *
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002061 * Locking: tty->termios_mutex is taken to ensure the winsize data
Alan Cox808a0d32006-09-29 02:00:40 -07002062 * is consistent.
Alan Coxaf9b8972006-08-27 01:24:01 -07002063 */
2064
Alan Cox37bdfb02008-02-08 04:18:47 -08002065static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066{
Alan Cox808a0d32006-09-29 02:00:40 -07002067 int err;
2068
Arjan van de Ven5785c952006-09-29 02:00:43 -07002069 mutex_lock(&tty->termios_mutex);
Alan Cox808a0d32006-09-29 02:00:40 -07002070 err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
Arjan van de Ven5785c952006-09-29 02:00:43 -07002071 mutex_unlock(&tty->termios_mutex);
Alan Cox808a0d32006-09-29 02:00:40 -07002072
2073 return err ? -EFAULT: 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074}
2075
Alan Coxaf9b8972006-08-27 01:24:01 -07002076/**
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002077 * tty_do_resize - resize event
2078 * @tty: tty being resized
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002079 * @rows: rows (character)
2080 * @cols: cols (character)
Alan Coxaf9b8972006-08-27 01:24:01 -07002081 *
Daniel Mack3ad2f3fb2010-02-03 08:01:28 +08002082 * Update the termios variables and send the necessary signals to
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002083 * peform a terminal resize correctly
Alan Coxaf9b8972006-08-27 01:24:01 -07002084 */
2085
Alan Coxfc6f6232009-01-02 13:43:17 +00002086int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087{
Alan Coxfc6f6232009-01-02 13:43:17 +00002088 struct pid *pgrp;
Alan Cox47f86832008-04-30 00:53:30 -07002089 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090
Alan Coxfc6f6232009-01-02 13:43:17 +00002091 /* Lock the tty */
2092 mutex_lock(&tty->termios_mutex);
2093 if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
Alan Coxca9bda02006-09-29 02:00:03 -07002094 goto done;
Alan Cox47f86832008-04-30 00:53:30 -07002095 /* Get the PID values and reference them so we can
2096 avoid holding the tty ctrl lock while sending signals */
2097 spin_lock_irqsave(&tty->ctrl_lock, flags);
2098 pgrp = get_pid(tty->pgrp);
Alan Cox47f86832008-04-30 00:53:30 -07002099 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
2100
2101 if (pgrp)
2102 kill_pgrp(pgrp, SIGWINCH, 1);
Alan Cox47f86832008-04-30 00:53:30 -07002103 put_pid(pgrp);
Alan Cox47f86832008-04-30 00:53:30 -07002104
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002105 tty->winsize = *ws;
Alan Coxca9bda02006-09-29 02:00:03 -07002106done:
Alan Coxfc6f6232009-01-02 13:43:17 +00002107 mutex_unlock(&tty->termios_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108 return 0;
2109}
2110
Alan Coxaf9b8972006-08-27 01:24:01 -07002111/**
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002112 * tiocswinsz - implement window size set ioctl
Alan Coxfc6f6232009-01-02 13:43:17 +00002113 * @tty; tty side of tty
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002114 * @arg: user buffer for result
2115 *
2116 * Copies the user idea of the window size to the kernel. Traditionally
2117 * this is just advisory information but for the Linux console it
2118 * actually has driver level meaning and triggers a VC resize.
2119 *
2120 * Locking:
2121 * Driver dependant. The default do_resize method takes the
2122 * tty termios mutex and ctrl_lock. The console takes its own lock
2123 * then calls into the default method.
2124 */
2125
Alan Coxfc6f6232009-01-02 13:43:17 +00002126static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg)
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002127{
2128 struct winsize tmp_ws;
2129 if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
2130 return -EFAULT;
2131
2132 if (tty->ops->resize)
Alan Coxfc6f6232009-01-02 13:43:17 +00002133 return tty->ops->resize(tty, &tmp_ws);
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002134 else
Alan Coxfc6f6232009-01-02 13:43:17 +00002135 return tty_do_resize(tty, &tmp_ws);
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002136}
2137
2138/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002139 * tioccons - allow admin to move logical console
2140 * @file: the file to become console
2141 *
2142 * Allow the adminstrator to move the redirected console device
2143 *
2144 * Locking: uses redirect_lock to guard the redirect information
2145 */
2146
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147static int tioccons(struct file *file)
2148{
2149 if (!capable(CAP_SYS_ADMIN))
2150 return -EPERM;
2151 if (file->f_op->write == redirected_tty_write) {
2152 struct file *f;
2153 spin_lock(&redirect_lock);
2154 f = redirect;
2155 redirect = NULL;
2156 spin_unlock(&redirect_lock);
2157 if (f)
2158 fput(f);
2159 return 0;
2160 }
2161 spin_lock(&redirect_lock);
2162 if (redirect) {
2163 spin_unlock(&redirect_lock);
2164 return -EBUSY;
2165 }
2166 get_file(file);
2167 redirect = file;
2168 spin_unlock(&redirect_lock);
2169 return 0;
2170}
2171
Alan Coxaf9b8972006-08-27 01:24:01 -07002172/**
2173 * fionbio - non blocking ioctl
2174 * @file: file to set blocking value
2175 * @p: user parameter
2176 *
2177 * Historical tty interfaces had a blocking control ioctl before
2178 * the generic functionality existed. This piece of history is preserved
2179 * in the expected tty API of posix OS's.
2180 *
Alan Cox6146b9a2009-09-19 13:13:19 -07002181 * Locking: none, the open file handle ensures it won't go away.
Alan Coxaf9b8972006-08-27 01:24:01 -07002182 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183
2184static int fionbio(struct file *file, int __user *p)
2185{
2186 int nonblock;
2187
2188 if (get_user(nonblock, p))
2189 return -EFAULT;
2190
Jonathan Corbetdb1dd4d2009-02-06 15:25:24 -07002191 spin_lock(&file->f_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192 if (nonblock)
2193 file->f_flags |= O_NONBLOCK;
2194 else
2195 file->f_flags &= ~O_NONBLOCK;
Jonathan Corbetdb1dd4d2009-02-06 15:25:24 -07002196 spin_unlock(&file->f_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 return 0;
2198}
2199
Alan Coxaf9b8972006-08-27 01:24:01 -07002200/**
2201 * tiocsctty - set controlling tty
2202 * @tty: tty structure
2203 * @arg: user argument
2204 *
2205 * This ioctl is used to manage job control. It permits a session
2206 * leader to set this tty as the controlling tty for the session.
2207 *
2208 * Locking:
Alan Cox28298232006-09-29 02:00:58 -07002209 * Takes tty_mutex() to protect tty instance
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002210 * Takes tasklist_lock internally to walk sessions
2211 * Takes ->siglock() when updating signal->tty
Alan Coxaf9b8972006-08-27 01:24:01 -07002212 */
2213
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214static int tiocsctty(struct tty_struct *tty, int arg)
2215{
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002216 int ret = 0;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002217 if (current->signal->leader && (task_session(current) == tty->session))
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002218 return ret;
2219
2220 mutex_lock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221 /*
2222 * The process must be a session leader and
2223 * not have a controlling tty already.
2224 */
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002225 if (!current->signal->leader || current->signal->tty) {
2226 ret = -EPERM;
2227 goto unlock;
2228 }
2229
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002230 if (tty->session) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 /*
2232 * This tty is already the controlling
2233 * tty for another session group!
2234 */
Alan Cox37bdfb02008-02-08 04:18:47 -08002235 if (arg == 1 && capable(CAP_SYS_ADMIN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236 /*
2237 * Steal it away
2238 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 read_lock(&tasklist_lock);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002240 session_clear_tty(tty->session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 read_unlock(&tasklist_lock);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002242 } else {
2243 ret = -EPERM;
2244 goto unlock;
2245 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246 }
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002247 proc_set_tty(current, tty);
2248unlock:
Alan Cox28298232006-09-29 02:00:58 -07002249 mutex_unlock(&tty_mutex);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002250 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251}
2252
Alan Coxaf9b8972006-08-27 01:24:01 -07002253/**
Alan Cox5d0fdf12008-04-30 00:53:31 -07002254 * tty_get_pgrp - return a ref counted pgrp pid
2255 * @tty: tty to read
2256 *
2257 * Returns a refcounted instance of the pid struct for the process
2258 * group controlling the tty.
2259 */
2260
2261struct pid *tty_get_pgrp(struct tty_struct *tty)
2262{
2263 unsigned long flags;
2264 struct pid *pgrp;
2265
2266 spin_lock_irqsave(&tty->ctrl_lock, flags);
2267 pgrp = get_pid(tty->pgrp);
2268 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
2269
2270 return pgrp;
2271}
2272EXPORT_SYMBOL_GPL(tty_get_pgrp);
2273
2274/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002275 * tiocgpgrp - get process group
2276 * @tty: tty passed by user
2277 * @real_tty: tty side of the tty pased by the user if a pty else the tty
2278 * @p: returned pid
2279 *
2280 * Obtain the process group of the tty. If there is no process group
2281 * return an error.
2282 *
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002283 * Locking: none. Reference to current->signal->tty is safe.
Alan Coxaf9b8972006-08-27 01:24:01 -07002284 */
2285
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
2287{
Alan Cox5d0fdf12008-04-30 00:53:31 -07002288 struct pid *pid;
2289 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290 /*
2291 * (tty == real_tty) is a cheap way of
2292 * testing if the tty is NOT a master pty.
2293 */
2294 if (tty == real_tty && current->signal->tty != real_tty)
2295 return -ENOTTY;
Alan Cox5d0fdf12008-04-30 00:53:31 -07002296 pid = tty_get_pgrp(real_tty);
2297 ret = put_user(pid_vnr(pid), p);
2298 put_pid(pid);
2299 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002300}
2301
Alan Coxaf9b8972006-08-27 01:24:01 -07002302/**
2303 * tiocspgrp - attempt to set process group
2304 * @tty: tty passed by user
2305 * @real_tty: tty side device matching tty passed by user
2306 * @p: pid pointer
2307 *
2308 * Set the process group of the tty to the session passed. Only
2309 * permitted where the tty session is our session.
2310 *
Alan Cox47f86832008-04-30 00:53:30 -07002311 * Locking: RCU, ctrl lock
Alan Coxaf9b8972006-08-27 01:24:01 -07002312 */
2313
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
2315{
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002316 struct pid *pgrp;
2317 pid_t pgrp_nr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 int retval = tty_check_change(real_tty);
Alan Cox47f86832008-04-30 00:53:30 -07002319 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320
2321 if (retval == -EIO)
2322 return -ENOTTY;
2323 if (retval)
2324 return retval;
2325 if (!current->signal->tty ||
2326 (current->signal->tty != real_tty) ||
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002327 (real_tty->session != task_session(current)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328 return -ENOTTY;
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002329 if (get_user(pgrp_nr, p))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330 return -EFAULT;
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002331 if (pgrp_nr < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 return -EINVAL;
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002333 rcu_read_lock();
Pavel Emelyanovb4888932007-10-18 23:40:14 -07002334 pgrp = find_vpid(pgrp_nr);
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002335 retval = -ESRCH;
2336 if (!pgrp)
2337 goto out_unlock;
2338 retval = -EPERM;
2339 if (session_of_pgrp(pgrp) != task_session(current))
2340 goto out_unlock;
2341 retval = 0;
Alan Cox47f86832008-04-30 00:53:30 -07002342 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002343 put_pid(real_tty->pgrp);
2344 real_tty->pgrp = get_pid(pgrp);
Alan Cox47f86832008-04-30 00:53:30 -07002345 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002346out_unlock:
2347 rcu_read_unlock();
2348 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349}
2350
Alan Coxaf9b8972006-08-27 01:24:01 -07002351/**
2352 * tiocgsid - get session id
2353 * @tty: tty passed by user
2354 * @real_tty: tty side of the tty pased by the user if a pty else the tty
2355 * @p: pointer to returned session id
2356 *
2357 * Obtain the session id of the tty. If there is no session
2358 * return an error.
2359 *
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002360 * Locking: none. Reference to current->signal->tty is safe.
Alan Coxaf9b8972006-08-27 01:24:01 -07002361 */
2362
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
2364{
2365 /*
2366 * (tty == real_tty) is a cheap way of
2367 * testing if the tty is NOT a master pty.
2368 */
2369 if (tty == real_tty && current->signal->tty != real_tty)
2370 return -ENOTTY;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002371 if (!real_tty->session)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372 return -ENOTTY;
Pavel Emelyanovb4888932007-10-18 23:40:14 -07002373 return put_user(pid_vnr(real_tty->session), p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374}
2375
Alan Coxaf9b8972006-08-27 01:24:01 -07002376/**
2377 * tiocsetd - set line discipline
2378 * @tty: tty device
2379 * @p: pointer to user data
2380 *
2381 * Set the line discipline according to user request.
2382 *
2383 * Locking: see tty_set_ldisc, this function is just a helper
2384 */
2385
Linus Torvalds1da177e2005-04-16 15:20:36 -07002386static int tiocsetd(struct tty_struct *tty, int __user *p)
2387{
2388 int ldisc;
Alan Cox04f378b2008-04-30 00:53:29 -07002389 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002390
2391 if (get_user(ldisc, p))
2392 return -EFAULT;
Alan Cox04f378b2008-04-30 00:53:29 -07002393
Alan Cox04f378b2008-04-30 00:53:29 -07002394 ret = tty_set_ldisc(tty, ldisc);
Alan Cox04f378b2008-04-30 00:53:29 -07002395
2396 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397}
2398
Alan Coxaf9b8972006-08-27 01:24:01 -07002399/**
2400 * send_break - performed time break
2401 * @tty: device to break on
2402 * @duration: timeout in mS
2403 *
2404 * Perform a timed break on hardware that lacks its own driver level
2405 * timed break functionality.
2406 *
2407 * Locking:
Alan Cox28298232006-09-29 02:00:58 -07002408 * atomic_write_lock serializes
Alan Coxaf9b8972006-08-27 01:24:01 -07002409 *
Alan Coxaf9b8972006-08-27 01:24:01 -07002410 */
2411
Domen Puncerb20f3ae2005-06-25 14:58:42 -07002412static int send_break(struct tty_struct *tty, unsigned int duration)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413{
Alan Cox9e98966c2008-07-22 11:18:03 +01002414 int retval;
2415
2416 if (tty->ops->break_ctl == NULL)
2417 return 0;
2418
2419 if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
2420 retval = tty->ops->break_ctl(tty, duration);
2421 else {
2422 /* Do the work ourselves */
2423 if (tty_write_lock(tty, 0) < 0)
2424 return -EINTR;
2425 retval = tty->ops->break_ctl(tty, -1);
2426 if (retval)
2427 goto out;
2428 if (!signal_pending(current))
2429 msleep_interruptible(duration);
2430 retval = tty->ops->break_ctl(tty, 0);
2431out:
2432 tty_write_unlock(tty);
2433 if (signal_pending(current))
2434 retval = -EINTR;
2435 }
2436 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437}
2438
Alan Coxaf9b8972006-08-27 01:24:01 -07002439/**
Alan Coxf34d7a52008-04-30 00:54:13 -07002440 * tty_tiocmget - get modem status
Alan Coxaf9b8972006-08-27 01:24:01 -07002441 * @tty: tty device
2442 * @file: user file pointer
2443 * @p: pointer to result
2444 *
2445 * Obtain the modem status bits from the tty driver if the feature
2446 * is supported. Return -EINVAL if it is not available.
2447 *
2448 * Locking: none (up to the driver)
2449 */
2450
2451static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452{
2453 int retval = -EINVAL;
2454
Alan Coxf34d7a52008-04-30 00:54:13 -07002455 if (tty->ops->tiocmget) {
2456 retval = tty->ops->tiocmget(tty, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457
2458 if (retval >= 0)
2459 retval = put_user(retval, p);
2460 }
2461 return retval;
2462}
2463
Alan Coxaf9b8972006-08-27 01:24:01 -07002464/**
Alan Coxf34d7a52008-04-30 00:54:13 -07002465 * tty_tiocmset - set modem status
Alan Coxaf9b8972006-08-27 01:24:01 -07002466 * @tty: tty device
2467 * @file: user file pointer
2468 * @cmd: command - clear bits, set bits or set all
2469 * @p: pointer to desired bits
2470 *
2471 * Set the modem status bits from the tty driver if the feature
2472 * is supported. Return -EINVAL if it is not available.
2473 *
2474 * Locking: none (up to the driver)
2475 */
2476
2477static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478 unsigned __user *p)
2479{
Alan Coxae677512008-07-16 21:56:54 +01002480 int retval;
2481 unsigned int set, clear, val;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482
Alan Coxae677512008-07-16 21:56:54 +01002483 if (tty->ops->tiocmset == NULL)
2484 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485
Alan Coxae677512008-07-16 21:56:54 +01002486 retval = get_user(val, p);
2487 if (retval)
2488 return retval;
2489 set = clear = 0;
2490 switch (cmd) {
2491 case TIOCMBIS:
2492 set = val;
2493 break;
2494 case TIOCMBIC:
2495 clear = val;
2496 break;
2497 case TIOCMSET:
2498 set = val;
2499 clear = ~val;
2500 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501 }
Alan Coxae677512008-07-16 21:56:54 +01002502 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
2503 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
2504 return tty->ops->tiocmset(tty, file, set, clear);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505}
2506
Alan Coxe8b70e72009-06-11 12:48:02 +01002507struct tty_struct *tty_pair_get_tty(struct tty_struct *tty)
2508{
2509 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
2510 tty->driver->subtype == PTY_TYPE_MASTER)
2511 tty = tty->link;
2512 return tty;
2513}
2514EXPORT_SYMBOL(tty_pair_get_tty);
2515
2516struct tty_struct *tty_pair_get_pty(struct tty_struct *tty)
2517{
2518 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
2519 tty->driver->subtype == PTY_TYPE_MASTER)
2520 return tty;
2521 return tty->link;
2522}
2523EXPORT_SYMBOL(tty_pair_get_pty);
2524
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525/*
2526 * Split this up, as gcc can choke on it otherwise..
2527 */
Alan Cox04f378b2008-04-30 00:53:29 -07002528long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529{
Nick Piggind996b622010-08-18 04:37:36 +10002530 struct tty_struct *tty = file_tty(file);
2531 struct tty_struct *real_tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 void __user *p = (void __user *)arg;
2533 int retval;
2534 struct tty_ldisc *ld;
Alan Cox04f378b2008-04-30 00:53:29 -07002535 struct inode *inode = file->f_dentry->d_inode;
Alan Cox37bdfb02008-02-08 04:18:47 -08002536
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
2538 return -EINVAL;
2539
Alan Coxe8b70e72009-06-11 12:48:02 +01002540 real_tty = tty_pair_get_tty(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541
2542 /*
2543 * Factor out some common prep work
2544 */
2545 switch (cmd) {
2546 case TIOCSETD:
2547 case TIOCSBRK:
2548 case TIOCCBRK:
2549 case TCSBRK:
Alan Cox37bdfb02008-02-08 04:18:47 -08002550 case TCSBRKP:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 retval = tty_check_change(tty);
2552 if (retval)
2553 return retval;
2554 if (cmd != TIOCCBRK) {
2555 tty_wait_until_sent(tty, 0);
2556 if (signal_pending(current))
2557 return -EINTR;
2558 }
2559 break;
2560 }
2561
Alan Cox9e98966c2008-07-22 11:18:03 +01002562 /*
2563 * Now do the stuff.
2564 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565 switch (cmd) {
Alan Cox37bdfb02008-02-08 04:18:47 -08002566 case TIOCSTI:
2567 return tiocsti(tty, p);
2568 case TIOCGWINSZ:
Alan Cox8f520022008-10-13 10:38:46 +01002569 return tiocgwinsz(real_tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002570 case TIOCSWINSZ:
Alan Coxfc6f6232009-01-02 13:43:17 +00002571 return tiocswinsz(real_tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002572 case TIOCCONS:
2573 return real_tty != tty ? -EINVAL : tioccons(file);
2574 case FIONBIO:
2575 return fionbio(file, p);
2576 case TIOCEXCL:
2577 set_bit(TTY_EXCLUSIVE, &tty->flags);
2578 return 0;
2579 case TIOCNXCL:
2580 clear_bit(TTY_EXCLUSIVE, &tty->flags);
2581 return 0;
2582 case TIOCNOTTY:
2583 if (current->signal->tty != tty)
2584 return -ENOTTY;
2585 no_tty();
2586 return 0;
2587 case TIOCSCTTY:
2588 return tiocsctty(tty, arg);
2589 case TIOCGPGRP:
2590 return tiocgpgrp(tty, real_tty, p);
2591 case TIOCSPGRP:
2592 return tiocspgrp(tty, real_tty, p);
2593 case TIOCGSID:
2594 return tiocgsid(tty, real_tty, p);
2595 case TIOCGETD:
Alan Coxc65c9bc2009-06-11 12:50:12 +01002596 return put_user(tty->ldisc->ops->num, (int __user *)p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002597 case TIOCSETD:
2598 return tiocsetd(tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002599 /*
2600 * Break handling
2601 */
2602 case TIOCSBRK: /* Turn break on, unconditionally */
Alan Coxf34d7a52008-04-30 00:54:13 -07002603 if (tty->ops->break_ctl)
Alan Cox9e98966c2008-07-22 11:18:03 +01002604 return tty->ops->break_ctl(tty, -1);
Alan Cox37bdfb02008-02-08 04:18:47 -08002605 return 0;
Alan Cox37bdfb02008-02-08 04:18:47 -08002606 case TIOCCBRK: /* Turn break off, unconditionally */
Alan Coxf34d7a52008-04-30 00:54:13 -07002607 if (tty->ops->break_ctl)
Alan Cox9e98966c2008-07-22 11:18:03 +01002608 return tty->ops->break_ctl(tty, 0);
Alan Cox37bdfb02008-02-08 04:18:47 -08002609 return 0;
2610 case TCSBRK: /* SVID version: non-zero arg --> no break */
2611 /* non-zero arg means wait for all output data
2612 * to be sent (performed above) but don't send break.
2613 * This is used by the tcdrain() termios function.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614 */
Alan Cox37bdfb02008-02-08 04:18:47 -08002615 if (!arg)
2616 return send_break(tty, 250);
2617 return 0;
2618 case TCSBRKP: /* support for POSIX tcsendbreak() */
2619 return send_break(tty, arg ? arg*100 : 250);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620
Alan Cox37bdfb02008-02-08 04:18:47 -08002621 case TIOCMGET:
2622 return tty_tiocmget(tty, file, p);
2623 case TIOCMSET:
2624 case TIOCMBIC:
2625 case TIOCMBIS:
2626 return tty_tiocmset(tty, file, cmd, p);
2627 case TCFLSH:
2628 switch (arg) {
2629 case TCIFLUSH:
2630 case TCIOFLUSH:
2631 /* flush tty buffer and allow ldisc to process ioctl */
2632 tty_buffer_flush(tty);
Paul Fulghumc5c34d42007-05-12 10:36:55 -07002633 break;
Alan Cox37bdfb02008-02-08 04:18:47 -08002634 }
2635 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 }
Alan Coxf34d7a52008-04-30 00:54:13 -07002637 if (tty->ops->ioctl) {
2638 retval = (tty->ops->ioctl)(tty, file, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639 if (retval != -ENOIOCTLCMD)
2640 return retval;
2641 }
2642 ld = tty_ldisc_ref_wait(tty);
2643 retval = -EINVAL;
Alan Coxa352def2008-07-16 21:53:12 +01002644 if (ld->ops->ioctl) {
2645 retval = ld->ops->ioctl(tty, file, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646 if (retval == -ENOIOCTLCMD)
2647 retval = -EINVAL;
2648 }
2649 tty_ldisc_deref(ld);
2650 return retval;
2651}
2652
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002653#ifdef CONFIG_COMPAT
Alan Cox37bdfb02008-02-08 04:18:47 -08002654static long tty_compat_ioctl(struct file *file, unsigned int cmd,
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002655 unsigned long arg)
2656{
2657 struct inode *inode = file->f_dentry->d_inode;
Nick Piggind996b622010-08-18 04:37:36 +10002658 struct tty_struct *tty = file_tty(file);
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002659 struct tty_ldisc *ld;
2660 int retval = -ENOIOCTLCMD;
2661
2662 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
2663 return -EINVAL;
2664
Alan Coxf34d7a52008-04-30 00:54:13 -07002665 if (tty->ops->compat_ioctl) {
2666 retval = (tty->ops->compat_ioctl)(tty, file, cmd, arg);
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002667 if (retval != -ENOIOCTLCMD)
2668 return retval;
2669 }
2670
2671 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +01002672 if (ld->ops->compat_ioctl)
2673 retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002674 tty_ldisc_deref(ld);
2675
2676 return retval;
2677}
2678#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679
2680/*
2681 * This implements the "Secure Attention Key" --- the idea is to
2682 * prevent trojan horses by killing all processes associated with this
2683 * tty when the user hits the "Secure Attention Key". Required for
2684 * super-paranoid applications --- see the Orange Book for more details.
Alan Cox37bdfb02008-02-08 04:18:47 -08002685 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686 * This code could be nicer; ideally it should send a HUP, wait a few
2687 * seconds, then send a INT, and then a KILL signal. But you then
2688 * have to coordinate with the init process, since all processes associated
2689 * with the current tty must be dead before the new getty is allowed
2690 * to spawn.
2691 *
2692 * Now, if it would be correct ;-/ The current code has a nasty hole -
2693 * it doesn't catch files in flight. We may send the descriptor to ourselves
2694 * via AF_UNIX socket, close it and later fetch from socket. FIXME.
2695 *
2696 * Nasty bug: do_SAK is being called in interrupt context. This can
2697 * deadlock. We punt it up to process context. AKPM - 16Mar2001
2698 */
Eric W. Biederman8b6312f2007-02-10 01:44:34 -08002699void __do_SAK(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002700{
2701#ifdef TTY_SOFT_SAK
2702 tty_hangup(tty);
2703#else
Eric W. Biederman652486f2006-03-28 16:11:02 -08002704 struct task_struct *g, *p;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002705 struct pid *session;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706 int i;
2707 struct file *filp;
Dipankar Sarmabadf1662005-09-09 13:04:10 -07002708 struct fdtable *fdt;
Alan Cox37bdfb02008-02-08 04:18:47 -08002709
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710 if (!tty)
2711 return;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002712 session = tty->session;
Alan Cox37bdfb02008-02-08 04:18:47 -08002713
Dan Carpenterb3f13de2006-12-13 00:35:09 -08002714 tty_ldisc_flush(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715
Alan Coxf34d7a52008-04-30 00:54:13 -07002716 tty_driver_flush_buffer(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -08002717
Linus Torvalds1da177e2005-04-16 15:20:36 -07002718 read_lock(&tasklist_lock);
Eric W. Biederman652486f2006-03-28 16:11:02 -08002719 /* Kill the entire session */
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002720 do_each_pid_task(session, PIDTYPE_SID, p) {
Eric W. Biederman652486f2006-03-28 16:11:02 -08002721 printk(KERN_NOTICE "SAK: killed process %d"
Oleg Nesterov1b0f7ffd2009-04-02 16:58:39 -07002722 " (%s): task_session(p)==tty->session\n",
Pavel Emelyanovba25f9d2007-10-18 23:40:40 -07002723 task_pid_nr(p), p->comm);
Eric W. Biederman652486f2006-03-28 16:11:02 -08002724 send_sig(SIGKILL, p, 1);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002725 } while_each_pid_task(session, PIDTYPE_SID, p);
Eric W. Biederman652486f2006-03-28 16:11:02 -08002726 /* Now kill any processes that happen to have the
2727 * tty open.
2728 */
2729 do_each_thread(g, p) {
2730 if (p->signal->tty == tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731 printk(KERN_NOTICE "SAK: killed process %d"
Oleg Nesterov1b0f7ffd2009-04-02 16:58:39 -07002732 " (%s): task_session(p)==tty->session\n",
Pavel Emelyanovba25f9d2007-10-18 23:40:40 -07002733 task_pid_nr(p), p->comm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734 send_sig(SIGKILL, p, 1);
2735 continue;
2736 }
2737 task_lock(p);
2738 if (p->files) {
Dipankar Sarmaca99c1d2006-04-18 22:21:46 -07002739 /*
2740 * We don't take a ref to the file, so we must
2741 * hold ->file_lock instead.
2742 */
2743 spin_lock(&p->files->file_lock);
Dipankar Sarmabadf1662005-09-09 13:04:10 -07002744 fdt = files_fdtable(p->files);
Alan Cox37bdfb02008-02-08 04:18:47 -08002745 for (i = 0; i < fdt->max_fds; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746 filp = fcheck_files(p->files, i);
2747 if (!filp)
2748 continue;
2749 if (filp->f_op->read == tty_read &&
Nick Piggind996b622010-08-18 04:37:36 +10002750 file_tty(filp) == tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751 printk(KERN_NOTICE "SAK: killed process %d"
2752 " (%s): fd#%d opened to the tty\n",
Pavel Emelyanovba25f9d2007-10-18 23:40:40 -07002753 task_pid_nr(p), p->comm, i);
Eric W. Biederman20ac9432006-04-13 04:49:07 -06002754 force_sig(SIGKILL, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755 break;
2756 }
2757 }
Dipankar Sarmaca99c1d2006-04-18 22:21:46 -07002758 spin_unlock(&p->files->file_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759 }
2760 task_unlock(p);
Eric W. Biederman652486f2006-03-28 16:11:02 -08002761 } while_each_thread(g, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762 read_unlock(&tasklist_lock);
2763#endif
2764}
2765
Eric W. Biederman8b6312f2007-02-10 01:44:34 -08002766static void do_SAK_work(struct work_struct *work)
2767{
2768 struct tty_struct *tty =
2769 container_of(work, struct tty_struct, SAK_work);
2770 __do_SAK(tty);
2771}
2772
Linus Torvalds1da177e2005-04-16 15:20:36 -07002773/*
2774 * The tq handling here is a little racy - tty->SAK_work may already be queued.
2775 * Fortunately we don't need to worry, because if ->SAK_work is already queued,
2776 * the values which we write to it will be identical to the values which it
2777 * already has. --akpm
2778 */
2779void do_SAK(struct tty_struct *tty)
2780{
2781 if (!tty)
2782 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783 schedule_work(&tty->SAK_work);
2784}
2785
2786EXPORT_SYMBOL(do_SAK);
2787
Dmitry Eremin-Solenikov30004ac2010-08-09 18:22:49 +04002788static int dev_match_devt(struct device *dev, void *data)
2789{
2790 dev_t *devt = data;
2791 return dev->devt == *devt;
2792}
2793
2794/* Must put_device() after it's unused! */
2795static struct device *tty_get_device(struct tty_struct *tty)
2796{
2797 dev_t devt = tty_devnum(tty);
2798 return class_find_device(tty_class, NULL, &devt, dev_match_devt);
2799}
2800
2801
Alan Coxaf9b8972006-08-27 01:24:01 -07002802/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002803 * initialize_tty_struct
2804 * @tty: tty to initialize
2805 *
2806 * This subroutine initializes a tty structure that has been newly
2807 * allocated.
2808 *
2809 * Locking: none - tty in question must not be exposed at this point
Linus Torvalds1da177e2005-04-16 15:20:36 -07002810 */
Alan Coxaf9b8972006-08-27 01:24:01 -07002811
Alan Coxbf970ee2008-10-13 10:42:39 +01002812void initialize_tty_struct(struct tty_struct *tty,
2813 struct tty_driver *driver, int idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814{
2815 memset(tty, 0, sizeof(struct tty_struct));
Alan Cox9c9f4de2008-10-13 10:37:26 +01002816 kref_init(&tty->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 tty->magic = TTY_MAGIC;
Alan Cox01e1abb2008-07-22 11:16:55 +01002818 tty_ldisc_init(tty);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002819 tty->session = NULL;
2820 tty->pgrp = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 tty->overrun_time = jiffies;
Alan Cox33f0f882006-01-09 20:54:13 -08002822 tty->buf.head = tty->buf.tail = NULL;
2823 tty_buffer_init(tty);
Arjan van de Ven5785c952006-09-29 02:00:43 -07002824 mutex_init(&tty->termios_mutex);
Alan Coxc65c9bc2009-06-11 12:50:12 +01002825 mutex_init(&tty->ldisc_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 init_waitqueue_head(&tty->write_wait);
2827 init_waitqueue_head(&tty->read_wait);
David Howells65f27f32006-11-22 14:55:48 +00002828 INIT_WORK(&tty->hangup_work, do_tty_hangup);
Ingo Molnar70522e12006-03-23 03:00:31 -08002829 mutex_init(&tty->atomic_read_lock);
2830 mutex_init(&tty->atomic_write_lock);
Joe Petersona88a69c2009-01-02 13:40:53 +00002831 mutex_init(&tty->output_lock);
2832 mutex_init(&tty->echo_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 spin_lock_init(&tty->read_lock);
Alan Cox04f378b2008-04-30 00:53:29 -07002834 spin_lock_init(&tty->ctrl_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 INIT_LIST_HEAD(&tty->tty_files);
Eric W. Biederman7f1f86a2007-02-13 14:38:58 -07002836 INIT_WORK(&tty->SAK_work, do_SAK_work);
Alan Coxbf970ee2008-10-13 10:42:39 +01002837
2838 tty->driver = driver;
2839 tty->ops = driver->ops;
2840 tty->index = idx;
2841 tty_line_name(driver, idx, tty->name);
Dmitry Eremin-Solenikov30004ac2010-08-09 18:22:49 +04002842 tty->dev = tty_get_device(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843}
2844
Alan Coxf34d7a52008-04-30 00:54:13 -07002845/**
2846 * tty_put_char - write one character to a tty
2847 * @tty: tty
2848 * @ch: character
2849 *
2850 * Write one byte to the tty using the provided put_char method
2851 * if present. Returns the number of characters successfully output.
2852 *
2853 * Note: the specific put_char operation in the driver layer may go
2854 * away soon. Don't call it directly, use this method
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855 */
Alan Coxaf9b8972006-08-27 01:24:01 -07002856
Alan Coxf34d7a52008-04-30 00:54:13 -07002857int tty_put_char(struct tty_struct *tty, unsigned char ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858{
Alan Coxf34d7a52008-04-30 00:54:13 -07002859 if (tty->ops->put_char)
2860 return tty->ops->put_char(tty, ch);
2861 return tty->ops->write(tty, &ch, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862}
Alan Coxf34d7a52008-04-30 00:54:13 -07002863EXPORT_SYMBOL_GPL(tty_put_char);
2864
Alan Coxd81ed102008-10-13 10:41:42 +01002865struct class *tty_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866
2867/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002868 * tty_register_device - register a tty device
2869 * @driver: the tty driver that describes the tty device
2870 * @index: the index in the tty driver for this tty device
2871 * @device: a struct device that is associated with this tty device.
2872 * This field is optional, if there is no known struct device
2873 * for this tty device it can be set to NULL safely.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874 *
Greg Kroah-Hartman01107d32006-08-07 22:19:37 -07002875 * Returns a pointer to the struct device for this tty device
2876 * (or ERR_PTR(-EFOO) on error).
Hansjoerg Lipp1cdcb6b2006-04-22 18:36:53 +02002877 *
Alan Coxaf9b8972006-08-27 01:24:01 -07002878 * This call is required to be made to register an individual tty device
2879 * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If
2880 * that bit is not set, this function should not be called by a tty
2881 * driver.
2882 *
2883 * Locking: ??
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884 */
Alan Coxaf9b8972006-08-27 01:24:01 -07002885
Greg Kroah-Hartman01107d32006-08-07 22:19:37 -07002886struct device *tty_register_device(struct tty_driver *driver, unsigned index,
2887 struct device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888{
2889 char name[64];
2890 dev_t dev = MKDEV(driver->major, driver->minor_start) + index;
2891
2892 if (index >= driver->num) {
2893 printk(KERN_ERR "Attempt to register invalid tty line number "
2894 " (%d).\n", index);
Hansjoerg Lipp1cdcb6b2006-04-22 18:36:53 +02002895 return ERR_PTR(-EINVAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 }
2897
Linus Torvalds1da177e2005-04-16 15:20:36 -07002898 if (driver->type == TTY_DRIVER_TYPE_PTY)
2899 pty_line_name(driver, index, name);
2900 else
2901 tty_line_name(driver, index, name);
Hansjoerg Lipp1cdcb6b2006-04-22 18:36:53 +02002902
Greg Kroah-Hartman03457cd2008-07-21 20:03:34 -07002903 return device_create(tty_class, device, dev, NULL, name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904}
Alan Cox7d7b93c2008-10-13 10:42:09 +01002905EXPORT_SYMBOL(tty_register_device);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906
2907/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002908 * tty_unregister_device - unregister a tty device
2909 * @driver: the tty driver that describes the tty device
2910 * @index: the index in the tty driver for this tty device
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 *
Alan Coxaf9b8972006-08-27 01:24:01 -07002912 * If a tty device is registered with a call to tty_register_device() then
2913 * this function must be called when the tty device is gone.
2914 *
2915 * Locking: ??
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916 */
Alan Coxaf9b8972006-08-27 01:24:01 -07002917
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918void tty_unregister_device(struct tty_driver *driver, unsigned index)
2919{
Alan Cox37bdfb02008-02-08 04:18:47 -08002920 device_destroy(tty_class,
2921 MKDEV(driver->major, driver->minor_start) + index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923EXPORT_SYMBOL(tty_unregister_device);
2924
2925struct tty_driver *alloc_tty_driver(int lines)
2926{
2927 struct tty_driver *driver;
2928
Jean Delvare506eb992007-07-15 23:40:14 -07002929 driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 if (driver) {
Alan Cox7d7b93c2008-10-13 10:42:09 +01002931 kref_init(&driver->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 driver->magic = TTY_DRIVER_MAGIC;
2933 driver->num = lines;
2934 /* later we'll move allocation of tables here */
2935 }
2936 return driver;
2937}
Alan Cox7d7b93c2008-10-13 10:42:09 +01002938EXPORT_SYMBOL(alloc_tty_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939
Alan Cox7d7b93c2008-10-13 10:42:09 +01002940static void destruct_tty_driver(struct kref *kref)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941{
Alan Cox7d7b93c2008-10-13 10:42:09 +01002942 struct tty_driver *driver = container_of(kref, struct tty_driver, kref);
2943 int i;
2944 struct ktermios *tp;
2945 void *p;
2946
2947 if (driver->flags & TTY_DRIVER_INSTALLED) {
2948 /*
2949 * Free the termios and termios_locked structures because
2950 * we don't want to get memory leaks when modular tty
2951 * drivers are removed from the kernel.
2952 */
2953 for (i = 0; i < driver->num; i++) {
2954 tp = driver->termios[i];
2955 if (tp) {
2956 driver->termios[i] = NULL;
2957 kfree(tp);
2958 }
Alan Cox7d7b93c2008-10-13 10:42:09 +01002959 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
2960 tty_unregister_device(driver, i);
2961 }
2962 p = driver->ttys;
2963 proc_tty_unregister_driver(driver);
2964 driver->ttys = NULL;
Alan Coxfe6e29f2008-10-13 10:44:08 +01002965 driver->termios = NULL;
Alan Cox7d7b93c2008-10-13 10:42:09 +01002966 kfree(p);
2967 cdev_del(&driver->cdev);
2968 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969 kfree(driver);
2970}
2971
Alan Cox7d7b93c2008-10-13 10:42:09 +01002972void tty_driver_kref_put(struct tty_driver *driver)
2973{
2974 kref_put(&driver->kref, destruct_tty_driver);
2975}
2976EXPORT_SYMBOL(tty_driver_kref_put);
2977
Jeff Dikeb68e31d2006-10-02 02:17:18 -07002978void tty_set_operations(struct tty_driver *driver,
2979 const struct tty_operations *op)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980{
Alan Coxf34d7a52008-04-30 00:54:13 -07002981 driver->ops = op;
2982};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983EXPORT_SYMBOL(tty_set_operations);
2984
Alan Cox7d7b93c2008-10-13 10:42:09 +01002985void put_tty_driver(struct tty_driver *d)
2986{
2987 tty_driver_kref_put(d);
2988}
2989EXPORT_SYMBOL(put_tty_driver);
2990
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991/*
2992 * Called by a tty driver to register itself.
2993 */
2994int tty_register_driver(struct tty_driver *driver)
2995{
2996 int error;
Alan Cox37bdfb02008-02-08 04:18:47 -08002997 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 dev_t dev;
2999 void **p = NULL;
3000
Andy Whitcroft543691a62007-05-06 14:49:33 -07003001 if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
Alan Coxfe6e29f2008-10-13 10:44:08 +01003002 p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003003 if (!p)
3004 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 }
3006
3007 if (!driver->major) {
Alan Cox37bdfb02008-02-08 04:18:47 -08003008 error = alloc_chrdev_region(&dev, driver->minor_start,
3009 driver->num, driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010 if (!error) {
3011 driver->major = MAJOR(dev);
3012 driver->minor_start = MINOR(dev);
3013 }
3014 } else {
3015 dev = MKDEV(driver->major, driver->minor_start);
Geert Uytterhoevene5717c42007-02-20 15:45:21 +01003016 error = register_chrdev_region(dev, driver->num, driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017 }
3018 if (error < 0) {
3019 kfree(p);
3020 return error;
3021 }
3022
3023 if (p) {
3024 driver->ttys = (struct tty_struct **)p;
Alan Coxedc6afc2006-12-08 02:38:44 -08003025 driver->termios = (struct ktermios **)(p + driver->num);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026 } else {
3027 driver->ttys = NULL;
3028 driver->termios = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029 }
3030
3031 cdev_init(&driver->cdev, &tty_fops);
3032 driver->cdev.owner = driver->owner;
3033 error = cdev_add(&driver->cdev, dev, driver->num);
3034 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003035 unregister_chrdev_region(dev, driver->num);
3036 driver->ttys = NULL;
Alan Coxfe6e29f2008-10-13 10:44:08 +01003037 driver->termios = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038 kfree(p);
3039 return error;
3040 }
3041
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003042 mutex_lock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003043 list_add(&driver->tty_drivers, &tty_drivers);
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003044 mutex_unlock(&tty_mutex);
Alan Cox37bdfb02008-02-08 04:18:47 -08003045
3046 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
3047 for (i = 0; i < driver->num; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003048 tty_register_device(driver, i, NULL);
3049 }
3050 proc_tty_register_driver(driver);
Alan Cox7d7b93c2008-10-13 10:42:09 +01003051 driver->flags |= TTY_DRIVER_INSTALLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003052 return 0;
3053}
3054
3055EXPORT_SYMBOL(tty_register_driver);
3056
3057/*
3058 * Called by a tty driver to unregister itself.
3059 */
3060int tty_unregister_driver(struct tty_driver *driver)
3061{
Alan Cox7d7b93c2008-10-13 10:42:09 +01003062#if 0
3063 /* FIXME */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064 if (driver->refcount)
3065 return -EBUSY;
Alan Cox7d7b93c2008-10-13 10:42:09 +01003066#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
3068 driver->num);
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003069 mutex_lock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070 list_del(&driver->tty_drivers);
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003071 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 return 0;
3073}
Alan Cox7d7b93c2008-10-13 10:42:09 +01003074
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075EXPORT_SYMBOL(tty_unregister_driver);
3076
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003077dev_t tty_devnum(struct tty_struct *tty)
3078{
3079 return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
3080}
3081EXPORT_SYMBOL(tty_devnum);
3082
3083void proc_clear_tty(struct task_struct *p)
3084{
Arjan van de Ven7c3b1dc2008-10-15 10:52:34 +01003085 unsigned long flags;
Alan Cox9c9f4de2008-10-13 10:37:26 +01003086 struct tty_struct *tty;
Arjan van de Ven7c3b1dc2008-10-15 10:52:34 +01003087 spin_lock_irqsave(&p->sighand->siglock, flags);
Alan Cox9c9f4de2008-10-13 10:37:26 +01003088 tty = p->signal->tty;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003089 p->signal->tty = NULL;
Arjan van de Ven7c3b1dc2008-10-15 10:52:34 +01003090 spin_unlock_irqrestore(&p->sighand->siglock, flags);
Alan Cox9c9f4de2008-10-13 10:37:26 +01003091 tty_kref_put(tty);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003092}
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003093
Alan Cox47f86832008-04-30 00:53:30 -07003094/* Called under the sighand lock */
3095
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -07003096static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003097{
3098 if (tty) {
Alan Cox47f86832008-04-30 00:53:30 -07003099 unsigned long flags;
3100 /* We should not have a session or pgrp to put here but.... */
3101 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermand9c1e9a2007-03-18 12:45:44 -06003102 put_pid(tty->session);
3103 put_pid(tty->pgrp);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08003104 tty->pgrp = get_pid(task_pgrp(tsk));
Alan Cox47f86832008-04-30 00:53:30 -07003105 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
3106 tty->session = get_pid(task_session(tsk));
Alan Cox9c9f4de2008-10-13 10:37:26 +01003107 if (tsk->signal->tty) {
3108 printk(KERN_DEBUG "tty not NULL!!\n");
3109 tty_kref_put(tsk->signal->tty);
3110 }
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003111 }
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -07003112 put_pid(tsk->signal->tty_old_pgrp);
Alan Cox9c9f4de2008-10-13 10:37:26 +01003113 tsk->signal->tty = tty_kref_get(tty);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08003114 tsk->signal->tty_old_pgrp = NULL;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003115}
3116
Eric W. Biederman98a27ba2007-05-08 00:26:56 -07003117static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003118{
3119 spin_lock_irq(&tsk->sighand->siglock);
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -07003120 __proc_set_tty(tsk, tty);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003121 spin_unlock_irq(&tsk->sighand->siglock);
3122}
3123
3124struct tty_struct *get_current_tty(void)
3125{
3126 struct tty_struct *tty;
Alan Cox934e6eb2008-10-13 10:40:43 +01003127 unsigned long flags;
3128
3129 spin_lock_irqsave(&current->sighand->siglock, flags);
Alan Cox452a00d2008-10-13 10:39:13 +01003130 tty = tty_kref_get(current->signal->tty);
Alan Cox934e6eb2008-10-13 10:40:43 +01003131 spin_unlock_irqrestore(&current->sighand->siglock, flags);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003132 return tty;
3133}
Heiko Carstensa311f742006-12-13 00:33:41 -08003134EXPORT_SYMBOL_GPL(get_current_tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135
Alan Coxd81ed102008-10-13 10:41:42 +01003136void tty_default_fops(struct file_operations *fops)
3137{
3138 *fops = tty_fops;
3139}
3140
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141/*
3142 * Initialize the console device. This is called *early*, so
3143 * we can't necessarily depend on lots of kernel help here.
3144 * Just do some early initializations, and do the complex setup
3145 * later.
3146 */
3147void __init console_init(void)
3148{
3149 initcall_t *call;
3150
3151 /* Setup the default TTY line discipline. */
Alan Cox01e1abb2008-07-22 11:16:55 +01003152 tty_ldisc_begin();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153
3154 /*
Alan Cox37bdfb02008-02-08 04:18:47 -08003155 * set up the console device so that later boot sequences can
Linus Torvalds1da177e2005-04-16 15:20:36 -07003156 * inform about problems etc..
3157 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158 call = __con_initcall_start;
3159 while (call < __con_initcall_end) {
3160 (*call)();
3161 call++;
3162 }
3163}
3164
Kay Sieverse454cea2009-09-18 23:01:12 +02003165static char *tty_devnode(struct device *dev, mode_t *mode)
3166{
3167 if (!mode)
3168 return NULL;
3169 if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
3170 dev->devt == MKDEV(TTYAUX_MAJOR, 2))
3171 *mode = 0666;
3172 return NULL;
3173}
3174
Linus Torvalds1da177e2005-04-16 15:20:36 -07003175static int __init tty_class_init(void)
3176{
gregkh@suse.de7fe845d2005-03-15 14:23:15 -08003177 tty_class = class_create(THIS_MODULE, "tty");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178 if (IS_ERR(tty_class))
3179 return PTR_ERR(tty_class);
Kay Sieverse454cea2009-09-18 23:01:12 +02003180 tty_class->devnode = tty_devnode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181 return 0;
3182}
3183
3184postcore_initcall(tty_class_init);
3185
3186/* 3/2004 jmc: why do these devices exist? */
3187
3188static struct cdev tty_cdev, console_cdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189
3190/*
3191 * Ok, now we can initialize the rest of the tty devices and can count
3192 * on memory allocations, interrupts etc..
3193 */
David Howells31d1d482010-08-06 16:34:43 +01003194int __init tty_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195{
3196 cdev_init(&tty_cdev, &tty_fops);
3197 if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
3198 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
3199 panic("Couldn't register /dev/tty driver\n");
Alan Coxd81ed102008-10-13 10:41:42 +01003200 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
Greg Kroah-Hartman47aa5792008-05-21 12:52:33 -07003201 "tty");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003202
3203 cdev_init(&console_cdev, &console_fops);
3204 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
3205 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
3206 panic("Couldn't register /dev/console driver\n");
Alan Coxd81ed102008-10-13 10:41:42 +01003207 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
Greg Kroah-Hartman47aa5792008-05-21 12:52:33 -07003208 "console");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210#ifdef CONFIG_VT
Alan Coxd81ed102008-10-13 10:41:42 +01003211 vty_init(&console_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003212#endif
3213 return 0;
3214}
David Howells31d1d482010-08-06 16:34:43 +01003215