blob: 613c852ee0feced279c50f6850e9e30c7c870111 [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{
186 kfree(tty->write_buf);
Alan Cox33f0f882006-01-09 20:54:13 -0800187 tty_buffer_free_all(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 kfree(tty);
189}
190
Nick Piggind996b622010-08-18 04:37:36 +1000191static inline struct tty_struct *file_tty(struct file *file)
192{
193 return ((struct tty_file_private *)file->private_data)->tty;
194}
195
196/* Associate a new file with the tty structure */
197void tty_add_file(struct tty_struct *tty, struct file *file)
198{
199 struct tty_file_private *priv;
200
201 /* XXX: must implement proper error handling in callers */
202 priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL);
203
204 priv->tty = tty;
205 priv->file = file;
206 file->private_data = priv;
207
208 spin_lock(&tty_files_lock);
209 list_add(&priv->list, &tty->tty_files);
210 spin_unlock(&tty_files_lock);
211}
212
213/* Delete file from its tty */
214void tty_del_file(struct file *file)
215{
216 struct tty_file_private *priv = file->private_data;
217
218 spin_lock(&tty_files_lock);
219 list_del(&priv->list);
220 spin_unlock(&tty_files_lock);
221 file->private_data = NULL;
222 kfree(priv);
223}
224
225
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)
227
Alan Coxaf9b8972006-08-27 01:24:01 -0700228/**
229 * tty_name - return tty naming
230 * @tty: tty structure
231 * @buf: buffer for output
232 *
233 * Convert a tty structure into a name. The name reflects the kernel
234 * naming policy and if udev is in use may not reflect user space
235 *
236 * Locking: none
237 */
238
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239char *tty_name(struct tty_struct *tty, char *buf)
240{
241 if (!tty) /* Hmm. NULL pointer. That's fun. */
242 strcpy(buf, "NULL tty");
243 else
244 strcpy(buf, tty->name);
245 return buf;
246}
247
248EXPORT_SYMBOL(tty_name);
249
Andrew Mortond769a662005-05-05 16:15:50 -0700250int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 const char *routine)
252{
253#ifdef TTY_PARANOIA_CHECK
254 if (!tty) {
255 printk(KERN_WARNING
256 "null TTY for (%d:%d) in %s\n",
257 imajor(inode), iminor(inode), routine);
258 return 1;
259 }
260 if (tty->magic != TTY_MAGIC) {
261 printk(KERN_WARNING
262 "bad magic number for tty struct (%d:%d) in %s\n",
263 imajor(inode), iminor(inode), routine);
264 return 1;
265 }
266#endif
267 return 0;
268}
269
270static int check_tty_count(struct tty_struct *tty, const char *routine)
271{
272#ifdef CHECK_TTY_COUNT
273 struct list_head *p;
274 int count = 0;
Alan Cox37bdfb02008-02-08 04:18:47 -0800275
Nick Pigginee2ffa02010-08-18 04:37:35 +1000276 spin_lock(&tty_files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 list_for_each(p, &tty->tty_files) {
278 count++;
279 }
Nick Pigginee2ffa02010-08-18 04:37:35 +1000280 spin_unlock(&tty_files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
282 tty->driver->subtype == PTY_TYPE_SLAVE &&
283 tty->link && tty->link->count)
284 count++;
285 if (tty->count != count) {
286 printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) "
287 "!= #fd's(%d) in %s\n",
288 tty->name, tty->count, count, routine);
289 return count;
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800290 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291#endif
292 return 0;
293}
294
Alan Coxaf9b8972006-08-27 01:24:01 -0700295/**
Alan Coxaf9b8972006-08-27 01:24:01 -0700296 * get_tty_driver - find device of a tty
297 * @dev_t: device identifier
298 * @index: returns the index of the tty
299 *
300 * This routine returns a tty driver structure, given a device number
301 * and also passes back the index number.
302 *
303 * Locking: caller must hold tty_mutex
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 */
Alan Coxaf9b8972006-08-27 01:24:01 -0700305
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306static struct tty_driver *get_tty_driver(dev_t device, int *index)
307{
308 struct tty_driver *p;
309
310 list_for_each_entry(p, &tty_drivers, tty_drivers) {
311 dev_t base = MKDEV(p->major, p->minor_start);
312 if (device < base || device >= base + p->num)
313 continue;
314 *index = device - base;
Alan Cox7d7b93c2008-10-13 10:42:09 +0100315 return tty_driver_kref_get(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 }
317 return NULL;
318}
319
Jason Wesself2d937f2008-04-17 20:05:37 +0200320#ifdef CONFIG_CONSOLE_POLL
321
322/**
323 * tty_find_polling_driver - find device of a polled tty
324 * @name: name string to match
325 * @line: pointer to resulting tty line nr
326 *
327 * This routine returns a tty driver structure, given a name
328 * and the condition that the tty driver is capable of polled
329 * operation.
330 */
331struct tty_driver *tty_find_polling_driver(char *name, int *line)
332{
333 struct tty_driver *p, *res = NULL;
334 int tty_line = 0;
Jason Wessel0dca0fd2008-09-26 10:36:42 -0500335 int len;
Alan Cox5f0878a2009-06-11 12:46:41 +0100336 char *str, *stp;
Jason Wesself2d937f2008-04-17 20:05:37 +0200337
Jason Wessel0dca0fd2008-09-26 10:36:42 -0500338 for (str = name; *str; str++)
339 if ((*str >= '0' && *str <= '9') || *str == ',')
340 break;
341 if (!*str)
342 return NULL;
343
344 len = str - name;
345 tty_line = simple_strtoul(str, &str, 10);
346
Jason Wesself2d937f2008-04-17 20:05:37 +0200347 mutex_lock(&tty_mutex);
348 /* Search through the tty devices to look for a match */
349 list_for_each_entry(p, &tty_drivers, tty_drivers) {
Jason Wessel0dca0fd2008-09-26 10:36:42 -0500350 if (strncmp(name, p->name, len) != 0)
351 continue;
Alan Cox5f0878a2009-06-11 12:46:41 +0100352 stp = str;
353 if (*stp == ',')
354 stp++;
355 if (*stp == '\0')
356 stp = NULL;
Jason Wesself2d937f2008-04-17 20:05:37 +0200357
Nathael Pajani6eb68d62010-09-02 16:06:16 +0200358 if (tty_line >= 0 && tty_line < p->num && p->ops &&
Alan Cox5f0878a2009-06-11 12:46:41 +0100359 p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
Alan Cox7d7b93c2008-10-13 10:42:09 +0100360 res = tty_driver_kref_get(p);
Jason Wesself2d937f2008-04-17 20:05:37 +0200361 *line = tty_line;
362 break;
363 }
364 }
365 mutex_unlock(&tty_mutex);
366
367 return res;
368}
369EXPORT_SYMBOL_GPL(tty_find_polling_driver);
370#endif
371
Alan Coxaf9b8972006-08-27 01:24:01 -0700372/**
373 * tty_check_change - check for POSIX terminal changes
374 * @tty: tty to check
375 *
376 * If we try to write to, or set the state of, a terminal and we're
377 * not in the foreground, send a SIGTTOU. If the signal is blocked or
378 * ignored, go ahead and perform the operation. (POSIX 7.2)
379 *
Alan Cox978e5952008-04-30 00:53:59 -0700380 * Locking: ctrl_lock
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 */
Alan Coxaf9b8972006-08-27 01:24:01 -0700382
Alan Cox37bdfb02008-02-08 04:18:47 -0800383int tty_check_change(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384{
Alan Cox47f86832008-04-30 00:53:30 -0700385 unsigned long flags;
386 int ret = 0;
387
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 if (current->signal->tty != tty)
389 return 0;
Alan Cox47f86832008-04-30 00:53:30 -0700390
391 spin_lock_irqsave(&tty->ctrl_lock, flags);
392
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800393 if (!tty->pgrp) {
394 printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
Andrew Morton9ffee4c2008-05-14 16:05:58 -0700395 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 }
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800397 if (task_pgrp(current) == tty->pgrp)
Andrew Morton9ffee4c2008-05-14 16:05:58 -0700398 goto out_unlock;
399 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 if (is_ignored(SIGTTOU))
Alan Cox47f86832008-04-30 00:53:30 -0700401 goto out;
402 if (is_current_pgrp_orphaned()) {
403 ret = -EIO;
404 goto out;
405 }
Oleg Nesterov040b6362007-06-01 00:46:53 -0700406 kill_pgrp(task_pgrp(current), SIGTTOU, 1);
407 set_thread_flag(TIF_SIGPENDING);
Alan Cox47f86832008-04-30 00:53:30 -0700408 ret = -ERESTARTSYS;
409out:
Andrew Morton9ffee4c2008-05-14 16:05:58 -0700410 return ret;
411out_unlock:
Alan Cox47f86832008-04-30 00:53:30 -0700412 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
413 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414}
415
416EXPORT_SYMBOL(tty_check_change);
417
Alan Cox37bdfb02008-02-08 04:18:47 -0800418static ssize_t hung_up_tty_read(struct file *file, char __user *buf,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 size_t count, loff_t *ppos)
420{
421 return 0;
422}
423
Alan Cox37bdfb02008-02-08 04:18:47 -0800424static ssize_t hung_up_tty_write(struct file *file, const char __user *buf,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 size_t count, loff_t *ppos)
426{
427 return -EIO;
428}
429
430/* No kernel lock held - none needed ;) */
Alan Cox37bdfb02008-02-08 04:18:47 -0800431static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432{
433 return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
434}
435
Alan Cox04f378b2008-04-30 00:53:29 -0700436static long hung_up_tty_ioctl(struct file *file, unsigned int cmd,
437 unsigned long arg)
Paul Fulghum38ad2ed2007-06-16 10:15:55 -0700438{
439 return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
440}
441
Alan Cox37bdfb02008-02-08 04:18:47 -0800442static long hung_up_tty_compat_ioctl(struct file *file,
Paul Fulghum38ad2ed2007-06-16 10:15:55 -0700443 unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444{
445 return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
446}
447
Arjan van de Ven62322d22006-07-03 00:24:21 -0700448static const struct file_operations tty_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 .llseek = no_llseek,
450 .read = tty_read,
451 .write = tty_write,
452 .poll = tty_poll,
Alan Cox04f378b2008-04-30 00:53:29 -0700453 .unlocked_ioctl = tty_ioctl,
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700454 .compat_ioctl = tty_compat_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 .open = tty_open,
456 .release = tty_release,
457 .fasync = tty_fasync,
458};
459
Arjan van de Ven62322d22006-07-03 00:24:21 -0700460static const struct file_operations console_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 .llseek = no_llseek,
462 .read = tty_read,
463 .write = redirected_tty_write,
464 .poll = tty_poll,
Alan Cox04f378b2008-04-30 00:53:29 -0700465 .unlocked_ioctl = tty_ioctl,
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700466 .compat_ioctl = tty_compat_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 .open = tty_open,
468 .release = tty_release,
469 .fasync = tty_fasync,
470};
471
Arjan van de Ven62322d22006-07-03 00:24:21 -0700472static const struct file_operations hung_up_tty_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 .llseek = no_llseek,
474 .read = hung_up_tty_read,
475 .write = hung_up_tty_write,
476 .poll = hung_up_tty_poll,
Alan Cox04f378b2008-04-30 00:53:29 -0700477 .unlocked_ioctl = hung_up_tty_ioctl,
Paul Fulghum38ad2ed2007-06-16 10:15:55 -0700478 .compat_ioctl = hung_up_tty_compat_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 .release = tty_release,
480};
481
482static DEFINE_SPINLOCK(redirect_lock);
483static struct file *redirect;
484
485/**
486 * tty_wakeup - request more data
487 * @tty: terminal
488 *
489 * Internal and external helper for wakeups of tty. This function
490 * informs the line discipline if present that the driver is ready
491 * to receive more output data.
492 */
Alan Cox37bdfb02008-02-08 04:18:47 -0800493
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494void tty_wakeup(struct tty_struct *tty)
495{
496 struct tty_ldisc *ld;
Alan Cox37bdfb02008-02-08 04:18:47 -0800497
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
499 ld = tty_ldisc_ref(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -0800500 if (ld) {
Alan Coxa352def2008-07-16 21:53:12 +0100501 if (ld->ops->write_wakeup)
502 ld->ops->write_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 tty_ldisc_deref(ld);
504 }
505 }
Davide Libenzi4b194492009-03-31 15:24:24 -0700506 wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507}
508
509EXPORT_SYMBOL_GPL(tty_wakeup);
510
511/**
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200512 * __tty_hangup - actual handler for hangup events
David Howells65f27f32006-11-22 14:55:48 +0000513 * @work: tty device
Alan Coxaf9b8972006-08-27 01:24:01 -0700514 *
Alan Cox1bad8792008-07-22 23:38:04 +0100515 * This can be called by the "eventd" kernel thread. That is process
Alan Coxaf9b8972006-08-27 01:24:01 -0700516 * synchronous but doesn't hold any locks, so we need to make sure we
517 * have the appropriate locks for what we're doing.
518 *
519 * The hangup event clears any pending redirections onto the hung up
520 * device. It ensures future writes will error and it does the needed
521 * line discipline hangup and signal delivery. The tty object itself
522 * remains intact.
523 *
524 * Locking:
Arnd Bergmannec79d602010-06-01 22:53:01 +0200525 * BTM
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800526 * redirect lock for undoing redirection
527 * file list lock for manipulating list of ttys
528 * tty_ldisc_lock from called functions
529 * termios_mutex resetting termios data
530 * tasklist_lock to walk task list for hangup event
531 * ->siglock to protect ->signal/->sighand
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 */
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200533void __tty_hangup(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534{
Alan Cox37bdfb02008-02-08 04:18:47 -0800535 struct file *cons_filp = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 struct file *filp, *f = NULL;
537 struct task_struct *p;
Nick Piggind996b622010-08-18 04:37:36 +1000538 struct tty_file_private *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 int closecount = 0, n;
Alan Cox47f86832008-04-30 00:53:30 -0700540 unsigned long flags;
Alan Cox9c9f4de2008-10-13 10:37:26 +0100541 int refs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542
543 if (!tty)
544 return;
545
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
547 spin_lock(&redirect_lock);
Nick Piggind996b622010-08-18 04:37:36 +1000548 if (redirect && file_tty(redirect) == tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 f = redirect;
550 redirect = NULL;
551 }
552 spin_unlock(&redirect_lock);
Alan Cox37bdfb02008-02-08 04:18:47 -0800553
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200554 tty_lock();
555
Arnd Bergmannec79d602010-06-01 22:53:01 +0200556 /* inuse_filps is protected by the single tty lock,
557 this really needs to change if we want to flush the
558 workqueue with the lock held */
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200559 check_tty_count(tty, "tty_hangup");
Alan Cox36ba7822009-11-30 13:18:51 +0000560
Nick Pigginee2ffa02010-08-18 04:37:35 +1000561 spin_lock(&tty_files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 /* This breaks for file handles being sent over AF_UNIX sockets ? */
Nick Piggind996b622010-08-18 04:37:36 +1000563 list_for_each_entry(priv, &tty->tty_files, list) {
564 filp = priv->file;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 if (filp->f_op->write == redirected_tty_write)
566 cons_filp = filp;
567 if (filp->f_op->write != tty_write)
568 continue;
569 closecount++;
Arnd Bergmannec79d602010-06-01 22:53:01 +0200570 __tty_fasync(-1, filp, 0); /* can't block */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 filp->f_op = &hung_up_tty_fops;
572 }
Nick Pigginee2ffa02010-08-18 04:37:35 +1000573 spin_unlock(&tty_files_lock);
Alan Cox37bdfb02008-02-08 04:18:47 -0800574
Alan Coxc65c9bc2009-06-11 12:50:12 +0100575 tty_ldisc_hangup(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -0800576
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 read_lock(&tasklist_lock);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800578 if (tty->session) {
579 do_each_pid_task(tty->session, PIDTYPE_SID, p) {
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800580 spin_lock_irq(&p->sighand->siglock);
Alan Cox9c9f4de2008-10-13 10:37:26 +0100581 if (p->signal->tty == tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 p->signal->tty = NULL;
Alan Cox9c9f4de2008-10-13 10:37:26 +0100583 /* We defer the dereferences outside fo
584 the tasklist lock */
585 refs++;
586 }
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800587 if (!p->signal->leader) {
588 spin_unlock_irq(&p->sighand->siglock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 continue;
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800590 }
591 __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
592 __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800593 put_pid(p->signal->tty_old_pgrp); /* A noop */
Alan Cox47f86832008-04-30 00:53:30 -0700594 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800595 if (tty->pgrp)
596 p->signal->tty_old_pgrp = get_pid(tty->pgrp);
Alan Cox47f86832008-04-30 00:53:30 -0700597 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800598 spin_unlock_irq(&p->sighand->siglock);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800599 } while_each_pid_task(tty->session, PIDTYPE_SID, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 }
601 read_unlock(&tasklist_lock);
602
Alan Cox47f86832008-04-30 00:53:30 -0700603 spin_lock_irqsave(&tty->ctrl_lock, flags);
Alan Coxc65c9bc2009-06-11 12:50:12 +0100604 clear_bit(TTY_THROTTLED, &tty->flags);
605 clear_bit(TTY_PUSH, &tty->flags);
606 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
Eric W. Biedermand9c1e9a2007-03-18 12:45:44 -0600607 put_pid(tty->session);
608 put_pid(tty->pgrp);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800609 tty->session = NULL;
610 tty->pgrp = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611 tty->ctrl_status = 0;
Alan Coxc65c9bc2009-06-11 12:50:12 +0100612 set_bit(TTY_HUPPED, &tty->flags);
Alan Cox47f86832008-04-30 00:53:30 -0700613 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
614
Alan Cox9c9f4de2008-10-13 10:37:26 +0100615 /* Account for the p->signal references we killed */
616 while (refs--)
617 tty_kref_put(tty);
618
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 /*
Alan Cox37bdfb02008-02-08 04:18:47 -0800620 * If one of the devices matches a console pointer, we
621 * cannot just call hangup() because that will cause
622 * tty->count and state->count to go out of sync.
623 * So we just call close() the right number of times.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 */
625 if (cons_filp) {
Alan Coxf34d7a52008-04-30 00:54:13 -0700626 if (tty->ops->close)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 for (n = 0; n < closecount; n++)
Alan Coxf34d7a52008-04-30 00:54:13 -0700628 tty->ops->close(tty, cons_filp);
629 } else if (tty->ops->hangup)
630 (tty->ops->hangup)(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -0800631 /*
632 * We don't want to have driver/ldisc interactions beyond
633 * the ones we did here. The driver layer expects no
634 * calls after ->hangup() from the ldisc side. However we
635 * can't yet guarantee all that.
636 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 set_bit(TTY_HUPPED, &tty->flags);
Alan Coxc65c9bc2009-06-11 12:50:12 +0100638 tty_ldisc_enable(tty);
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200639
640 tty_unlock();
641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 if (f)
643 fput(f);
644}
645
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200646static void do_tty_hangup(struct work_struct *work)
647{
648 struct tty_struct *tty =
649 container_of(work, struct tty_struct, hangup_work);
650
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200651 __tty_hangup(tty);
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200652}
653
Alan Coxaf9b8972006-08-27 01:24:01 -0700654/**
655 * tty_hangup - trigger a hangup event
656 * @tty: tty to hangup
657 *
658 * A carrier loss (virtual or otherwise) has occurred on this like
659 * schedule a hangup sequence to run after this event.
660 */
661
Alan Cox37bdfb02008-02-08 04:18:47 -0800662void tty_hangup(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663{
664#ifdef TTY_DEBUG_HANGUP
665 char buf[64];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf));
667#endif
668 schedule_work(&tty->hangup_work);
669}
670
671EXPORT_SYMBOL(tty_hangup);
672
Alan Coxaf9b8972006-08-27 01:24:01 -0700673/**
674 * tty_vhangup - process vhangup
675 * @tty: tty to hangup
676 *
677 * The user has asked via system call for the terminal to be hung up.
678 * We do this synchronously so that when the syscall returns the process
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +0200679 * is complete. That guarantee is necessary for security reasons.
Alan Coxaf9b8972006-08-27 01:24:01 -0700680 */
681
Alan Cox37bdfb02008-02-08 04:18:47 -0800682void tty_vhangup(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683{
684#ifdef TTY_DEBUG_HANGUP
685 char buf[64];
686
687 printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
688#endif
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200689 __tty_hangup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690}
Alan Cox37bdfb02008-02-08 04:18:47 -0800691
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692EXPORT_SYMBOL(tty_vhangup);
693
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200694
Alan Coxaf9b8972006-08-27 01:24:01 -0700695/**
Alan Cox2cb59982008-10-13 10:40:30 +0100696 * tty_vhangup_self - process vhangup for own ctty
697 *
698 * Perform a vhangup on the current controlling tty
699 */
700
701void tty_vhangup_self(void)
702{
703 struct tty_struct *tty;
704
Alan Cox2cb59982008-10-13 10:40:30 +0100705 tty = get_current_tty();
706 if (tty) {
707 tty_vhangup(tty);
708 tty_kref_put(tty);
709 }
Alan Cox2cb59982008-10-13 10:40:30 +0100710}
711
712/**
Alan Coxaf9b8972006-08-27 01:24:01 -0700713 * tty_hung_up_p - was tty hung up
714 * @filp: file pointer of tty
715 *
716 * Return true if the tty has been subject to a vhangup or a carrier
717 * loss
718 */
719
Alan Cox37bdfb02008-02-08 04:18:47 -0800720int tty_hung_up_p(struct file *filp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721{
722 return (filp->f_op == &hung_up_tty_fops);
723}
724
725EXPORT_SYMBOL(tty_hung_up_p);
726
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800727static void session_clear_tty(struct pid *session)
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800728{
729 struct task_struct *p;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800730 do_each_pid_task(session, PIDTYPE_SID, p) {
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800731 proc_clear_tty(p);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800732 } while_each_pid_task(session, PIDTYPE_SID, p);
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800733}
734
Alan Coxaf9b8972006-08-27 01:24:01 -0700735/**
736 * disassociate_ctty - disconnect controlling tty
737 * @on_exit: true if exiting so need to "hang up" the session
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 *
Alan Coxaf9b8972006-08-27 01:24:01 -0700739 * This function is typically called only by the session leader, when
740 * it wants to disassociate itself from its controlling tty.
741 *
742 * It performs the following functions:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 * (1) Sends a SIGHUP and SIGCONT to the foreground process group
744 * (2) Clears the tty from being controlling the session
745 * (3) Clears the controlling tty for all processes in the
746 * session group.
747 *
Alan Coxaf9b8972006-08-27 01:24:01 -0700748 * The argument on_exit is set to 1 if called when a process is
749 * exiting; it is 0 if called by the ioctl TIOCNOTTY.
750 *
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800751 * Locking:
Arnd Bergmannec79d602010-06-01 22:53:01 +0200752 * BTM is taken for hysterical raisins, and held when
753 * called from no_tty().
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800754 * tty_mutex is taken to protect tty
755 * ->siglock is taken to protect ->signal/->sighand
756 * tasklist_lock is taken to walk process list for sessions
757 * ->siglock is taken to protect ->signal/->sighand
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 */
Alan Coxaf9b8972006-08-27 01:24:01 -0700759
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760void disassociate_ctty(int on_exit)
761{
762 struct tty_struct *tty;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800763 struct pid *tty_pgrp = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764
Alan Cox5ec93d12009-11-30 13:18:45 +0000765 if (!current->signal->leader)
766 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800768 tty = get_current_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 if (tty) {
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800770 tty_pgrp = get_pid(tty->pgrp);
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200771 if (on_exit) {
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200772 if (tty->driver->type != TTY_DRIVER_TYPE_PTY)
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200773 tty_vhangup(tty);
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200774 }
Alan Cox452a00d2008-10-13 10:39:13 +0100775 tty_kref_put(tty);
Eric W. Biederman680a9672007-02-12 00:52:52 -0800776 } else if (on_exit) {
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800777 struct pid *old_pgrp;
Eric W. Biederman680a9672007-02-12 00:52:52 -0800778 spin_lock_irq(&current->sighand->siglock);
779 old_pgrp = current->signal->tty_old_pgrp;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800780 current->signal->tty_old_pgrp = NULL;
Eric W. Biederman680a9672007-02-12 00:52:52 -0800781 spin_unlock_irq(&current->sighand->siglock);
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800782 if (old_pgrp) {
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800783 kill_pgrp(old_pgrp, SIGHUP, on_exit);
784 kill_pgrp(old_pgrp, SIGCONT, on_exit);
785 put_pid(old_pgrp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 return;
788 }
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800789 if (tty_pgrp) {
790 kill_pgrp(tty_pgrp, SIGHUP, on_exit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 if (!on_exit)
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800792 kill_pgrp(tty_pgrp, SIGCONT, on_exit);
793 put_pid(tty_pgrp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 }
795
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800796 spin_lock_irq(&current->sighand->siglock);
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -0700797 put_pid(current->signal->tty_old_pgrp);
Randy Dunlap23cac8d2007-02-20 13:58:05 -0800798 current->signal->tty_old_pgrp = NULL;
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800799 spin_unlock_irq(&current->sighand->siglock);
800
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800801 tty = get_current_tty();
802 if (tty) {
Alan Cox47f86832008-04-30 00:53:30 -0700803 unsigned long flags;
804 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800805 put_pid(tty->session);
806 put_pid(tty->pgrp);
807 tty->session = NULL;
808 tty->pgrp = NULL;
Alan Cox47f86832008-04-30 00:53:30 -0700809 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Alan Cox452a00d2008-10-13 10:39:13 +0100810 tty_kref_put(tty);
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800811 } else {
812#ifdef TTY_DEBUG_HANGUP
813 printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
814 " = NULL", tty);
815#endif
816 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
818 /* Now clear signal->tty under the lock */
819 read_lock(&tasklist_lock);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -0800820 session_clear_tty(task_session(current));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822}
823
Eric W. Biederman98a27ba2007-05-08 00:26:56 -0700824/**
825 *
826 * no_tty - Ensure the current process does not have a controlling tty
827 */
828void no_tty(void)
829{
830 struct task_struct *tsk = current;
Arnd Bergmannec79d602010-06-01 22:53:01 +0200831 tty_lock();
Alan Cox5ec93d12009-11-30 13:18:45 +0000832 disassociate_ctty(0);
Arnd Bergmannec79d602010-06-01 22:53:01 +0200833 tty_unlock();
Eric W. Biederman98a27ba2007-05-08 00:26:56 -0700834 proc_clear_tty(tsk);
835}
836
Alan Coxaf9b8972006-08-27 01:24:01 -0700837
838/**
Robert P. J. Daybeb7dd82007-05-09 07:14:03 +0200839 * stop_tty - propagate flow control
Alan Coxaf9b8972006-08-27 01:24:01 -0700840 * @tty: tty to stop
841 *
842 * Perform flow control to the driver. For PTY/TTY pairs we
Robert P. J. Daybeb7dd82007-05-09 07:14:03 +0200843 * must also propagate the TIOCKPKT status. May be called
Alan Coxaf9b8972006-08-27 01:24:01 -0700844 * on an already stopped device and will not re-call the driver
845 * method.
846 *
847 * This functionality is used by both the line disciplines for
848 * halting incoming flow and by the driver. It may therefore be
849 * called from any context, may be under the tty atomic_write_lock
850 * but not always.
851 *
852 * Locking:
Alan Cox04f378b2008-04-30 00:53:29 -0700853 * Uses the tty control lock internally
Alan Coxaf9b8972006-08-27 01:24:01 -0700854 */
855
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856void stop_tty(struct tty_struct *tty)
857{
Alan Cox04f378b2008-04-30 00:53:29 -0700858 unsigned long flags;
859 spin_lock_irqsave(&tty->ctrl_lock, flags);
860 if (tty->stopped) {
861 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 return;
Alan Cox04f378b2008-04-30 00:53:29 -0700863 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 tty->stopped = 1;
865 if (tty->link && tty->link->packet) {
866 tty->ctrl_status &= ~TIOCPKT_START;
867 tty->ctrl_status |= TIOCPKT_STOP;
Davide Libenzi4b194492009-03-31 15:24:24 -0700868 wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 }
Alan Cox04f378b2008-04-30 00:53:29 -0700870 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Alan Coxf34d7a52008-04-30 00:54:13 -0700871 if (tty->ops->stop)
872 (tty->ops->stop)(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873}
874
875EXPORT_SYMBOL(stop_tty);
876
Alan Coxaf9b8972006-08-27 01:24:01 -0700877/**
Robert P. J. Daybeb7dd82007-05-09 07:14:03 +0200878 * start_tty - propagate flow control
Alan Coxaf9b8972006-08-27 01:24:01 -0700879 * @tty: tty to start
880 *
881 * Start a tty that has been stopped if at all possible. Perform
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +0200882 * any necessary wakeups and propagate the TIOCPKT status. If this
Alan Coxaf9b8972006-08-27 01:24:01 -0700883 * is the tty was previous stopped and is being started then the
884 * driver start method is invoked and the line discipline woken.
885 *
886 * Locking:
Alan Cox04f378b2008-04-30 00:53:29 -0700887 * ctrl_lock
Alan Coxaf9b8972006-08-27 01:24:01 -0700888 */
889
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890void start_tty(struct tty_struct *tty)
891{
Alan Cox04f378b2008-04-30 00:53:29 -0700892 unsigned long flags;
893 spin_lock_irqsave(&tty->ctrl_lock, flags);
894 if (!tty->stopped || tty->flow_stopped) {
895 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 return;
Alan Cox04f378b2008-04-30 00:53:29 -0700897 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 tty->stopped = 0;
899 if (tty->link && tty->link->packet) {
900 tty->ctrl_status &= ~TIOCPKT_STOP;
901 tty->ctrl_status |= TIOCPKT_START;
Davide Libenzi4b194492009-03-31 15:24:24 -0700902 wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 }
Alan Cox04f378b2008-04-30 00:53:29 -0700904 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Alan Coxf34d7a52008-04-30 00:54:13 -0700905 if (tty->ops->start)
906 (tty->ops->start)(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 /* If we have a running line discipline it may need kicking */
908 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909}
910
911EXPORT_SYMBOL(start_tty);
912
Alan Coxaf9b8972006-08-27 01:24:01 -0700913/**
914 * tty_read - read method for tty device files
915 * @file: pointer to tty file
916 * @buf: user buffer
917 * @count: size of user buffer
918 * @ppos: unused
919 *
920 * Perform the read system call function on this terminal device. Checks
921 * for hung up devices before calling the line discipline method.
922 *
923 * Locking:
Alan Cox47f86832008-04-30 00:53:30 -0700924 * Locks the line discipline internally while needed. Multiple
925 * read calls may be outstanding in parallel.
Alan Coxaf9b8972006-08-27 01:24:01 -0700926 */
927
Alan Cox37bdfb02008-02-08 04:18:47 -0800928static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 loff_t *ppos)
930{
931 int i;
Nick Piggind996b622010-08-18 04:37:36 +1000932 struct inode *inode = file->f_path.dentry->d_inode;
933 struct tty_struct *tty = file_tty(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 struct tty_ldisc *ld;
935
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 if (tty_paranoia_check(tty, inode, "tty_read"))
937 return -EIO;
938 if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
939 return -EIO;
940
941 /* We want to wait for the line discipline to sort out in this
942 situation */
943 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +0100944 if (ld->ops->read)
945 i = (ld->ops->read)(tty, file, buf, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 else
947 i = -EIO;
948 tty_ldisc_deref(ld);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 if (i > 0)
950 inode->i_atime = current_fs_time(inode->i_sb);
951 return i;
952}
953
Alan Cox9c1729d2007-07-15 23:39:43 -0700954void tty_write_unlock(struct tty_struct *tty)
955{
956 mutex_unlock(&tty->atomic_write_lock);
Davide Libenzi4b194492009-03-31 15:24:24 -0700957 wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
Alan Cox9c1729d2007-07-15 23:39:43 -0700958}
959
960int tty_write_lock(struct tty_struct *tty, int ndelay)
961{
962 if (!mutex_trylock(&tty->atomic_write_lock)) {
963 if (ndelay)
964 return -EAGAIN;
965 if (mutex_lock_interruptible(&tty->atomic_write_lock))
966 return -ERESTARTSYS;
967 }
968 return 0;
969}
970
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971/*
972 * Split writes up in sane blocksizes to avoid
973 * denial-of-service type attacks
974 */
975static inline ssize_t do_tty_write(
976 ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),
977 struct tty_struct *tty,
978 struct file *file,
979 const char __user *buf,
980 size_t count)
981{
Alan Cox9c1729d2007-07-15 23:39:43 -0700982 ssize_t ret, written = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 unsigned int chunk;
Alan Cox37bdfb02008-02-08 04:18:47 -0800984
Alan Cox9c1729d2007-07-15 23:39:43 -0700985 ret = tty_write_lock(tty, file->f_flags & O_NDELAY);
986 if (ret < 0)
987 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988
989 /*
990 * We chunk up writes into a temporary buffer. This
991 * simplifies low-level drivers immensely, since they
992 * don't have locking issues and user mode accesses.
993 *
994 * But if TTY_NO_WRITE_SPLIT is set, we should use a
995 * big chunk-size..
996 *
997 * The default chunk-size is 2kB, because the NTTY
998 * layer has problems with bigger chunks. It will
999 * claim to be able to handle more characters than
1000 * it actually does.
Alan Coxaf9b8972006-08-27 01:24:01 -07001001 *
1002 * FIXME: This can probably go away now except that 64K chunks
1003 * are too likely to fail unless switched to vmalloc...
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 */
1005 chunk = 2048;
1006 if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags))
1007 chunk = 65536;
1008 if (count < chunk)
1009 chunk = count;
1010
Ingo Molnar70522e12006-03-23 03:00:31 -08001011 /* write_buf/write_cnt is protected by the atomic_write_lock mutex */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 if (tty->write_cnt < chunk) {
Jason Wessel402fda92008-10-13 10:45:36 +01001013 unsigned char *buf_chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014
1015 if (chunk < 1024)
1016 chunk = 1024;
1017
Jason Wessel402fda92008-10-13 10:45:36 +01001018 buf_chunk = kmalloc(chunk, GFP_KERNEL);
1019 if (!buf_chunk) {
Alan Cox9c1729d2007-07-15 23:39:43 -07001020 ret = -ENOMEM;
1021 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 }
1023 kfree(tty->write_buf);
1024 tty->write_cnt = chunk;
Jason Wessel402fda92008-10-13 10:45:36 +01001025 tty->write_buf = buf_chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 }
1027
1028 /* Do the write .. */
1029 for (;;) {
1030 size_t size = count;
1031 if (size > chunk)
1032 size = chunk;
1033 ret = -EFAULT;
1034 if (copy_from_user(tty->write_buf, buf, size))
1035 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 ret = write(tty, file, tty->write_buf, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 if (ret <= 0)
1038 break;
1039 written += ret;
1040 buf += ret;
1041 count -= ret;
1042 if (!count)
1043 break;
1044 ret = -ERESTARTSYS;
1045 if (signal_pending(current))
1046 break;
1047 cond_resched();
1048 }
1049 if (written) {
Josef Sipeka7113a92006-12-08 02:36:55 -08001050 struct inode *inode = file->f_path.dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 inode->i_mtime = current_fs_time(inode->i_sb);
1052 ret = written;
1053 }
Alan Cox9c1729d2007-07-15 23:39:43 -07001054out:
1055 tty_write_unlock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 return ret;
1057}
1058
Alan Cox95f9bfc2008-10-13 10:39:23 +01001059/**
1060 * tty_write_message - write a message to a certain tty, not just the console.
1061 * @tty: the destination tty_struct
1062 * @msg: the message to write
1063 *
1064 * This is used for messages that need to be redirected to a specific tty.
1065 * We don't put it into the syslog queue right now maybe in the future if
1066 * really needed.
1067 *
Arnd Bergmannec79d602010-06-01 22:53:01 +02001068 * We must still hold the BTM and test the CLOSING flag for the moment.
Alan Cox95f9bfc2008-10-13 10:39:23 +01001069 */
1070
1071void tty_write_message(struct tty_struct *tty, char *msg)
1072{
Alan Cox95f9bfc2008-10-13 10:39:23 +01001073 if (tty) {
1074 mutex_lock(&tty->atomic_write_lock);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001075 tty_lock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001076 if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001077 tty_unlock();
Alan Cox95f9bfc2008-10-13 10:39:23 +01001078 tty->ops->write(tty, msg, strlen(msg));
Alan Coxeeb89d92009-11-30 13:18:29 +00001079 } else
Arnd Bergmannec79d602010-06-01 22:53:01 +02001080 tty_unlock();
Alan Cox95f9bfc2008-10-13 10:39:23 +01001081 tty_write_unlock(tty);
1082 }
Alan Cox95f9bfc2008-10-13 10:39:23 +01001083 return;
1084}
1085
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086
Alan Coxaf9b8972006-08-27 01:24:01 -07001087/**
1088 * tty_write - write method for tty device file
1089 * @file: tty file pointer
1090 * @buf: user data to write
1091 * @count: bytes to write
1092 * @ppos: unused
1093 *
1094 * Write data to a tty device via the line discipline.
1095 *
1096 * Locking:
1097 * Locks the line discipline as required
1098 * Writes to the tty driver are serialized by the atomic_write_lock
1099 * and are then processed in chunks to the device. The line discipline
Joe Petersona88a69c2009-01-02 13:40:53 +00001100 * write method will not be invoked in parallel for each device.
Alan Coxaf9b8972006-08-27 01:24:01 -07001101 */
1102
Alan Cox37bdfb02008-02-08 04:18:47 -08001103static ssize_t tty_write(struct file *file, const char __user *buf,
1104 size_t count, loff_t *ppos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105{
Josef Sipeka7113a92006-12-08 02:36:55 -08001106 struct inode *inode = file->f_path.dentry->d_inode;
Nick Piggind996b622010-08-18 04:37:36 +10001107 struct tty_struct *tty = file_tty(file);
1108 struct tty_ldisc *ld;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 ssize_t ret;
Alan Cox37bdfb02008-02-08 04:18:47 -08001110
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 if (tty_paranoia_check(tty, inode, "tty_write"))
1112 return -EIO;
Alan Coxf34d7a52008-04-30 00:54:13 -07001113 if (!tty || !tty->ops->write ||
Alan Cox37bdfb02008-02-08 04:18:47 -08001114 (test_bit(TTY_IO_ERROR, &tty->flags)))
1115 return -EIO;
Alan Coxf34d7a52008-04-30 00:54:13 -07001116 /* Short term debug to catch buggy drivers */
1117 if (tty->ops->write_room == NULL)
1118 printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
1119 tty->driver->name);
Alan Cox37bdfb02008-02-08 04:18:47 -08001120 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +01001121 if (!ld->ops->write)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 ret = -EIO;
1123 else
Alan Coxa352def2008-07-16 21:53:12 +01001124 ret = do_tty_write(ld->ops->write, tty, file, buf, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 tty_ldisc_deref(ld);
1126 return ret;
1127}
1128
Alan Cox37bdfb02008-02-08 04:18:47 -08001129ssize_t redirected_tty_write(struct file *file, const char __user *buf,
1130 size_t count, loff_t *ppos)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131{
1132 struct file *p = NULL;
1133
1134 spin_lock(&redirect_lock);
1135 if (redirect) {
1136 get_file(redirect);
1137 p = redirect;
1138 }
1139 spin_unlock(&redirect_lock);
1140
1141 if (p) {
1142 ssize_t res;
1143 res = vfs_write(p, buf, count, &p->f_pos);
1144 fput(p);
1145 return res;
1146 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 return tty_write(file, buf, count, ppos);
1148}
1149
1150static char ptychar[] = "pqrstuvwxyzabcde";
1151
Alan Coxaf9b8972006-08-27 01:24:01 -07001152/**
1153 * pty_line_name - generate name for a pty
1154 * @driver: the tty driver in use
1155 * @index: the minor number
1156 * @p: output buffer of at least 6 bytes
1157 *
1158 * Generate a name from a driver reference and write it to the output
1159 * buffer.
1160 *
1161 * Locking: None
1162 */
1163static void pty_line_name(struct tty_driver *driver, int index, char *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164{
1165 int i = index + driver->name_base;
1166 /* ->name is initialized to "ttyp", but "tty" is expected */
1167 sprintf(p, "%s%c%x",
Alan Cox37bdfb02008-02-08 04:18:47 -08001168 driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name,
1169 ptychar[i >> 4 & 0xf], i & 0xf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170}
1171
Alan Coxaf9b8972006-08-27 01:24:01 -07001172/**
Alan Cox8b0a88d2008-10-13 10:42:19 +01001173 * tty_line_name - generate name for a tty
Alan Coxaf9b8972006-08-27 01:24:01 -07001174 * @driver: the tty driver in use
1175 * @index: the minor number
1176 * @p: output buffer of at least 7 bytes
1177 *
1178 * Generate a name from a driver reference and write it to the output
1179 * buffer.
1180 *
1181 * Locking: None
1182 */
1183static void tty_line_name(struct tty_driver *driver, int index, char *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184{
1185 sprintf(p, "%s%d", driver->name, index + driver->name_base);
1186}
1187
Alan Cox99f1fe12008-10-13 10:42:00 +01001188/**
1189 * tty_driver_lookup_tty() - find an existing tty, if any
1190 * @driver: the driver for the tty
1191 * @idx: the minor number
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001192 *
Alan Cox99f1fe12008-10-13 10:42:00 +01001193 * Return the tty, if found or ERR_PTR() otherwise.
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001194 *
Alan Cox99f1fe12008-10-13 10:42:00 +01001195 * Locking: tty_mutex must be held. If tty is found, the mutex must
1196 * be held until the 'fast-open' is also done. Will change once we
1197 * have refcounting in the driver and per driver locking
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001198 */
Jason Wessela47d5452009-01-02 13:43:04 +00001199static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001200 struct inode *inode, int idx)
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001201{
1202 struct tty_struct *tty;
1203
Alan Cox99f1fe12008-10-13 10:42:00 +01001204 if (driver->ops->lookup)
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001205 return driver->ops->lookup(driver, inode, idx);
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001206
Alan Cox8b0a88d2008-10-13 10:42:19 +01001207 tty = driver->ttys[idx];
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001208 return tty;
1209}
1210
Alan Cox99f1fe12008-10-13 10:42:00 +01001211/**
Alan Coxbf970ee2008-10-13 10:42:39 +01001212 * tty_init_termios - helper for termios setup
1213 * @tty: the tty to set up
1214 *
1215 * Initialise the termios structures for this tty. Thus runs under
1216 * the tty_mutex currently so we can be relaxed about ordering.
1217 */
1218
1219int tty_init_termios(struct tty_struct *tty)
1220{
Alan Coxfe6e29f2008-10-13 10:44:08 +01001221 struct ktermios *tp;
Alan Coxbf970ee2008-10-13 10:42:39 +01001222 int idx = tty->index;
1223
1224 tp = tty->driver->termios[idx];
Alan Coxbf970ee2008-10-13 10:42:39 +01001225 if (tp == NULL) {
Alan Coxfe6e29f2008-10-13 10:44:08 +01001226 tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
1227 if (tp == NULL)
Alan Coxbf970ee2008-10-13 10:42:39 +01001228 return -ENOMEM;
Alan Coxbf970ee2008-10-13 10:42:39 +01001229 memcpy(tp, &tty->driver->init_termios,
1230 sizeof(struct ktermios));
1231 tty->driver->termios[idx] = tp;
Alan Coxbf970ee2008-10-13 10:42:39 +01001232 }
1233 tty->termios = tp;
Alan Coxfe6e29f2008-10-13 10:44:08 +01001234 tty->termios_locked = tp + 1;
Alan Coxbf970ee2008-10-13 10:42:39 +01001235
1236 /* Compatibility until drivers always set this */
1237 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
1238 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
1239 return 0;
1240}
Alan Coxfe1ae7f2009-09-19 13:13:33 -07001241EXPORT_SYMBOL_GPL(tty_init_termios);
Alan Coxbf970ee2008-10-13 10:42:39 +01001242
1243/**
Alan Cox8b0a88d2008-10-13 10:42:19 +01001244 * tty_driver_install_tty() - install a tty entry in the driver
1245 * @driver: the driver for the tty
1246 * @tty: the tty
1247 *
1248 * Install a tty object into the driver tables. The tty->index field
Alan Coxbf970ee2008-10-13 10:42:39 +01001249 * will be set by the time this is called. This method is responsible
1250 * for ensuring any need additional structures are allocated and
1251 * configured.
Alan Cox8b0a88d2008-10-13 10:42:19 +01001252 *
1253 * Locking: tty_mutex for now
1254 */
1255static int tty_driver_install_tty(struct tty_driver *driver,
1256 struct tty_struct *tty)
1257{
Alan Coxbf970ee2008-10-13 10:42:39 +01001258 int idx = tty->index;
Alan Coxeeb89d92009-11-30 13:18:29 +00001259 int ret;
Alan Coxbf970ee2008-10-13 10:42:39 +01001260
Alan Coxeeb89d92009-11-30 13:18:29 +00001261 if (driver->ops->install) {
Alan Coxeeb89d92009-11-30 13:18:29 +00001262 ret = driver->ops->install(driver, tty);
Alan Coxeeb89d92009-11-30 13:18:29 +00001263 return ret;
1264 }
Alan Coxbf970ee2008-10-13 10:42:39 +01001265
1266 if (tty_init_termios(tty) == 0) {
1267 tty_driver_kref_get(driver);
1268 tty->count++;
1269 driver->ttys[idx] = tty;
1270 return 0;
1271 }
1272 return -ENOMEM;
Alan Cox8b0a88d2008-10-13 10:42:19 +01001273}
1274
1275/**
1276 * tty_driver_remove_tty() - remove a tty from the driver tables
1277 * @driver: the driver for the tty
1278 * @idx: the minor number
1279 *
1280 * Remvoe a tty object from the driver tables. The tty->index field
1281 * will be set by the time this is called.
1282 *
1283 * Locking: tty_mutex for now
1284 */
1285static void tty_driver_remove_tty(struct tty_driver *driver,
1286 struct tty_struct *tty)
1287{
1288 if (driver->ops->remove)
1289 driver->ops->remove(driver, tty);
1290 else
1291 driver->ttys[tty->index] = NULL;
1292}
1293
1294/*
1295 * tty_reopen() - fast re-open of an open tty
1296 * @tty - the tty to open
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001297 *
Alan Cox99f1fe12008-10-13 10:42:00 +01001298 * Return 0 on success, -errno on error.
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001299 *
Alan Cox99f1fe12008-10-13 10:42:00 +01001300 * Locking: tty_mutex must be held from the time the tty was found
1301 * till this open completes.
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001302 */
Alan Cox99f1fe12008-10-13 10:42:00 +01001303static int tty_reopen(struct tty_struct *tty)
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001304{
1305 struct tty_driver *driver = tty->driver;
1306
1307 if (test_bit(TTY_CLOSING, &tty->flags))
1308 return -EIO;
1309
1310 if (driver->type == TTY_DRIVER_TYPE_PTY &&
1311 driver->subtype == PTY_TYPE_MASTER) {
1312 /*
1313 * special case for PTY masters: only one open permitted,
1314 * and the slave side open count is incremented as well.
1315 */
1316 if (tty->count)
1317 return -EIO;
1318
1319 tty->link->count++;
1320 }
1321 tty->count++;
1322 tty->driver = driver; /* N.B. why do this every time?? */
1323
Alan Cox1aa4bed2009-06-16 17:01:33 +01001324 mutex_lock(&tty->ldisc_mutex);
Alan Cox99f1fe12008-10-13 10:42:00 +01001325 WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
Alan Cox1aa4bed2009-06-16 17:01:33 +01001326 mutex_unlock(&tty->ldisc_mutex);
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001327
1328 return 0;
1329}
1330
Alan Coxaf9b8972006-08-27 01:24:01 -07001331/**
Alan Coxd81ed102008-10-13 10:41:42 +01001332 * tty_init_dev - initialise a tty device
Alan Coxaf9b8972006-08-27 01:24:01 -07001333 * @driver: tty driver we are opening a device on
1334 * @idx: device index
Alan Cox15582d32008-10-13 10:41:03 +01001335 * @ret_tty: returned tty structure
1336 * @first_ok: ok to open a new device (used by ptmx)
Alan Coxaf9b8972006-08-27 01:24:01 -07001337 *
1338 * Prepare a tty device. This may not be a "new" clean device but
1339 * could also be an active device. The pty drivers require special
1340 * handling because of this.
1341 *
1342 * Locking:
1343 * The function is called under the tty_mutex, which
1344 * protects us from the tty struct or driver itself going away.
1345 *
1346 * On exit the tty device has the line discipline attached and
1347 * a reference count of 1. If a pair was created for pty/tty use
1348 * and the other was a pty master then it too has a reference count of 1.
1349 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 * WSH 06/09/97: Rewritten to remove races and properly clean up after a
Ingo Molnar70522e12006-03-23 03:00:31 -08001351 * failed open. The new code protects the open with a mutex, so it's
1352 * really quite straightforward. The mutex locking can probably be
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 * relaxed for the (most common) case of reopening a tty.
1354 */
Alan Coxaf9b8972006-08-27 01:24:01 -07001355
Alan Cox73ec06f2008-10-13 10:42:29 +01001356struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
1357 int first_ok)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358{
Alan Coxbf970ee2008-10-13 10:42:39 +01001359 struct tty_struct *tty;
Alan Cox73ec06f2008-10-13 10:42:29 +01001360 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001362 /* Check if pty master is being opened multiple times */
Alan Cox15582d32008-10-13 10:41:03 +01001363 if (driver->subtype == PTY_TYPE_MASTER &&
Alan Coxeeb89d92009-11-30 13:18:29 +00001364 (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
Alan Cox73ec06f2008-10-13 10:42:29 +01001365 return ERR_PTR(-EIO);
Alan Coxeeb89d92009-11-30 13:18:29 +00001366 }
Alan Cox73ec06f2008-10-13 10:42:29 +01001367
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 /*
1369 * First time open is complex, especially for PTY devices.
1370 * This code guarantees that either everything succeeds and the
1371 * TTY is ready for operation, or else the table slots are vacated
Alan Cox37bdfb02008-02-08 04:18:47 -08001372 * and the allocated memory released. (Except that the termios
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 * and locked termios may be retained.)
1374 */
1375
Alan Cox73ec06f2008-10-13 10:42:29 +01001376 if (!try_module_get(driver->owner))
1377 return ERR_PTR(-ENODEV);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 tty = alloc_tty_struct();
Alan Cox37bdfb02008-02-08 04:18:47 -08001380 if (!tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 goto fail_no_mem;
Alan Coxbf970ee2008-10-13 10:42:39 +01001382 initialize_tty_struct(tty, driver, idx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383
Alan Cox73ec06f2008-10-13 10:42:29 +01001384 retval = tty_driver_install_tty(driver, tty);
Alan Coxbf970ee2008-10-13 10:42:39 +01001385 if (retval < 0) {
1386 free_tty_struct(tty);
1387 module_put(driver->owner);
1388 return ERR_PTR(retval);
1389 }
Alan Cox8b0a88d2008-10-13 10:42:19 +01001390
Alan Cox37bdfb02008-02-08 04:18:47 -08001391 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 * Structures all installed ... call the ldisc open routines.
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001393 * If we fail here just call release_tty to clean up. No need
1394 * to decrement the use counts, as release_tty doesn't care.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 */
Alan Coxbf970ee2008-10-13 10:42:39 +01001396 retval = tty_ldisc_setup(tty, tty->link);
Alan Cox01e1abb2008-07-22 11:16:55 +01001397 if (retval)
1398 goto release_mem_out;
Alan Cox73ec06f2008-10-13 10:42:29 +01001399 return tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401fail_no_mem:
1402 module_put(driver->owner);
Alan Cox73ec06f2008-10-13 10:42:29 +01001403 return ERR_PTR(-ENOMEM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001405 /* call the tty release_tty routine to clean out this slot */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406release_mem_out:
Akinobu Mita40509142006-09-29 02:01:27 -07001407 if (printk_ratelimit())
Alan Coxd81ed102008-10-13 10:41:42 +01001408 printk(KERN_INFO "tty_init_dev: ldisc open failed, "
Akinobu Mita40509142006-09-29 02:01:27 -07001409 "clearing slot %d\n", idx);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001410 release_tty(tty, idx);
Alan Cox73ec06f2008-10-13 10:42:29 +01001411 return ERR_PTR(retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412}
1413
Alan Coxfeebed62008-10-13 10:41:30 +01001414void tty_free_termios(struct tty_struct *tty)
1415{
1416 struct ktermios *tp;
1417 int idx = tty->index;
1418 /* Kill this flag and push into drivers for locking etc */
1419 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
1420 /* FIXME: Locking on ->termios array */
1421 tp = tty->termios;
1422 tty->driver->termios[idx] = NULL;
1423 kfree(tp);
Alan Coxfeebed62008-10-13 10:41:30 +01001424 }
1425}
1426EXPORT_SYMBOL(tty_free_termios);
1427
1428void tty_shutdown(struct tty_struct *tty)
1429{
Alan Cox8b0a88d2008-10-13 10:42:19 +01001430 tty_driver_remove_tty(tty->driver, tty);
Alan Coxfeebed62008-10-13 10:41:30 +01001431 tty_free_termios(tty);
1432}
1433EXPORT_SYMBOL(tty_shutdown);
1434
Alan Coxaf9b8972006-08-27 01:24:01 -07001435/**
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001436 * release_one_tty - release tty structure memory
Alan Cox9c9f4de2008-10-13 10:37:26 +01001437 * @kref: kref of tty we are obliterating
Alan Coxaf9b8972006-08-27 01:24:01 -07001438 *
1439 * Releases memory associated with a tty structure, and clears out the
1440 * driver table slots. This function is called when a device is no longer
1441 * in use. It also gets called when setup of a device fails.
1442 *
1443 * Locking:
1444 * tty_mutex - sometimes only
1445 * takes the file list lock internally when working on the list
1446 * of ttys that the driver keeps.
Alan Coxb50989d2009-09-19 13:13:22 -07001447 *
1448 * This method gets called from a work queue so that the driver private
Dave Youngf278a2f2009-09-27 16:00:42 +00001449 * cleanup ops can sleep (needed for USB at least)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 */
Alan Coxb50989d2009-09-19 13:13:22 -07001451static void release_one_tty(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452{
Alan Coxb50989d2009-09-19 13:13:22 -07001453 struct tty_struct *tty =
1454 container_of(work, struct tty_struct, hangup_work);
Alan Cox6f967f72008-10-13 10:37:36 +01001455 struct tty_driver *driver = tty->driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456
Dave Youngf278a2f2009-09-27 16:00:42 +00001457 if (tty->ops->cleanup)
1458 tty->ops->cleanup(tty);
1459
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 tty->magic = 0;
Alan Cox7d7b93c2008-10-13 10:42:09 +01001461 tty_driver_kref_put(driver);
Alan Cox6f967f72008-10-13 10:37:36 +01001462 module_put(driver->owner);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001463
Nick Pigginee2ffa02010-08-18 04:37:35 +10001464 spin_lock(&tty_files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 list_del_init(&tty->tty_files);
Nick Pigginee2ffa02010-08-18 04:37:35 +10001466 spin_unlock(&tty_files_lock);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001467
Oleg Nesterov6da8d862010-04-02 18:05:12 +02001468 put_pid(tty->pgrp);
1469 put_pid(tty->session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 free_tty_struct(tty);
1471}
1472
Alan Coxb50989d2009-09-19 13:13:22 -07001473static void queue_release_one_tty(struct kref *kref)
1474{
1475 struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
Dave Youngf278a2f2009-09-27 16:00:42 +00001476
1477 if (tty->ops->shutdown)
1478 tty->ops->shutdown(tty);
1479 else
1480 tty_shutdown(tty);
1481
Alan Coxb50989d2009-09-19 13:13:22 -07001482 /* The hangup queue is now free so we can reuse it rather than
1483 waste a chunk of memory for each port */
1484 INIT_WORK(&tty->hangup_work, release_one_tty);
1485 schedule_work(&tty->hangup_work);
1486}
1487
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001488/**
Alan Cox9c9f4de2008-10-13 10:37:26 +01001489 * tty_kref_put - release a tty kref
1490 * @tty: tty device
1491 *
1492 * Release a reference to a tty device and if need be let the kref
1493 * layer destruct the object for us
1494 */
1495
1496void tty_kref_put(struct tty_struct *tty)
1497{
1498 if (tty)
Alan Coxb50989d2009-09-19 13:13:22 -07001499 kref_put(&tty->kref, queue_release_one_tty);
Alan Cox9c9f4de2008-10-13 10:37:26 +01001500}
1501EXPORT_SYMBOL(tty_kref_put);
1502
1503/**
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001504 * release_tty - release tty structure memory
1505 *
1506 * Release both @tty and a possible linked partner (think pty pair),
1507 * and decrement the refcount of the backing module.
1508 *
1509 * Locking:
1510 * tty_mutex - sometimes only
1511 * takes the file list lock internally when working on the list
1512 * of ttys that the driver keeps.
1513 * FIXME: should we require tty_mutex is held here ??
Alan Cox9c9f4de2008-10-13 10:37:26 +01001514 *
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001515 */
1516static void release_tty(struct tty_struct *tty, int idx)
1517{
Alan Cox9c9f4de2008-10-13 10:37:26 +01001518 /* This should always be true but check for the moment */
1519 WARN_ON(tty->index != idx);
1520
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001521 if (tty->link)
Alan Cox9c9f4de2008-10-13 10:37:26 +01001522 tty_kref_put(tty->link);
1523 tty_kref_put(tty);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001524}
1525
Alan Coxeeb89d92009-11-30 13:18:29 +00001526/**
1527 * tty_release - vfs callback for close
1528 * @inode: inode of tty
1529 * @filp: file pointer for handle to tty
1530 *
1531 * Called the last time each file handle is closed that references
1532 * this tty. There may however be several such references.
1533 *
1534 * Locking:
1535 * Takes bkl. See tty_release_dev
1536 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 * Even releasing the tty structures is a tricky business.. We have
1538 * to be very careful that the structures are all released at the
1539 * same time, as interrupts might otherwise get the wrong pointers.
1540 *
1541 * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
1542 * lead to double frees or releasing memory still in use.
1543 */
Alan Coxeeb89d92009-11-30 13:18:29 +00001544
1545int tty_release(struct inode *inode, struct file *filp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546{
Nick Piggind996b622010-08-18 04:37:36 +10001547 struct tty_struct *tty = file_tty(filp);
1548 struct tty_struct *o_tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 int pty_master, tty_closing, o_tty_closing, do_sleep;
Paul Fulghum14a62832006-04-10 22:54:19 -07001550 int devpts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 int idx;
1552 char buf[64];
Alan Cox37bdfb02008-02-08 04:18:47 -08001553
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001554 if (tty_paranoia_check(tty, inode, "tty_release_dev"))
Alan Coxeeb89d92009-11-30 13:18:29 +00001555 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
Arnd Bergmannec79d602010-06-01 22:53:01 +02001557 tty_lock();
Alan Coxd81ed102008-10-13 10:41:42 +01001558 check_tty_count(tty, "tty_release_dev");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
Arnd Bergmannec79d602010-06-01 22:53:01 +02001560 __tty_fasync(-1, filp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561
1562 idx = tty->index;
1563 pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1564 tty->driver->subtype == PTY_TYPE_MASTER);
1565 devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 o_tty = tty->link;
1567
1568#ifdef TTY_PARANOIA_CHECK
1569 if (idx < 0 || idx >= tty->driver->num) {
Alan Coxd81ed102008-10-13 10:41:42 +01001570 printk(KERN_DEBUG "tty_release_dev: bad idx when trying to "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 "free (%s)\n", tty->name);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001572 tty_unlock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001573 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 }
Alan Cox8b0a88d2008-10-13 10:42:19 +01001575 if (!devpts) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 if (tty != tty->driver->ttys[idx]) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001577 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001578 printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 "for (%s)\n", idx, tty->name);
Alan Coxeeb89d92009-11-30 13:18:29 +00001580 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 }
1582 if (tty->termios != tty->driver->termios[idx]) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001583 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001584 printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 "for (%s)\n",
1586 idx, tty->name);
Alan Coxeeb89d92009-11-30 13:18:29 +00001587 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 }
1590#endif
1591
1592#ifdef TTY_DEBUG_HANGUP
Alan Coxd81ed102008-10-13 10:41:42 +01001593 printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 tty_name(tty, buf), tty->count);
1595#endif
1596
1597#ifdef TTY_PARANOIA_CHECK
1598 if (tty->driver->other &&
1599 !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
1600 if (o_tty != tty->driver->other->ttys[idx]) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001601 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001602 printk(KERN_DEBUG "tty_release_dev: other->table[%d] "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 "not o_tty for (%s)\n",
1604 idx, tty->name);
Alan Coxeeb89d92009-11-30 13:18:29 +00001605 return 0 ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 }
1607 if (o_tty->termios != tty->driver->other->termios[idx]) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001608 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001609 printk(KERN_DEBUG "tty_release_dev: other->termios[%d] "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 "not o_termios for (%s)\n",
1611 idx, tty->name);
Alan Coxeeb89d92009-11-30 13:18:29 +00001612 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 if (o_tty->link != tty) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001615 tty_unlock();
Alan Coxd81ed102008-10-13 10:41:42 +01001616 printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n");
Alan Coxeeb89d92009-11-30 13:18:29 +00001617 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 }
1619 }
1620#endif
Alan Coxf34d7a52008-04-30 00:54:13 -07001621 if (tty->ops->close)
1622 tty->ops->close(tty, filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
Arnd Bergmannec79d602010-06-01 22:53:01 +02001624 tty_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 /*
1626 * Sanity check: if tty->count is going to zero, there shouldn't be
1627 * any waiters on tty->read_wait or tty->write_wait. We test the
1628 * wait queues and kick everyone out _before_ actually starting to
1629 * close. This ensures that we won't block while releasing the tty
1630 * structure.
1631 *
1632 * The test for the o_tty closing is necessary, since the master and
1633 * slave sides may close in any order. If the slave side closes out
1634 * first, its count will be one, since the master side holds an open.
1635 * Thus this test wouldn't be triggered at the time the slave closes,
1636 * so we do it now.
1637 *
1638 * Note that it's possible for the tty to be opened again while we're
1639 * flushing out waiters. By recalculating the closing flags before
1640 * each iteration we avoid any problems.
1641 */
1642 while (1) {
1643 /* Guard against races with tty->count changes elsewhere and
1644 opens on /dev/tty */
Alan Cox37bdfb02008-02-08 04:18:47 -08001645
Ingo Molnar70522e12006-03-23 03:00:31 -08001646 mutex_lock(&tty_mutex);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001647 tty_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 tty_closing = tty->count <= 1;
1649 o_tty_closing = o_tty &&
1650 (o_tty->count <= (pty_master ? 1 : 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 do_sleep = 0;
1652
1653 if (tty_closing) {
1654 if (waitqueue_active(&tty->read_wait)) {
Davide Libenzi4b194492009-03-31 15:24:24 -07001655 wake_up_poll(&tty->read_wait, POLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 do_sleep++;
1657 }
1658 if (waitqueue_active(&tty->write_wait)) {
Davide Libenzi4b194492009-03-31 15:24:24 -07001659 wake_up_poll(&tty->write_wait, POLLOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 do_sleep++;
1661 }
1662 }
1663 if (o_tty_closing) {
1664 if (waitqueue_active(&o_tty->read_wait)) {
Davide Libenzi4b194492009-03-31 15:24:24 -07001665 wake_up_poll(&o_tty->read_wait, POLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 do_sleep++;
1667 }
1668 if (waitqueue_active(&o_tty->write_wait)) {
Davide Libenzi4b194492009-03-31 15:24:24 -07001669 wake_up_poll(&o_tty->write_wait, POLLOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 do_sleep++;
1671 }
1672 }
1673 if (!do_sleep)
1674 break;
1675
Alan Coxd81ed102008-10-13 10:41:42 +01001676 printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 "active!\n", tty_name(tty, buf));
Arnd Bergmannec79d602010-06-01 22:53:01 +02001678 tty_unlock();
Ingo Molnar70522e12006-03-23 03:00:31 -08001679 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 schedule();
Alan Cox37bdfb02008-02-08 04:18:47 -08001681 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682
1683 /*
Alan Cox37bdfb02008-02-08 04:18:47 -08001684 * The closing flags are now consistent with the open counts on
1685 * both sides, and we've completed the last operation that could
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 * block, so it's safe to proceed with closing.
1687 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 if (pty_master) {
1689 if (--o_tty->count < 0) {
Alan Coxd81ed102008-10-13 10:41:42 +01001690 printk(KERN_WARNING "tty_release_dev: bad pty slave count "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 "(%d) for %s\n",
1692 o_tty->count, tty_name(o_tty, buf));
1693 o_tty->count = 0;
1694 }
1695 }
1696 if (--tty->count < 0) {
Alan Coxd81ed102008-10-13 10:41:42 +01001697 printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 tty->count, tty_name(tty, buf));
1699 tty->count = 0;
1700 }
Alan Cox37bdfb02008-02-08 04:18:47 -08001701
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 /*
1703 * We've decremented tty->count, so we need to remove this file
1704 * descriptor off the tty->tty_files list; this serves two
1705 * purposes:
1706 * - check_tty_count sees the correct number of file descriptors
1707 * associated with this tty.
1708 * - do_tty_hangup no longer sees this file descriptor as
1709 * something that needs to be handled for hangups.
1710 */
Nick Piggind996b622010-08-18 04:37:36 +10001711 tty_del_file(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
1713 /*
1714 * Perform some housekeeping before deciding whether to return.
1715 *
1716 * Set the TTY_CLOSING flag if this was the last open. In the
1717 * case of a pty we may have to wait around for the other side
1718 * to close, and TTY_CLOSING makes sure we can't be reopened.
1719 */
Alan Cox37bdfb02008-02-08 04:18:47 -08001720 if (tty_closing)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 set_bit(TTY_CLOSING, &tty->flags);
Alan Cox37bdfb02008-02-08 04:18:47 -08001722 if (o_tty_closing)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 set_bit(TTY_CLOSING, &o_tty->flags);
1724
1725 /*
1726 * If _either_ side is closing, make sure there aren't any
1727 * processes that still think tty or o_tty is their controlling
1728 * tty.
1729 */
1730 if (tty_closing || o_tty_closing) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 read_lock(&tasklist_lock);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001732 session_clear_tty(tty->session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 if (o_tty)
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001734 session_clear_tty(o_tty->session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 read_unlock(&tasklist_lock);
1736 }
1737
Ingo Molnar70522e12006-03-23 03:00:31 -08001738 mutex_unlock(&tty_mutex);
Paul Fulghumda965822006-02-14 13:53:00 -08001739
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 /* check whether both sides are closing ... */
Alan Coxeeb89d92009-11-30 13:18:29 +00001741 if (!tty_closing || (o_tty && !o_tty_closing)) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001742 tty_unlock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001743 return 0;
1744 }
Alan Cox37bdfb02008-02-08 04:18:47 -08001745
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746#ifdef TTY_DEBUG_HANGUP
1747 printk(KERN_DEBUG "freeing tty structure...");
1748#endif
1749 /*
Alan Cox01e1abb2008-07-22 11:16:55 +01001750 * Ask the line discipline code to release its structures
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 */
Alan Cox01e1abb2008-07-22 11:16:55 +01001752 tty_ldisc_release(tty, o_tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 /*
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001754 * The release_tty function takes care of the details of clearing
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 * the slots and preserving the termios structure.
1756 */
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001757 release_tty(tty, idx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 /* Make this pty number available for reallocation */
Sukadev Bhattiprolu718a9162008-04-30 00:54:21 -07001760 if (devpts)
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001761 devpts_kill_index(inode, idx);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001762 tty_unlock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001763 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764}
1765
Alan Coxaf9b8972006-08-27 01:24:01 -07001766/**
Alan Coxeeb89d92009-11-30 13:18:29 +00001767 * tty_open - open a tty device
Alan Coxaf9b8972006-08-27 01:24:01 -07001768 * @inode: inode of device file
1769 * @filp: file pointer to tty
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 *
Alan Coxaf9b8972006-08-27 01:24:01 -07001771 * tty_open and tty_release keep up the tty count that contains the
1772 * number of opens done on a tty. We cannot use the inode-count, as
1773 * different inodes might point to the same tty.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 *
Alan Coxaf9b8972006-08-27 01:24:01 -07001775 * Open-counting is needed for pty masters, as well as for keeping
1776 * track of serial lines: DTR is dropped when the last close happens.
1777 * (This is not done solely through tty->count, now. - Ted 1/27/92)
1778 *
1779 * The termios state of a pty is reset on first open so that
1780 * settings don't persist across reuse.
1781 *
Alan Coxd81ed102008-10-13 10:41:42 +01001782 * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work.
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001783 * tty->count should protect the rest.
1784 * ->siglock protects ->signal/->sighand
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 */
Alan Coxaf9b8972006-08-27 01:24:01 -07001786
Alan Coxeeb89d92009-11-30 13:18:29 +00001787static int tty_open(struct inode *inode, struct file *filp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788{
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001789 struct tty_struct *tty = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 int noctty, retval;
1791 struct tty_driver *driver;
1792 int index;
1793 dev_t device = inode->i_rdev;
Andrew Morton846c1512009-04-02 16:56:36 -07001794 unsigned saved_flags = filp->f_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
1796 nonseekable_open(inode, filp);
Alan Cox37bdfb02008-02-08 04:18:47 -08001797
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798retry_open:
1799 noctty = filp->f_flags & O_NOCTTY;
1800 index = -1;
1801 retval = 0;
Alan Cox37bdfb02008-02-08 04:18:47 -08001802
Ingo Molnar70522e12006-03-23 03:00:31 -08001803 mutex_lock(&tty_mutex);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001804 tty_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805
Alan Cox37bdfb02008-02-08 04:18:47 -08001806 if (device == MKDEV(TTYAUX_MAJOR, 0)) {
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001807 tty = get_current_tty();
1808 if (!tty) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001809 tty_unlock();
Ingo Molnar70522e12006-03-23 03:00:31 -08001810 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 return -ENXIO;
1812 }
Alan Cox7d7b93c2008-10-13 10:42:09 +01001813 driver = tty_driver_kref_get(tty->driver);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001814 index = tty->index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
1816 /* noctty = 1; */
Alan Cox452a00d2008-10-13 10:39:13 +01001817 /* FIXME: Should we take a driver reference ? */
1818 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 goto got_driver;
1820 }
1821#ifdef CONFIG_VT
Alan Cox37bdfb02008-02-08 04:18:47 -08001822 if (device == MKDEV(TTY_MAJOR, 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 extern struct tty_driver *console_driver;
Alan Cox7d7b93c2008-10-13 10:42:09 +01001824 driver = tty_driver_kref_get(console_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 index = fg_console;
1826 noctty = 1;
1827 goto got_driver;
1828 }
1829#endif
Alan Cox37bdfb02008-02-08 04:18:47 -08001830 if (device == MKDEV(TTYAUX_MAJOR, 1)) {
Will Newton296fa7f2008-12-01 11:36:06 +00001831 struct tty_driver *console_driver = console_device(&index);
1832 if (console_driver) {
1833 driver = tty_driver_kref_get(console_driver);
1834 if (driver) {
1835 /* Don't let /dev/console block */
1836 filp->f_flags |= O_NONBLOCK;
1837 noctty = 1;
1838 goto got_driver;
1839 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 }
Arnd Bergmannec79d602010-06-01 22:53:01 +02001841 tty_unlock();
Ingo Molnar70522e12006-03-23 03:00:31 -08001842 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 return -ENODEV;
1844 }
1845
1846 driver = get_tty_driver(device, &index);
1847 if (!driver) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001848 tty_unlock();
Ingo Molnar70522e12006-03-23 03:00:31 -08001849 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 return -ENODEV;
1851 }
1852got_driver:
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001853 if (!tty) {
1854 /* check whether we're reopening an existing tty */
Sukadev Bhattiprolu15f1a632008-10-13 10:42:59 +01001855 tty = tty_driver_lookup_tty(driver, inode, index);
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001856
Eric Paris808ffa32009-01-27 11:50:37 +00001857 if (IS_ERR(tty)) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001858 tty_unlock();
Eric Paris808ffa32009-01-27 11:50:37 +00001859 mutex_unlock(&tty_mutex);
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001860 return PTR_ERR(tty);
Eric Paris808ffa32009-01-27 11:50:37 +00001861 }
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01001862 }
1863
1864 if (tty) {
1865 retval = tty_reopen(tty);
1866 if (retval)
1867 tty = ERR_PTR(retval);
1868 } else
1869 tty = tty_init_dev(driver, index, 0);
1870
Ingo Molnar70522e12006-03-23 03:00:31 -08001871 mutex_unlock(&tty_mutex);
Alan Cox7d7b93c2008-10-13 10:42:09 +01001872 tty_driver_kref_put(driver);
Alan Coxeeb89d92009-11-30 13:18:29 +00001873 if (IS_ERR(tty)) {
Arnd Bergmannec79d602010-06-01 22:53:01 +02001874 tty_unlock();
Alan Cox73ec06f2008-10-13 10:42:29 +01001875 return PTR_ERR(tty);
Alan Coxeeb89d92009-11-30 13:18:29 +00001876 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
Nick Piggind996b622010-08-18 04:37:36 +10001878 tty_add_file(tty, filp);
1879
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 check_tty_count(tty, "tty_open");
1881 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1882 tty->driver->subtype == PTY_TYPE_MASTER)
1883 noctty = 1;
1884#ifdef TTY_DEBUG_HANGUP
1885 printk(KERN_DEBUG "opening %s...", tty->name);
1886#endif
1887 if (!retval) {
Alan Coxf34d7a52008-04-30 00:54:13 -07001888 if (tty->ops->open)
1889 retval = tty->ops->open(tty, filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 else
1891 retval = -ENODEV;
1892 }
1893 filp->f_flags = saved_flags;
1894
Alan Cox37bdfb02008-02-08 04:18:47 -08001895 if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) &&
1896 !capable(CAP_SYS_ADMIN))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 retval = -EBUSY;
1898
1899 if (retval) {
1900#ifdef TTY_DEBUG_HANGUP
1901 printk(KERN_DEBUG "error %d in opening %s...", retval,
1902 tty->name);
1903#endif
Arnd Bergmann64ba3dc2010-06-01 22:53:02 +02001904 tty_unlock(); /* need to call tty_release without BTM */
Alan Coxeeb89d92009-11-30 13:18:29 +00001905 tty_release(inode, filp);
Arnd Bergmann64ba3dc2010-06-01 22:53:02 +02001906 if (retval != -ERESTARTSYS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 return retval;
Arnd Bergmann64ba3dc2010-06-01 22:53:02 +02001908
1909 if (signal_pending(current))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910 return retval;
Arnd Bergmann64ba3dc2010-06-01 22:53:02 +02001911
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 schedule();
1913 /*
1914 * Need to reset f_op in case a hangup happened.
1915 */
Arnd Bergmann64ba3dc2010-06-01 22:53:02 +02001916 tty_lock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917 if (filp->f_op == &hung_up_tty_fops)
1918 filp->f_op = &tty_fops;
Arnd Bergmannec79d602010-06-01 22:53:01 +02001919 tty_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 goto retry_open;
1921 }
Arnd Bergmannec79d602010-06-01 22:53:01 +02001922 tty_unlock();
Alan Coxeeb89d92009-11-30 13:18:29 +00001923
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001924
1925 mutex_lock(&tty_mutex);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001926 tty_lock();
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001927 spin_lock_irq(&current->sighand->siglock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 if (!noctty &&
1929 current->signal->leader &&
1930 !current->signal->tty &&
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08001931 tty->session == NULL)
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -07001932 __proc_set_tty(current, tty);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001933 spin_unlock_irq(&current->sighand->siglock);
Arnd Bergmannec79d602010-06-01 22:53:01 +02001934 tty_unlock();
Peter Zijlstra24ec8392006-12-08 02:36:04 -08001935 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 return 0;
1937}
1938
Jonathan Corbet39d95b92008-05-16 09:10:50 -06001939
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940
Alan Coxaf9b8972006-08-27 01:24:01 -07001941/**
1942 * tty_poll - check tty status
1943 * @filp: file being polled
1944 * @wait: poll wait structures to update
1945 *
1946 * Call the line discipline polling method to obtain the poll
1947 * status of the device.
1948 *
1949 * Locking: locks called line discipline but ldisc poll method
1950 * may be re-entered freely by other callers.
1951 */
1952
Alan Cox37bdfb02008-02-08 04:18:47 -08001953static unsigned int tty_poll(struct file *filp, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954{
Nick Piggind996b622010-08-18 04:37:36 +10001955 struct tty_struct *tty = file_tty(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 struct tty_ldisc *ld;
1957 int ret = 0;
1958
Josef Sipeka7113a92006-12-08 02:36:55 -08001959 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 return 0;
Alan Cox37bdfb02008-02-08 04:18:47 -08001961
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +01001963 if (ld->ops->poll)
1964 ret = (ld->ops->poll)(tty, filp, wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 tty_ldisc_deref(ld);
1966 return ret;
1967}
1968
Arnd Bergmannec79d602010-06-01 22:53:01 +02001969static int __tty_fasync(int fd, struct file *filp, int on)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970{
Nick Piggind996b622010-08-18 04:37:36 +10001971 struct tty_struct *tty = file_tty(filp);
Alan Cox47f86832008-04-30 00:53:30 -07001972 unsigned long flags;
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06001973 int retval = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974
Josef Sipeka7113a92006-12-08 02:36:55 -08001975 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06001976 goto out;
Alan Cox37bdfb02008-02-08 04:18:47 -08001977
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978 retval = fasync_helper(fd, filp, on, &tty->fasync);
1979 if (retval <= 0)
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06001980 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981
1982 if (on) {
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08001983 enum pid_type type;
1984 struct pid *pid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985 if (!waitqueue_active(&tty->read_wait))
1986 tty->minimum_to_wake = 1;
Alan Cox47f86832008-04-30 00:53:30 -07001987 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08001988 if (tty->pgrp) {
1989 pid = tty->pgrp;
1990 type = PIDTYPE_PGID;
1991 } else {
1992 pid = task_pid(current);
1993 type = PIDTYPE_PID;
1994 }
Linus Torvalds80e1e822010-02-07 10:11:23 -08001995 get_pid(pid);
Greg Kroah-Hartman70362512009-12-17 07:07:19 -08001996 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds80e1e822010-02-07 10:11:23 -08001997 retval = __f_setown(filp, pid, type, 0);
1998 put_pid(pid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999 if (retval)
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002000 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001 } else {
2002 if (!tty->fasync && !waitqueue_active(&tty->read_wait))
2003 tty->minimum_to_wake = N_TTY_BUF_SIZE;
2004 }
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002005 retval = 0;
2006out:
Arnd Bergmannec79d602010-06-01 22:53:01 +02002007 return retval;
2008}
2009
2010static int tty_fasync(int fd, struct file *filp, int on)
2011{
2012 int retval;
2013 tty_lock();
2014 retval = __tty_fasync(fd, filp, on);
2015 tty_unlock();
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002016 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017}
2018
Alan Coxaf9b8972006-08-27 01:24:01 -07002019/**
2020 * tiocsti - fake input character
2021 * @tty: tty to fake input into
2022 * @p: pointer to character
2023 *
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +02002024 * Fake input to a tty device. Does the necessary locking and
Alan Coxaf9b8972006-08-27 01:24:01 -07002025 * input management.
2026 *
2027 * FIXME: does not honour flow control ??
2028 *
2029 * Locking:
2030 * Called functions take tty_ldisc_lock
2031 * current->signal->tty check is safe without locks
Alan Cox28298232006-09-29 02:00:58 -07002032 *
2033 * FIXME: may race normal receive processing
Alan Coxaf9b8972006-08-27 01:24:01 -07002034 */
2035
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036static int tiocsti(struct tty_struct *tty, char __user *p)
2037{
2038 char ch, mbz = 0;
2039 struct tty_ldisc *ld;
Alan Cox37bdfb02008-02-08 04:18:47 -08002040
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
2042 return -EPERM;
2043 if (get_user(ch, p))
2044 return -EFAULT;
Al Viro1e641742008-12-09 09:23:33 +00002045 tty_audit_tiocsti(tty, ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +01002047 ld->ops->receive_buf(tty, &ch, &mbz, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048 tty_ldisc_deref(ld);
2049 return 0;
2050}
2051
Alan Coxaf9b8972006-08-27 01:24:01 -07002052/**
2053 * tiocgwinsz - implement window query ioctl
2054 * @tty; tty
2055 * @arg: user buffer for result
2056 *
Alan Cox808a0d32006-09-29 02:00:40 -07002057 * Copies the kernel idea of the window size into the user buffer.
Alan Coxaf9b8972006-08-27 01:24:01 -07002058 *
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002059 * Locking: tty->termios_mutex is taken to ensure the winsize data
Alan Cox808a0d32006-09-29 02:00:40 -07002060 * is consistent.
Alan Coxaf9b8972006-08-27 01:24:01 -07002061 */
2062
Alan Cox37bdfb02008-02-08 04:18:47 -08002063static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064{
Alan Cox808a0d32006-09-29 02:00:40 -07002065 int err;
2066
Arjan van de Ven5785c952006-09-29 02:00:43 -07002067 mutex_lock(&tty->termios_mutex);
Alan Cox808a0d32006-09-29 02:00:40 -07002068 err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
Arjan van de Ven5785c952006-09-29 02:00:43 -07002069 mutex_unlock(&tty->termios_mutex);
Alan Cox808a0d32006-09-29 02:00:40 -07002070
2071 return err ? -EFAULT: 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072}
2073
Alan Coxaf9b8972006-08-27 01:24:01 -07002074/**
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002075 * tty_do_resize - resize event
2076 * @tty: tty being resized
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002077 * @rows: rows (character)
2078 * @cols: cols (character)
Alan Coxaf9b8972006-08-27 01:24:01 -07002079 *
Daniel Mack3ad2f3f2010-02-03 08:01:28 +08002080 * Update the termios variables and send the necessary signals to
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002081 * peform a terminal resize correctly
Alan Coxaf9b8972006-08-27 01:24:01 -07002082 */
2083
Alan Coxfc6f6232009-01-02 13:43:17 +00002084int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085{
Alan Coxfc6f6232009-01-02 13:43:17 +00002086 struct pid *pgrp;
Alan Cox47f86832008-04-30 00:53:30 -07002087 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088
Alan Coxfc6f6232009-01-02 13:43:17 +00002089 /* Lock the tty */
2090 mutex_lock(&tty->termios_mutex);
2091 if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
Alan Coxca9bda02006-09-29 02:00:03 -07002092 goto done;
Alan Cox47f86832008-04-30 00:53:30 -07002093 /* Get the PID values and reference them so we can
2094 avoid holding the tty ctrl lock while sending signals */
2095 spin_lock_irqsave(&tty->ctrl_lock, flags);
2096 pgrp = get_pid(tty->pgrp);
Alan Cox47f86832008-04-30 00:53:30 -07002097 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
2098
2099 if (pgrp)
2100 kill_pgrp(pgrp, SIGWINCH, 1);
Alan Cox47f86832008-04-30 00:53:30 -07002101 put_pid(pgrp);
Alan Cox47f86832008-04-30 00:53:30 -07002102
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002103 tty->winsize = *ws;
Alan Coxca9bda02006-09-29 02:00:03 -07002104done:
Alan Coxfc6f6232009-01-02 13:43:17 +00002105 mutex_unlock(&tty->termios_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002106 return 0;
2107}
2108
Alan Coxaf9b8972006-08-27 01:24:01 -07002109/**
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002110 * tiocswinsz - implement window size set ioctl
Alan Coxfc6f6232009-01-02 13:43:17 +00002111 * @tty; tty side of tty
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002112 * @arg: user buffer for result
2113 *
2114 * Copies the user idea of the window size to the kernel. Traditionally
2115 * this is just advisory information but for the Linux console it
2116 * actually has driver level meaning and triggers a VC resize.
2117 *
2118 * Locking:
2119 * Driver dependant. The default do_resize method takes the
2120 * tty termios mutex and ctrl_lock. The console takes its own lock
2121 * then calls into the default method.
2122 */
2123
Alan Coxfc6f6232009-01-02 13:43:17 +00002124static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg)
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002125{
2126 struct winsize tmp_ws;
2127 if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
2128 return -EFAULT;
2129
2130 if (tty->ops->resize)
Alan Coxfc6f6232009-01-02 13:43:17 +00002131 return tty->ops->resize(tty, &tmp_ws);
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002132 else
Alan Coxfc6f6232009-01-02 13:43:17 +00002133 return tty_do_resize(tty, &tmp_ws);
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002134}
2135
2136/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002137 * tioccons - allow admin to move logical console
2138 * @file: the file to become console
2139 *
2140 * Allow the adminstrator to move the redirected console device
2141 *
2142 * Locking: uses redirect_lock to guard the redirect information
2143 */
2144
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145static int tioccons(struct file *file)
2146{
2147 if (!capable(CAP_SYS_ADMIN))
2148 return -EPERM;
2149 if (file->f_op->write == redirected_tty_write) {
2150 struct file *f;
2151 spin_lock(&redirect_lock);
2152 f = redirect;
2153 redirect = NULL;
2154 spin_unlock(&redirect_lock);
2155 if (f)
2156 fput(f);
2157 return 0;
2158 }
2159 spin_lock(&redirect_lock);
2160 if (redirect) {
2161 spin_unlock(&redirect_lock);
2162 return -EBUSY;
2163 }
2164 get_file(file);
2165 redirect = file;
2166 spin_unlock(&redirect_lock);
2167 return 0;
2168}
2169
Alan Coxaf9b8972006-08-27 01:24:01 -07002170/**
2171 * fionbio - non blocking ioctl
2172 * @file: file to set blocking value
2173 * @p: user parameter
2174 *
2175 * Historical tty interfaces had a blocking control ioctl before
2176 * the generic functionality existed. This piece of history is preserved
2177 * in the expected tty API of posix OS's.
2178 *
Alan Cox6146b9a2009-09-19 13:13:19 -07002179 * Locking: none, the open file handle ensures it won't go away.
Alan Coxaf9b8972006-08-27 01:24:01 -07002180 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181
2182static int fionbio(struct file *file, int __user *p)
2183{
2184 int nonblock;
2185
2186 if (get_user(nonblock, p))
2187 return -EFAULT;
2188
Jonathan Corbetdb1dd4d2009-02-06 15:25:24 -07002189 spin_lock(&file->f_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002190 if (nonblock)
2191 file->f_flags |= O_NONBLOCK;
2192 else
2193 file->f_flags &= ~O_NONBLOCK;
Jonathan Corbetdb1dd4d2009-02-06 15:25:24 -07002194 spin_unlock(&file->f_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 return 0;
2196}
2197
Alan Coxaf9b8972006-08-27 01:24:01 -07002198/**
2199 * tiocsctty - set controlling tty
2200 * @tty: tty structure
2201 * @arg: user argument
2202 *
2203 * This ioctl is used to manage job control. It permits a session
2204 * leader to set this tty as the controlling tty for the session.
2205 *
2206 * Locking:
Alan Cox28298232006-09-29 02:00:58 -07002207 * Takes tty_mutex() to protect tty instance
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002208 * Takes tasklist_lock internally to walk sessions
2209 * Takes ->siglock() when updating signal->tty
Alan Coxaf9b8972006-08-27 01:24:01 -07002210 */
2211
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212static int tiocsctty(struct tty_struct *tty, int arg)
2213{
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002214 int ret = 0;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002215 if (current->signal->leader && (task_session(current) == tty->session))
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002216 return ret;
2217
2218 mutex_lock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219 /*
2220 * The process must be a session leader and
2221 * not have a controlling tty already.
2222 */
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002223 if (!current->signal->leader || current->signal->tty) {
2224 ret = -EPERM;
2225 goto unlock;
2226 }
2227
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002228 if (tty->session) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229 /*
2230 * This tty is already the controlling
2231 * tty for another session group!
2232 */
Alan Cox37bdfb02008-02-08 04:18:47 -08002233 if (arg == 1 && capable(CAP_SYS_ADMIN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 /*
2235 * Steal it away
2236 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 read_lock(&tasklist_lock);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002238 session_clear_tty(tty->session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 read_unlock(&tasklist_lock);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002240 } else {
2241 ret = -EPERM;
2242 goto unlock;
2243 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244 }
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002245 proc_set_tty(current, tty);
2246unlock:
Alan Cox28298232006-09-29 02:00:58 -07002247 mutex_unlock(&tty_mutex);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002248 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249}
2250
Alan Coxaf9b8972006-08-27 01:24:01 -07002251/**
Alan Cox5d0fdf12008-04-30 00:53:31 -07002252 * tty_get_pgrp - return a ref counted pgrp pid
2253 * @tty: tty to read
2254 *
2255 * Returns a refcounted instance of the pid struct for the process
2256 * group controlling the tty.
2257 */
2258
2259struct pid *tty_get_pgrp(struct tty_struct *tty)
2260{
2261 unsigned long flags;
2262 struct pid *pgrp;
2263
2264 spin_lock_irqsave(&tty->ctrl_lock, flags);
2265 pgrp = get_pid(tty->pgrp);
2266 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
2267
2268 return pgrp;
2269}
2270EXPORT_SYMBOL_GPL(tty_get_pgrp);
2271
2272/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002273 * tiocgpgrp - get process group
2274 * @tty: tty passed by user
2275 * @real_tty: tty side of the tty pased by the user if a pty else the tty
2276 * @p: returned pid
2277 *
2278 * Obtain the process group of the tty. If there is no process group
2279 * return an error.
2280 *
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002281 * Locking: none. Reference to current->signal->tty is safe.
Alan Coxaf9b8972006-08-27 01:24:01 -07002282 */
2283
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
2285{
Alan Cox5d0fdf12008-04-30 00:53:31 -07002286 struct pid *pid;
2287 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 /*
2289 * (tty == real_tty) is a cheap way of
2290 * testing if the tty is NOT a master pty.
2291 */
2292 if (tty == real_tty && current->signal->tty != real_tty)
2293 return -ENOTTY;
Alan Cox5d0fdf12008-04-30 00:53:31 -07002294 pid = tty_get_pgrp(real_tty);
2295 ret = put_user(pid_vnr(pid), p);
2296 put_pid(pid);
2297 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298}
2299
Alan Coxaf9b8972006-08-27 01:24:01 -07002300/**
2301 * tiocspgrp - attempt to set process group
2302 * @tty: tty passed by user
2303 * @real_tty: tty side device matching tty passed by user
2304 * @p: pid pointer
2305 *
2306 * Set the process group of the tty to the session passed. Only
2307 * permitted where the tty session is our session.
2308 *
Alan Cox47f86832008-04-30 00:53:30 -07002309 * Locking: RCU, ctrl lock
Alan Coxaf9b8972006-08-27 01:24:01 -07002310 */
2311
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
2313{
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002314 struct pid *pgrp;
2315 pid_t pgrp_nr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 int retval = tty_check_change(real_tty);
Alan Cox47f86832008-04-30 00:53:30 -07002317 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318
2319 if (retval == -EIO)
2320 return -ENOTTY;
2321 if (retval)
2322 return retval;
2323 if (!current->signal->tty ||
2324 (current->signal->tty != real_tty) ||
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002325 (real_tty->session != task_session(current)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 return -ENOTTY;
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002327 if (get_user(pgrp_nr, p))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328 return -EFAULT;
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002329 if (pgrp_nr < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330 return -EINVAL;
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002331 rcu_read_lock();
Pavel Emelyanovb4888932007-10-18 23:40:14 -07002332 pgrp = find_vpid(pgrp_nr);
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002333 retval = -ESRCH;
2334 if (!pgrp)
2335 goto out_unlock;
2336 retval = -EPERM;
2337 if (session_of_pgrp(pgrp) != task_session(current))
2338 goto out_unlock;
2339 retval = 0;
Alan Cox47f86832008-04-30 00:53:30 -07002340 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002341 put_pid(real_tty->pgrp);
2342 real_tty->pgrp = get_pid(pgrp);
Alan Cox47f86832008-04-30 00:53:30 -07002343 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Eric W. Biederman04a2e6a2007-02-12 00:52:56 -08002344out_unlock:
2345 rcu_read_unlock();
2346 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347}
2348
Alan Coxaf9b8972006-08-27 01:24:01 -07002349/**
2350 * tiocgsid - get session id
2351 * @tty: tty passed by user
2352 * @real_tty: tty side of the tty pased by the user if a pty else the tty
2353 * @p: pointer to returned session id
2354 *
2355 * Obtain the session id of the tty. If there is no session
2356 * return an error.
2357 *
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002358 * Locking: none. Reference to current->signal->tty is safe.
Alan Coxaf9b8972006-08-27 01:24:01 -07002359 */
2360
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
2362{
2363 /*
2364 * (tty == real_tty) is a cheap way of
2365 * testing if the tty is NOT a master pty.
2366 */
2367 if (tty == real_tty && current->signal->tty != real_tty)
2368 return -ENOTTY;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002369 if (!real_tty->session)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370 return -ENOTTY;
Pavel Emelyanovb4888932007-10-18 23:40:14 -07002371 return put_user(pid_vnr(real_tty->session), p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372}
2373
Alan Coxaf9b8972006-08-27 01:24:01 -07002374/**
2375 * tiocsetd - set line discipline
2376 * @tty: tty device
2377 * @p: pointer to user data
2378 *
2379 * Set the line discipline according to user request.
2380 *
2381 * Locking: see tty_set_ldisc, this function is just a helper
2382 */
2383
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384static int tiocsetd(struct tty_struct *tty, int __user *p)
2385{
2386 int ldisc;
Alan Cox04f378b2008-04-30 00:53:29 -07002387 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388
2389 if (get_user(ldisc, p))
2390 return -EFAULT;
Alan Cox04f378b2008-04-30 00:53:29 -07002391
Alan Cox04f378b2008-04-30 00:53:29 -07002392 ret = tty_set_ldisc(tty, ldisc);
Alan Cox04f378b2008-04-30 00:53:29 -07002393
2394 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395}
2396
Alan Coxaf9b8972006-08-27 01:24:01 -07002397/**
2398 * send_break - performed time break
2399 * @tty: device to break on
2400 * @duration: timeout in mS
2401 *
2402 * Perform a timed break on hardware that lacks its own driver level
2403 * timed break functionality.
2404 *
2405 * Locking:
Alan Cox28298232006-09-29 02:00:58 -07002406 * atomic_write_lock serializes
Alan Coxaf9b8972006-08-27 01:24:01 -07002407 *
Alan Coxaf9b8972006-08-27 01:24:01 -07002408 */
2409
Domen Puncerb20f3ae2005-06-25 14:58:42 -07002410static int send_break(struct tty_struct *tty, unsigned int duration)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411{
Alan Cox9e989662008-07-22 11:18:03 +01002412 int retval;
2413
2414 if (tty->ops->break_ctl == NULL)
2415 return 0;
2416
2417 if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
2418 retval = tty->ops->break_ctl(tty, duration);
2419 else {
2420 /* Do the work ourselves */
2421 if (tty_write_lock(tty, 0) < 0)
2422 return -EINTR;
2423 retval = tty->ops->break_ctl(tty, -1);
2424 if (retval)
2425 goto out;
2426 if (!signal_pending(current))
2427 msleep_interruptible(duration);
2428 retval = tty->ops->break_ctl(tty, 0);
2429out:
2430 tty_write_unlock(tty);
2431 if (signal_pending(current))
2432 retval = -EINTR;
2433 }
2434 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435}
2436
Alan Coxaf9b8972006-08-27 01:24:01 -07002437/**
Alan Coxf34d7a52008-04-30 00:54:13 -07002438 * tty_tiocmget - get modem status
Alan Coxaf9b8972006-08-27 01:24:01 -07002439 * @tty: tty device
2440 * @file: user file pointer
2441 * @p: pointer to result
2442 *
2443 * Obtain the modem status bits from the tty driver if the feature
2444 * is supported. Return -EINVAL if it is not available.
2445 *
2446 * Locking: none (up to the driver)
2447 */
2448
2449static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450{
2451 int retval = -EINVAL;
2452
Alan Coxf34d7a52008-04-30 00:54:13 -07002453 if (tty->ops->tiocmget) {
2454 retval = tty->ops->tiocmget(tty, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455
2456 if (retval >= 0)
2457 retval = put_user(retval, p);
2458 }
2459 return retval;
2460}
2461
Alan Coxaf9b8972006-08-27 01:24:01 -07002462/**
Alan Coxf34d7a52008-04-30 00:54:13 -07002463 * tty_tiocmset - set modem status
Alan Coxaf9b8972006-08-27 01:24:01 -07002464 * @tty: tty device
2465 * @file: user file pointer
2466 * @cmd: command - clear bits, set bits or set all
2467 * @p: pointer to desired bits
2468 *
2469 * Set the modem status bits from the tty driver if the feature
2470 * is supported. Return -EINVAL if it is not available.
2471 *
2472 * Locking: none (up to the driver)
2473 */
2474
2475static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476 unsigned __user *p)
2477{
Alan Coxae677512008-07-16 21:56:54 +01002478 int retval;
2479 unsigned int set, clear, val;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480
Alan Coxae677512008-07-16 21:56:54 +01002481 if (tty->ops->tiocmset == NULL)
2482 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483
Alan Coxae677512008-07-16 21:56:54 +01002484 retval = get_user(val, p);
2485 if (retval)
2486 return retval;
2487 set = clear = 0;
2488 switch (cmd) {
2489 case TIOCMBIS:
2490 set = val;
2491 break;
2492 case TIOCMBIC:
2493 clear = val;
2494 break;
2495 case TIOCMSET:
2496 set = val;
2497 clear = ~val;
2498 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 }
Alan Coxae677512008-07-16 21:56:54 +01002500 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
2501 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
2502 return tty->ops->tiocmset(tty, file, set, clear);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503}
2504
Alan Coxe8b70e72009-06-11 12:48:02 +01002505struct tty_struct *tty_pair_get_tty(struct tty_struct *tty)
2506{
2507 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
2508 tty->driver->subtype == PTY_TYPE_MASTER)
2509 tty = tty->link;
2510 return tty;
2511}
2512EXPORT_SYMBOL(tty_pair_get_tty);
2513
2514struct tty_struct *tty_pair_get_pty(struct tty_struct *tty)
2515{
2516 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
2517 tty->driver->subtype == PTY_TYPE_MASTER)
2518 return tty;
2519 return tty->link;
2520}
2521EXPORT_SYMBOL(tty_pair_get_pty);
2522
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523/*
2524 * Split this up, as gcc can choke on it otherwise..
2525 */
Alan Cox04f378b2008-04-30 00:53:29 -07002526long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527{
Nick Piggind996b622010-08-18 04:37:36 +10002528 struct tty_struct *tty = file_tty(file);
2529 struct tty_struct *real_tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 void __user *p = (void __user *)arg;
2531 int retval;
2532 struct tty_ldisc *ld;
Alan Cox04f378b2008-04-30 00:53:29 -07002533 struct inode *inode = file->f_dentry->d_inode;
Alan Cox37bdfb02008-02-08 04:18:47 -08002534
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
2536 return -EINVAL;
2537
Alan Coxe8b70e72009-06-11 12:48:02 +01002538 real_tty = tty_pair_get_tty(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539
2540 /*
2541 * Factor out some common prep work
2542 */
2543 switch (cmd) {
2544 case TIOCSETD:
2545 case TIOCSBRK:
2546 case TIOCCBRK:
2547 case TCSBRK:
Alan Cox37bdfb02008-02-08 04:18:47 -08002548 case TCSBRKP:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 retval = tty_check_change(tty);
2550 if (retval)
2551 return retval;
2552 if (cmd != TIOCCBRK) {
2553 tty_wait_until_sent(tty, 0);
2554 if (signal_pending(current))
2555 return -EINTR;
2556 }
2557 break;
2558 }
2559
Alan Cox9e989662008-07-22 11:18:03 +01002560 /*
2561 * Now do the stuff.
2562 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563 switch (cmd) {
Alan Cox37bdfb02008-02-08 04:18:47 -08002564 case TIOCSTI:
2565 return tiocsti(tty, p);
2566 case TIOCGWINSZ:
Alan Cox8f520022008-10-13 10:38:46 +01002567 return tiocgwinsz(real_tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002568 case TIOCSWINSZ:
Alan Coxfc6f6232009-01-02 13:43:17 +00002569 return tiocswinsz(real_tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002570 case TIOCCONS:
2571 return real_tty != tty ? -EINVAL : tioccons(file);
2572 case FIONBIO:
2573 return fionbio(file, p);
2574 case TIOCEXCL:
2575 set_bit(TTY_EXCLUSIVE, &tty->flags);
2576 return 0;
2577 case TIOCNXCL:
2578 clear_bit(TTY_EXCLUSIVE, &tty->flags);
2579 return 0;
2580 case TIOCNOTTY:
2581 if (current->signal->tty != tty)
2582 return -ENOTTY;
2583 no_tty();
2584 return 0;
2585 case TIOCSCTTY:
2586 return tiocsctty(tty, arg);
2587 case TIOCGPGRP:
2588 return tiocgpgrp(tty, real_tty, p);
2589 case TIOCSPGRP:
2590 return tiocspgrp(tty, real_tty, p);
2591 case TIOCGSID:
2592 return tiocgsid(tty, real_tty, p);
2593 case TIOCGETD:
Alan Coxc65c9bc2009-06-11 12:50:12 +01002594 return put_user(tty->ldisc->ops->num, (int __user *)p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002595 case TIOCSETD:
2596 return tiocsetd(tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002597 /*
2598 * Break handling
2599 */
2600 case TIOCSBRK: /* Turn break on, unconditionally */
Alan Coxf34d7a52008-04-30 00:54:13 -07002601 if (tty->ops->break_ctl)
Alan Cox9e989662008-07-22 11:18:03 +01002602 return tty->ops->break_ctl(tty, -1);
Alan Cox37bdfb02008-02-08 04:18:47 -08002603 return 0;
Alan Cox37bdfb02008-02-08 04:18:47 -08002604 case TIOCCBRK: /* Turn break off, unconditionally */
Alan Coxf34d7a52008-04-30 00:54:13 -07002605 if (tty->ops->break_ctl)
Alan Cox9e989662008-07-22 11:18:03 +01002606 return tty->ops->break_ctl(tty, 0);
Alan Cox37bdfb02008-02-08 04:18:47 -08002607 return 0;
2608 case TCSBRK: /* SVID version: non-zero arg --> no break */
2609 /* non-zero arg means wait for all output data
2610 * to be sent (performed above) but don't send break.
2611 * This is used by the tcdrain() termios function.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612 */
Alan Cox37bdfb02008-02-08 04:18:47 -08002613 if (!arg)
2614 return send_break(tty, 250);
2615 return 0;
2616 case TCSBRKP: /* support for POSIX tcsendbreak() */
2617 return send_break(tty, arg ? arg*100 : 250);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618
Alan Cox37bdfb02008-02-08 04:18:47 -08002619 case TIOCMGET:
2620 return tty_tiocmget(tty, file, p);
2621 case TIOCMSET:
2622 case TIOCMBIC:
2623 case TIOCMBIS:
2624 return tty_tiocmset(tty, file, cmd, p);
2625 case TCFLSH:
2626 switch (arg) {
2627 case TCIFLUSH:
2628 case TCIOFLUSH:
2629 /* flush tty buffer and allow ldisc to process ioctl */
2630 tty_buffer_flush(tty);
Paul Fulghumc5c34d42007-05-12 10:36:55 -07002631 break;
Alan Cox37bdfb02008-02-08 04:18:47 -08002632 }
2633 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 }
Alan Coxf34d7a52008-04-30 00:54:13 -07002635 if (tty->ops->ioctl) {
2636 retval = (tty->ops->ioctl)(tty, file, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 if (retval != -ENOIOCTLCMD)
2638 return retval;
2639 }
2640 ld = tty_ldisc_ref_wait(tty);
2641 retval = -EINVAL;
Alan Coxa352def2008-07-16 21:53:12 +01002642 if (ld->ops->ioctl) {
2643 retval = ld->ops->ioctl(tty, file, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644 if (retval == -ENOIOCTLCMD)
2645 retval = -EINVAL;
2646 }
2647 tty_ldisc_deref(ld);
2648 return retval;
2649}
2650
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002651#ifdef CONFIG_COMPAT
Alan Cox37bdfb02008-02-08 04:18:47 -08002652static long tty_compat_ioctl(struct file *file, unsigned int cmd,
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002653 unsigned long arg)
2654{
2655 struct inode *inode = file->f_dentry->d_inode;
Nick Piggind996b622010-08-18 04:37:36 +10002656 struct tty_struct *tty = file_tty(file);
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002657 struct tty_ldisc *ld;
2658 int retval = -ENOIOCTLCMD;
2659
2660 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
2661 return -EINVAL;
2662
Alan Coxf34d7a52008-04-30 00:54:13 -07002663 if (tty->ops->compat_ioctl) {
2664 retval = (tty->ops->compat_ioctl)(tty, file, cmd, arg);
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002665 if (retval != -ENOIOCTLCMD)
2666 return retval;
2667 }
2668
2669 ld = tty_ldisc_ref_wait(tty);
Alan Coxa352def2008-07-16 21:53:12 +01002670 if (ld->ops->compat_ioctl)
2671 retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002672 tty_ldisc_deref(ld);
2673
2674 return retval;
2675}
2676#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677
2678/*
2679 * This implements the "Secure Attention Key" --- the idea is to
2680 * prevent trojan horses by killing all processes associated with this
2681 * tty when the user hits the "Secure Attention Key". Required for
2682 * super-paranoid applications --- see the Orange Book for more details.
Alan Cox37bdfb02008-02-08 04:18:47 -08002683 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684 * This code could be nicer; ideally it should send a HUP, wait a few
2685 * seconds, then send a INT, and then a KILL signal. But you then
2686 * have to coordinate with the init process, since all processes associated
2687 * with the current tty must be dead before the new getty is allowed
2688 * to spawn.
2689 *
2690 * Now, if it would be correct ;-/ The current code has a nasty hole -
2691 * it doesn't catch files in flight. We may send the descriptor to ourselves
2692 * via AF_UNIX socket, close it and later fetch from socket. FIXME.
2693 *
2694 * Nasty bug: do_SAK is being called in interrupt context. This can
2695 * deadlock. We punt it up to process context. AKPM - 16Mar2001
2696 */
Eric W. Biederman8b6312f2007-02-10 01:44:34 -08002697void __do_SAK(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698{
2699#ifdef TTY_SOFT_SAK
2700 tty_hangup(tty);
2701#else
Eric W. Biederman652486f2006-03-28 16:11:02 -08002702 struct task_struct *g, *p;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002703 struct pid *session;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 int i;
2705 struct file *filp;
Dipankar Sarmabadf1662005-09-09 13:04:10 -07002706 struct fdtable *fdt;
Alan Cox37bdfb02008-02-08 04:18:47 -08002707
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708 if (!tty)
2709 return;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002710 session = tty->session;
Alan Cox37bdfb02008-02-08 04:18:47 -08002711
Dan Carpenterb3f13de2006-12-13 00:35:09 -08002712 tty_ldisc_flush(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713
Alan Coxf34d7a52008-04-30 00:54:13 -07002714 tty_driver_flush_buffer(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -08002715
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716 read_lock(&tasklist_lock);
Eric W. Biederman652486f2006-03-28 16:11:02 -08002717 /* Kill the entire session */
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002718 do_each_pid_task(session, PIDTYPE_SID, p) {
Eric W. Biederman652486f2006-03-28 16:11:02 -08002719 printk(KERN_NOTICE "SAK: killed process %d"
Oleg Nesterov1b0f7ff2009-04-02 16:58:39 -07002720 " (%s): task_session(p)==tty->session\n",
Pavel Emelyanovba25f9d2007-10-18 23:40:40 -07002721 task_pid_nr(p), p->comm);
Eric W. Biederman652486f2006-03-28 16:11:02 -08002722 send_sig(SIGKILL, p, 1);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002723 } while_each_pid_task(session, PIDTYPE_SID, p);
Eric W. Biederman652486f2006-03-28 16:11:02 -08002724 /* Now kill any processes that happen to have the
2725 * tty open.
2726 */
2727 do_each_thread(g, p) {
2728 if (p->signal->tty == tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729 printk(KERN_NOTICE "SAK: killed process %d"
Oleg Nesterov1b0f7ff2009-04-02 16:58:39 -07002730 " (%s): task_session(p)==tty->session\n",
Pavel Emelyanovba25f9d2007-10-18 23:40:40 -07002731 task_pid_nr(p), p->comm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732 send_sig(SIGKILL, p, 1);
2733 continue;
2734 }
2735 task_lock(p);
2736 if (p->files) {
Dipankar Sarmaca99c1d2006-04-18 22:21:46 -07002737 /*
2738 * We don't take a ref to the file, so we must
2739 * hold ->file_lock instead.
2740 */
2741 spin_lock(&p->files->file_lock);
Dipankar Sarmabadf1662005-09-09 13:04:10 -07002742 fdt = files_fdtable(p->files);
Alan Cox37bdfb02008-02-08 04:18:47 -08002743 for (i = 0; i < fdt->max_fds; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744 filp = fcheck_files(p->files, i);
2745 if (!filp)
2746 continue;
2747 if (filp->f_op->read == tty_read &&
Nick Piggind996b622010-08-18 04:37:36 +10002748 file_tty(filp) == tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749 printk(KERN_NOTICE "SAK: killed process %d"
2750 " (%s): fd#%d opened to the tty\n",
Pavel Emelyanovba25f9d2007-10-18 23:40:40 -07002751 task_pid_nr(p), p->comm, i);
Eric W. Biederman20ac9432006-04-13 04:49:07 -06002752 force_sig(SIGKILL, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002753 break;
2754 }
2755 }
Dipankar Sarmaca99c1d2006-04-18 22:21:46 -07002756 spin_unlock(&p->files->file_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757 }
2758 task_unlock(p);
Eric W. Biederman652486f2006-03-28 16:11:02 -08002759 } while_each_thread(g, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760 read_unlock(&tasklist_lock);
2761#endif
2762}
2763
Eric W. Biederman8b6312f2007-02-10 01:44:34 -08002764static void do_SAK_work(struct work_struct *work)
2765{
2766 struct tty_struct *tty =
2767 container_of(work, struct tty_struct, SAK_work);
2768 __do_SAK(tty);
2769}
2770
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771/*
2772 * The tq handling here is a little racy - tty->SAK_work may already be queued.
2773 * Fortunately we don't need to worry, because if ->SAK_work is already queued,
2774 * the values which we write to it will be identical to the values which it
2775 * already has. --akpm
2776 */
2777void do_SAK(struct tty_struct *tty)
2778{
2779 if (!tty)
2780 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002781 schedule_work(&tty->SAK_work);
2782}
2783
2784EXPORT_SYMBOL(do_SAK);
2785
Alan Coxaf9b8972006-08-27 01:24:01 -07002786/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002787 * initialize_tty_struct
2788 * @tty: tty to initialize
2789 *
2790 * This subroutine initializes a tty structure that has been newly
2791 * allocated.
2792 *
2793 * Locking: none - tty in question must not be exposed at this point
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 */
Alan Coxaf9b8972006-08-27 01:24:01 -07002795
Alan Coxbf970ee2008-10-13 10:42:39 +01002796void initialize_tty_struct(struct tty_struct *tty,
2797 struct tty_driver *driver, int idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798{
2799 memset(tty, 0, sizeof(struct tty_struct));
Alan Cox9c9f4de2008-10-13 10:37:26 +01002800 kref_init(&tty->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801 tty->magic = TTY_MAGIC;
Alan Cox01e1abb2008-07-22 11:16:55 +01002802 tty_ldisc_init(tty);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002803 tty->session = NULL;
2804 tty->pgrp = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805 tty->overrun_time = jiffies;
Alan Cox33f0f882006-01-09 20:54:13 -08002806 tty->buf.head = tty->buf.tail = NULL;
2807 tty_buffer_init(tty);
Arjan van de Ven5785c952006-09-29 02:00:43 -07002808 mutex_init(&tty->termios_mutex);
Alan Coxc65c9bc2009-06-11 12:50:12 +01002809 mutex_init(&tty->ldisc_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002810 init_waitqueue_head(&tty->write_wait);
2811 init_waitqueue_head(&tty->read_wait);
David Howells65f27f32006-11-22 14:55:48 +00002812 INIT_WORK(&tty->hangup_work, do_tty_hangup);
Ingo Molnar70522e12006-03-23 03:00:31 -08002813 mutex_init(&tty->atomic_read_lock);
2814 mutex_init(&tty->atomic_write_lock);
Joe Petersona88a69c2009-01-02 13:40:53 +00002815 mutex_init(&tty->output_lock);
2816 mutex_init(&tty->echo_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 spin_lock_init(&tty->read_lock);
Alan Cox04f378b2008-04-30 00:53:29 -07002818 spin_lock_init(&tty->ctrl_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819 INIT_LIST_HEAD(&tty->tty_files);
Eric W. Biederman7f1f86a2007-02-13 14:38:58 -07002820 INIT_WORK(&tty->SAK_work, do_SAK_work);
Alan Coxbf970ee2008-10-13 10:42:39 +01002821
2822 tty->driver = driver;
2823 tty->ops = driver->ops;
2824 tty->index = idx;
2825 tty_line_name(driver, idx, tty->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826}
2827
Alan Coxf34d7a52008-04-30 00:54:13 -07002828/**
2829 * tty_put_char - write one character to a tty
2830 * @tty: tty
2831 * @ch: character
2832 *
2833 * Write one byte to the tty using the provided put_char method
2834 * if present. Returns the number of characters successfully output.
2835 *
2836 * Note: the specific put_char operation in the driver layer may go
2837 * away soon. Don't call it directly, use this method
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838 */
Alan Coxaf9b8972006-08-27 01:24:01 -07002839
Alan Coxf34d7a52008-04-30 00:54:13 -07002840int tty_put_char(struct tty_struct *tty, unsigned char ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841{
Alan Coxf34d7a52008-04-30 00:54:13 -07002842 if (tty->ops->put_char)
2843 return tty->ops->put_char(tty, ch);
2844 return tty->ops->write(tty, &ch, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845}
Alan Coxf34d7a52008-04-30 00:54:13 -07002846EXPORT_SYMBOL_GPL(tty_put_char);
2847
Alan Coxd81ed102008-10-13 10:41:42 +01002848struct class *tty_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849
2850/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002851 * tty_register_device - register a tty device
2852 * @driver: the tty driver that describes the tty device
2853 * @index: the index in the tty driver for this tty device
2854 * @device: a struct device that is associated with this tty device.
2855 * This field is optional, if there is no known struct device
2856 * for this tty device it can be set to NULL safely.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 *
Greg Kroah-Hartman01107d32006-08-07 22:19:37 -07002858 * Returns a pointer to the struct device for this tty device
2859 * (or ERR_PTR(-EFOO) on error).
Hansjoerg Lipp1cdcb6b2006-04-22 18:36:53 +02002860 *
Alan Coxaf9b8972006-08-27 01:24:01 -07002861 * This call is required to be made to register an individual tty device
2862 * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If
2863 * that bit is not set, this function should not be called by a tty
2864 * driver.
2865 *
2866 * Locking: ??
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 */
Alan Coxaf9b8972006-08-27 01:24:01 -07002868
Greg Kroah-Hartman01107d32006-08-07 22:19:37 -07002869struct device *tty_register_device(struct tty_driver *driver, unsigned index,
2870 struct device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871{
2872 char name[64];
2873 dev_t dev = MKDEV(driver->major, driver->minor_start) + index;
2874
2875 if (index >= driver->num) {
2876 printk(KERN_ERR "Attempt to register invalid tty line number "
2877 " (%d).\n", index);
Hansjoerg Lipp1cdcb6b2006-04-22 18:36:53 +02002878 return ERR_PTR(-EINVAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 }
2880
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881 if (driver->type == TTY_DRIVER_TYPE_PTY)
2882 pty_line_name(driver, index, name);
2883 else
2884 tty_line_name(driver, index, name);
Hansjoerg Lipp1cdcb6b2006-04-22 18:36:53 +02002885
Greg Kroah-Hartman03457cd2008-07-21 20:03:34 -07002886 return device_create(tty_class, device, dev, NULL, name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887}
Alan Cox7d7b93c2008-10-13 10:42:09 +01002888EXPORT_SYMBOL(tty_register_device);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889
2890/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002891 * tty_unregister_device - unregister a tty device
2892 * @driver: the tty driver that describes the tty device
2893 * @index: the index in the tty driver for this tty device
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894 *
Alan Coxaf9b8972006-08-27 01:24:01 -07002895 * If a tty device is registered with a call to tty_register_device() then
2896 * this function must be called when the tty device is gone.
2897 *
2898 * Locking: ??
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 */
Alan Coxaf9b8972006-08-27 01:24:01 -07002900
Linus Torvalds1da177e2005-04-16 15:20:36 -07002901void tty_unregister_device(struct tty_driver *driver, unsigned index)
2902{
Alan Cox37bdfb02008-02-08 04:18:47 -08002903 device_destroy(tty_class,
2904 MKDEV(driver->major, driver->minor_start) + index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906EXPORT_SYMBOL(tty_unregister_device);
2907
2908struct tty_driver *alloc_tty_driver(int lines)
2909{
2910 struct tty_driver *driver;
2911
Jean Delvare506eb992007-07-15 23:40:14 -07002912 driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913 if (driver) {
Alan Cox7d7b93c2008-10-13 10:42:09 +01002914 kref_init(&driver->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915 driver->magic = TTY_DRIVER_MAGIC;
2916 driver->num = lines;
2917 /* later we'll move allocation of tables here */
2918 }
2919 return driver;
2920}
Alan Cox7d7b93c2008-10-13 10:42:09 +01002921EXPORT_SYMBOL(alloc_tty_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922
Alan Cox7d7b93c2008-10-13 10:42:09 +01002923static void destruct_tty_driver(struct kref *kref)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924{
Alan Cox7d7b93c2008-10-13 10:42:09 +01002925 struct tty_driver *driver = container_of(kref, struct tty_driver, kref);
2926 int i;
2927 struct ktermios *tp;
2928 void *p;
2929
2930 if (driver->flags & TTY_DRIVER_INSTALLED) {
2931 /*
2932 * Free the termios and termios_locked structures because
2933 * we don't want to get memory leaks when modular tty
2934 * drivers are removed from the kernel.
2935 */
2936 for (i = 0; i < driver->num; i++) {
2937 tp = driver->termios[i];
2938 if (tp) {
2939 driver->termios[i] = NULL;
2940 kfree(tp);
2941 }
Alan Cox7d7b93c2008-10-13 10:42:09 +01002942 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
2943 tty_unregister_device(driver, i);
2944 }
2945 p = driver->ttys;
2946 proc_tty_unregister_driver(driver);
2947 driver->ttys = NULL;
Alan Coxfe6e29f2008-10-13 10:44:08 +01002948 driver->termios = NULL;
Alan Cox7d7b93c2008-10-13 10:42:09 +01002949 kfree(p);
2950 cdev_del(&driver->cdev);
2951 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952 kfree(driver);
2953}
2954
Alan Cox7d7b93c2008-10-13 10:42:09 +01002955void tty_driver_kref_put(struct tty_driver *driver)
2956{
2957 kref_put(&driver->kref, destruct_tty_driver);
2958}
2959EXPORT_SYMBOL(tty_driver_kref_put);
2960
Jeff Dikeb68e31d2006-10-02 02:17:18 -07002961void tty_set_operations(struct tty_driver *driver,
2962 const struct tty_operations *op)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963{
Alan Coxf34d7a52008-04-30 00:54:13 -07002964 driver->ops = op;
2965};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966EXPORT_SYMBOL(tty_set_operations);
2967
Alan Cox7d7b93c2008-10-13 10:42:09 +01002968void put_tty_driver(struct tty_driver *d)
2969{
2970 tty_driver_kref_put(d);
2971}
2972EXPORT_SYMBOL(put_tty_driver);
2973
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974/*
2975 * Called by a tty driver to register itself.
2976 */
2977int tty_register_driver(struct tty_driver *driver)
2978{
2979 int error;
Alan Cox37bdfb02008-02-08 04:18:47 -08002980 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 dev_t dev;
2982 void **p = NULL;
2983
Andy Whitcroft543691a62007-05-06 14:49:33 -07002984 if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
Alan Coxfe6e29f2008-10-13 10:44:08 +01002985 p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986 if (!p)
2987 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988 }
2989
2990 if (!driver->major) {
Alan Cox37bdfb02008-02-08 04:18:47 -08002991 error = alloc_chrdev_region(&dev, driver->minor_start,
2992 driver->num, driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993 if (!error) {
2994 driver->major = MAJOR(dev);
2995 driver->minor_start = MINOR(dev);
2996 }
2997 } else {
2998 dev = MKDEV(driver->major, driver->minor_start);
Geert Uytterhoevene5717c42007-02-20 15:45:21 +01002999 error = register_chrdev_region(dev, driver->num, driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 }
3001 if (error < 0) {
3002 kfree(p);
3003 return error;
3004 }
3005
3006 if (p) {
3007 driver->ttys = (struct tty_struct **)p;
Alan Coxedc6afc2006-12-08 02:38:44 -08003008 driver->termios = (struct ktermios **)(p + driver->num);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009 } else {
3010 driver->ttys = NULL;
3011 driver->termios = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012 }
3013
3014 cdev_init(&driver->cdev, &tty_fops);
3015 driver->cdev.owner = driver->owner;
3016 error = cdev_add(&driver->cdev, dev, driver->num);
3017 if (error) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018 unregister_chrdev_region(dev, driver->num);
3019 driver->ttys = NULL;
Alan Coxfe6e29f2008-10-13 10:44:08 +01003020 driver->termios = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003021 kfree(p);
3022 return error;
3023 }
3024
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003025 mutex_lock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026 list_add(&driver->tty_drivers, &tty_drivers);
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003027 mutex_unlock(&tty_mutex);
Alan Cox37bdfb02008-02-08 04:18:47 -08003028
3029 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
3030 for (i = 0; i < driver->num; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003031 tty_register_device(driver, i, NULL);
3032 }
3033 proc_tty_register_driver(driver);
Alan Cox7d7b93c2008-10-13 10:42:09 +01003034 driver->flags |= TTY_DRIVER_INSTALLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003035 return 0;
3036}
3037
3038EXPORT_SYMBOL(tty_register_driver);
3039
3040/*
3041 * Called by a tty driver to unregister itself.
3042 */
3043int tty_unregister_driver(struct tty_driver *driver)
3044{
Alan Cox7d7b93c2008-10-13 10:42:09 +01003045#if 0
3046 /* FIXME */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047 if (driver->refcount)
3048 return -EBUSY;
Alan Cox7d7b93c2008-10-13 10:42:09 +01003049#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003050 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
3051 driver->num);
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003052 mutex_lock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003053 list_del(&driver->tty_drivers);
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003054 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 return 0;
3056}
Alan Cox7d7b93c2008-10-13 10:42:09 +01003057
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058EXPORT_SYMBOL(tty_unregister_driver);
3059
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003060dev_t tty_devnum(struct tty_struct *tty)
3061{
3062 return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
3063}
3064EXPORT_SYMBOL(tty_devnum);
3065
3066void proc_clear_tty(struct task_struct *p)
3067{
Arjan van de Ven7c3b1dc2008-10-15 10:52:34 +01003068 unsigned long flags;
Alan Cox9c9f4de2008-10-13 10:37:26 +01003069 struct tty_struct *tty;
Arjan van de Ven7c3b1dc2008-10-15 10:52:34 +01003070 spin_lock_irqsave(&p->sighand->siglock, flags);
Alan Cox9c9f4de2008-10-13 10:37:26 +01003071 tty = p->signal->tty;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003072 p->signal->tty = NULL;
Arjan van de Ven7c3b1dc2008-10-15 10:52:34 +01003073 spin_unlock_irqrestore(&p->sighand->siglock, flags);
Alan Cox9c9f4de2008-10-13 10:37:26 +01003074 tty_kref_put(tty);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003075}
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003076
Alan Cox47f86832008-04-30 00:53:30 -07003077/* Called under the sighand lock */
3078
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -07003079static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003080{
3081 if (tty) {
Alan Cox47f86832008-04-30 00:53:30 -07003082 unsigned long flags;
3083 /* We should not have a session or pgrp to put here but.... */
3084 spin_lock_irqsave(&tty->ctrl_lock, flags);
Eric W. Biedermand9c1e9a2007-03-18 12:45:44 -06003085 put_pid(tty->session);
3086 put_pid(tty->pgrp);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08003087 tty->pgrp = get_pid(task_pgrp(tsk));
Alan Cox47f86832008-04-30 00:53:30 -07003088 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
3089 tty->session = get_pid(task_session(tsk));
Alan Cox9c9f4de2008-10-13 10:37:26 +01003090 if (tsk->signal->tty) {
3091 printk(KERN_DEBUG "tty not NULL!!\n");
3092 tty_kref_put(tsk->signal->tty);
3093 }
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003094 }
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -07003095 put_pid(tsk->signal->tty_old_pgrp);
Alan Cox9c9f4de2008-10-13 10:37:26 +01003096 tsk->signal->tty = tty_kref_get(tty);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08003097 tsk->signal->tty_old_pgrp = NULL;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003098}
3099
Eric W. Biederman98a27ba2007-05-08 00:26:56 -07003100static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003101{
3102 spin_lock_irq(&tsk->sighand->siglock);
Eric W. Biederman2a65f1d2007-05-08 00:26:53 -07003103 __proc_set_tty(tsk, tty);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003104 spin_unlock_irq(&tsk->sighand->siglock);
3105}
3106
3107struct tty_struct *get_current_tty(void)
3108{
3109 struct tty_struct *tty;
Alan Cox934e6eb2008-10-13 10:40:43 +01003110 unsigned long flags;
3111
3112 spin_lock_irqsave(&current->sighand->siglock, flags);
Alan Cox452a00d2008-10-13 10:39:13 +01003113 tty = tty_kref_get(current->signal->tty);
Alan Cox934e6eb2008-10-13 10:40:43 +01003114 spin_unlock_irqrestore(&current->sighand->siglock, flags);
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003115 return tty;
3116}
Heiko Carstensa311f742006-12-13 00:33:41 -08003117EXPORT_SYMBOL_GPL(get_current_tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118
Alan Coxd81ed102008-10-13 10:41:42 +01003119void tty_default_fops(struct file_operations *fops)
3120{
3121 *fops = tty_fops;
3122}
3123
Linus Torvalds1da177e2005-04-16 15:20:36 -07003124/*
3125 * Initialize the console device. This is called *early*, so
3126 * we can't necessarily depend on lots of kernel help here.
3127 * Just do some early initializations, and do the complex setup
3128 * later.
3129 */
3130void __init console_init(void)
3131{
3132 initcall_t *call;
3133
3134 /* Setup the default TTY line discipline. */
Alan Cox01e1abb2008-07-22 11:16:55 +01003135 tty_ldisc_begin();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136
3137 /*
Alan Cox37bdfb02008-02-08 04:18:47 -08003138 * set up the console device so that later boot sequences can
Linus Torvalds1da177e2005-04-16 15:20:36 -07003139 * inform about problems etc..
3140 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 call = __con_initcall_start;
3142 while (call < __con_initcall_end) {
3143 (*call)();
3144 call++;
3145 }
3146}
3147
Kay Sieverse454cea2009-09-18 23:01:12 +02003148static char *tty_devnode(struct device *dev, mode_t *mode)
3149{
3150 if (!mode)
3151 return NULL;
3152 if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
3153 dev->devt == MKDEV(TTYAUX_MAJOR, 2))
3154 *mode = 0666;
3155 return NULL;
3156}
3157
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158static int __init tty_class_init(void)
3159{
gregkh@suse.de7fe845d2005-03-15 14:23:15 -08003160 tty_class = class_create(THIS_MODULE, "tty");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 if (IS_ERR(tty_class))
3162 return PTR_ERR(tty_class);
Kay Sieverse454cea2009-09-18 23:01:12 +02003163 tty_class->devnode = tty_devnode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164 return 0;
3165}
3166
3167postcore_initcall(tty_class_init);
3168
3169/* 3/2004 jmc: why do these devices exist? */
3170
3171static struct cdev tty_cdev, console_cdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172
3173/*
3174 * Ok, now we can initialize the rest of the tty devices and can count
3175 * on memory allocations, interrupts etc..
3176 */
David Howells31d1d482010-08-06 16:34:43 +01003177int __init tty_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178{
3179 cdev_init(&tty_cdev, &tty_fops);
3180 if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
3181 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
3182 panic("Couldn't register /dev/tty driver\n");
Alan Coxd81ed102008-10-13 10:41:42 +01003183 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
Greg Kroah-Hartman47aa5792008-05-21 12:52:33 -07003184 "tty");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003185
3186 cdev_init(&console_cdev, &console_fops);
3187 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
3188 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
3189 panic("Couldn't register /dev/console driver\n");
Alan Coxd81ed102008-10-13 10:41:42 +01003190 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
Greg Kroah-Hartman47aa5792008-05-21 12:52:33 -07003191 "console");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193#ifdef CONFIG_VT
Alan Coxd81ed102008-10-13 10:41:42 +01003194 vty_init(&console_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195#endif
3196 return 0;
3197}
David Howells31d1d482010-08-06 16:34:43 +01003198