tty_io.c 77.7 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 *  linux/drivers/char/tty_io.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

/*
 * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
 * or rs-channels. It also implements echoing, cooked mode etc.
 *
 * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
 *
 * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the
 * tty_struct and tty_queue structures.  Previously there was an array
 * of 256 tty_struct's which was statically allocated, and the
 * tty_queue structures were allocated at boot time.  Both are now
 * dynamically allocated only when the tty is open.
 *
 * Also restructured routines so that there is more of a separation
 * between the high-level tty routines (tty_io.c and tty_ioctl.c) and
 * the low-level tty routines (serial.c, pty.c, console.c).  This
22
 * makes for cleaner and more compact code.  -TYT, 9/17/92
Linus Torvalds's avatar
Linus Torvalds committed
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 *
 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
 * which can be dynamically activated and de-activated by the line
 * discipline handling modules (like SLIP).
 *
 * NOTE: pay no attention to the line discipline code (yet); its
 * interface is still subject to change in this version...
 * -- TYT, 1/31/92
 *
 * Added functionality to the OPOST tty handling.  No delays, but all
 * other bits should be there.
 *	-- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993.
 *
 * Rewrote canonical mode and added more termios flags.
 * 	-- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94
 *
 * Reorganized FASYNC support so mouse code can share it.
 *	-- ctm@ardi.com, 9Sep95
 *
 * New TIOCLINUX variants added.
 *	-- mj@k332.feld.cvut.cz, 19-Nov-95
44
 *
Linus Torvalds's avatar
Linus Torvalds committed
45
46
47
48
49
50
51
 * Restrict vt switching via ioctl()
 *      -- grif@cs.ucr.edu, 5-Dec-95
 *
 * Move console and virtual terminal code to more appropriate files,
 * implement CONFIG_VT and generalize console device interface.
 *	-- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97
 *
52
 * Rewrote tty_init_dev and tty_release_dev to eliminate races.
Linus Torvalds's avatar
Linus Torvalds committed
53
54
55
56
57
58
59
60
61
62
63
64
 *	-- Bill Hawes <whawes@star.net>, June 97
 *
 * Added devfs support.
 *      -- C. Scott Ananian <cananian@alumni.princeton.edu>, 13-Jan-1998
 *
 * Added support for a Unix98-style ptmx device.
 *      -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
 *
 * Reduced memory usage for older ARM systems
 *      -- Russell King <rmk@arm.linux.org.uk>
 *
 * Move do_SAK() into process context.  Less stack use in devfs functions.
65
66
 * alloc_tty_struct() always uses kmalloc()
 *			 -- Andrew Morton <andrewm@uow.edu.eu> 17Mar01
Linus Torvalds's avatar
Linus Torvalds committed
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 */

#include <linux/types.h>
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/devpts_fs.h>
#include <linux/file.h>
Al Viro's avatar
Al Viro committed
81
#include <linux/fdtable.h>
Linus Torvalds's avatar
Linus Torvalds committed
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <linux/console.h>
#include <linux/timer.h>
#include <linux/ctype.h>
#include <linux/kd.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/smp_lock.h>
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/bitops.h>
97
#include <linux/delay.h>
Alan Cox's avatar
Alan Cox committed
98
#include <linux/seq_file.h>
Linus Torvalds's avatar
Linus Torvalds committed
99

Alan Cox's avatar
Alan Cox committed
100
#include <linux/uaccess.h>
Linus Torvalds's avatar
Linus Torvalds committed
101
102
103
104
105
106
107
#include <asm/system.h>

#include <linux/kbd_kern.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>

#include <linux/kmod.h>
108
#include <linux/nsproxy.h>
Linus Torvalds's avatar
Linus Torvalds committed
109
110
111
112
113
114

#undef TTY_DEBUG_HANGUP

#define TTY_PARANOIA_CHECK 1
#define CHECK_TTY_COUNT 1

115
struct ktermios tty_std_termios = {	/* for the benefit of tty drivers  */
Linus Torvalds's avatar
Linus Torvalds committed
116
117
118
119
120
	.c_iflag = ICRNL | IXON,
	.c_oflag = OPOST | ONLCR,
	.c_cflag = B38400 | CS8 | CREAD | HUPCL,
	.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
		   ECHOCTL | ECHOKE | IEXTEN,
121
122
123
	.c_cc = INIT_C_CC,
	.c_ispeed = 38400,
	.c_ospeed = 38400
Linus Torvalds's avatar
Linus Torvalds committed
124
125
126
127
128
129
130
};

EXPORT_SYMBOL(tty_std_termios);

/* This list gets poked at by procfs and various bits of boot up code. This
   could do with some rationalisation such as pulling the tty proc function
   into this file */
131

Linus Torvalds's avatar
Linus Torvalds committed
132
133
LIST_HEAD(tty_drivers);			/* linked list of tty drivers */

134
/* Mutex to protect creating and releasing a tty. This is shared with
Linus Torvalds's avatar
Linus Torvalds committed
135
   vt.c for deeply disgusting hack reasons */
Ingo Molnar's avatar
Ingo Molnar committed
136
DEFINE_MUTEX(tty_mutex);
137
EXPORT_SYMBOL(tty_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
138
139
140

static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *);
141
142
ssize_t redirected_tty_write(struct file *, const char __user *,
							size_t, loff_t *);
Linus Torvalds's avatar
Linus Torvalds committed
143
144
static unsigned int tty_poll(struct file *, poll_table *);
static int tty_open(struct inode *, struct file *);
Alan Cox's avatar
Alan Cox committed
145
long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
Paul Fulghum's avatar
Paul Fulghum committed
146
#ifdef CONFIG_COMPAT
147
static long tty_compat_ioctl(struct file *file, unsigned int cmd,
Paul Fulghum's avatar
Paul Fulghum committed
148
149
150
151
				unsigned long arg);
#else
#define tty_compat_ioctl NULL
#endif
152
static int tty_fasync(int fd, struct file *filp, int on);
153
static void release_tty(struct tty_struct *tty, int idx);
154
static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
155
static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
Linus Torvalds's avatar
Linus Torvalds committed
156

157
158
159
160
161
162
163
164
/**
 *	alloc_tty_struct	-	allocate a tty object
 *
 *	Return a new empty tty structure. The data fields have not
 *	been initialized in any way but has been zeroed
 *
 *	Locking: none
 */
Linus Torvalds's avatar
Linus Torvalds committed
165

166
struct tty_struct *alloc_tty_struct(void)
Linus Torvalds's avatar
Linus Torvalds committed
167
{
168
	return kzalloc(sizeof(struct tty_struct), GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
169
170
}

171
172
173
174
175
176
177
178
179
/**
 *	free_tty_struct		-	free a disused tty
 *	@tty: tty struct to free
 *
 *	Free the write buffers, tty queue and tty memory itself.
 *
 *	Locking: none. Must be called after tty is definitely unused
 */

180
void free_tty_struct(struct tty_struct *tty)
Linus Torvalds's avatar
Linus Torvalds committed
181
182
{
	kfree(tty->write_buf);
Alan Cox's avatar
Alan Cox committed
183
	tty_buffer_free_all(tty);
Linus Torvalds's avatar
Linus Torvalds committed
184
185
186
187
188
	kfree(tty);
}

#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)

189
190
191
192
193
194
195
196
197
198
199
/**
 *	tty_name	-	return tty naming
 *	@tty: tty structure
 *	@buf: buffer for output
 *
 *	Convert a tty structure into a name. The name reflects the kernel
 *	naming policy and if udev is in use may not reflect user space
 *
 *	Locking: none
 */

Linus Torvalds's avatar
Linus Torvalds committed
200
201
202
203
204
205
206
207
208
209
210
char *tty_name(struct tty_struct *tty, char *buf)
{
	if (!tty) /* Hmm.  NULL pointer.  That's fun. */
		strcpy(buf, "NULL tty");
	else
		strcpy(buf, tty->name);
	return buf;
}

EXPORT_SYMBOL(tty_name);

211
int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
Linus Torvalds's avatar
Linus Torvalds committed
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
			      const char *routine)
{
#ifdef TTY_PARANOIA_CHECK
	if (!tty) {
		printk(KERN_WARNING
			"null TTY for (%d:%d) in %s\n",
			imajor(inode), iminor(inode), routine);
		return 1;
	}
	if (tty->magic != TTY_MAGIC) {
		printk(KERN_WARNING
			"bad magic number for tty struct (%d:%d) in %s\n",
			imajor(inode), iminor(inode), routine);
		return 1;
	}
#endif
	return 0;
}

static int check_tty_count(struct tty_struct *tty, const char *routine)
{
#ifdef CHECK_TTY_COUNT
	struct list_head *p;
	int count = 0;
236

Linus Torvalds's avatar
Linus Torvalds committed
237
238
239
240
241
242
243
244
245
246
247
248
249
250
	file_list_lock();
	list_for_each(p, &tty->tty_files) {
		count++;
	}
	file_list_unlock();
	if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
	    tty->driver->subtype == PTY_TYPE_SLAVE &&
	    tty->link && tty->link->count)
		count++;
	if (tty->count != count) {
		printk(KERN_WARNING "Warning: dev (%s) tty->count(%d) "
				    "!= #fd's(%d) in %s\n",
		       tty->name, tty->count, count, routine);
		return count;
251
	}
Linus Torvalds's avatar
Linus Torvalds committed
252
253
254
255
#endif
	return 0;
}

256
257
258
259
260
261
262
263
264
/**
 *	get_tty_driver		-	find device of a tty
 *	@dev_t: device identifier
 *	@index: returns the index of the tty
 *
 *	This routine returns a tty driver structure, given a device number
 *	and also passes back the index number.
 *
 *	Locking: caller must hold tty_mutex
Linus Torvalds's avatar
Linus Torvalds committed
265
 */
266

Linus Torvalds's avatar
Linus Torvalds committed
267
268
269
270
271
272
273
274
275
static struct tty_driver *get_tty_driver(dev_t device, int *index)
{
	struct tty_driver *p;

	list_for_each_entry(p, &tty_drivers, tty_drivers) {
		dev_t base = MKDEV(p->major, p->minor_start);
		if (device < base || device >= base + p->num)
			continue;
		*index = device - base;
Alan Cox's avatar
Alan Cox committed
276
		return tty_driver_kref_get(p);
Linus Torvalds's avatar
Linus Torvalds committed
277
278
279
280
	}
	return NULL;
}

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#ifdef CONFIG_CONSOLE_POLL

/**
 *	tty_find_polling_driver	-	find device of a polled tty
 *	@name: name string to match
 *	@line: pointer to resulting tty line nr
 *
 *	This routine returns a tty driver structure, given a name
 *	and the condition that the tty driver is capable of polled
 *	operation.
 */
struct tty_driver *tty_find_polling_driver(char *name, int *line)
{
	struct tty_driver *p, *res = NULL;
	int tty_line = 0;
296
	int len;
297
	char *str, *stp;
298

299
300
301
302
303
304
305
306
307
	for (str = name; *str; str++)
		if ((*str >= '0' && *str <= '9') || *str == ',')
			break;
	if (!*str)
		return NULL;

	len = str - name;
	tty_line = simple_strtoul(str, &str, 10);

308
309
310
	mutex_lock(&tty_mutex);
	/* Search through the tty devices to look for a match */
	list_for_each_entry(p, &tty_drivers, tty_drivers) {
311
312
		if (strncmp(name, p->name, len) != 0)
			continue;
313
314
315
316
317
		stp = str;
		if (*stp == ',')
			stp++;
		if (*stp == '\0')
			stp = NULL;
318

Alan Cox's avatar
Alan Cox committed
319
		if (tty_line >= 0 && tty_line <= p->num && p->ops &&
320
		    p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
Alan Cox's avatar
Alan Cox committed
321
			res = tty_driver_kref_get(p);
322
323
324
325
326
327
328
329
330
331
332
			*line = tty_line;
			break;
		}
	}
	mutex_unlock(&tty_mutex);

	return res;
}
EXPORT_SYMBOL_GPL(tty_find_polling_driver);
#endif

333
334
335
336
337
338
339
340
/**
 *	tty_check_change	-	check for POSIX terminal changes
 *	@tty: tty to check
 *
 *	If we try to write to, or set the state of, a terminal and we're
 *	not in the foreground, send a SIGTTOU.  If the signal is blocked or
 *	ignored, go ahead and perform the operation.  (POSIX 7.2)
 *
341
 *	Locking: ctrl_lock
Linus Torvalds's avatar
Linus Torvalds committed
342
 */
343

344
int tty_check_change(struct tty_struct *tty)
Linus Torvalds's avatar
Linus Torvalds committed
345
{
Alan Cox's avatar
Alan Cox committed
346
347
348
	unsigned long flags;
	int ret = 0;

Linus Torvalds's avatar
Linus Torvalds committed
349
350
	if (current->signal->tty != tty)
		return 0;
Alan Cox's avatar
Alan Cox committed
351
352
353

	spin_lock_irqsave(&tty->ctrl_lock, flags);

354
355
	if (!tty->pgrp) {
		printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
356
		goto out_unlock;
Linus Torvalds's avatar
Linus Torvalds committed
357
	}
358
	if (task_pgrp(current) == tty->pgrp)
359
360
		goto out_unlock;
	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
361
	if (is_ignored(SIGTTOU))
Alan Cox's avatar
Alan Cox committed
362
363
364
365
366
		goto out;
	if (is_current_pgrp_orphaned()) {
		ret = -EIO;
		goto out;
	}
367
368
	kill_pgrp(task_pgrp(current), SIGTTOU, 1);
	set_thread_flag(TIF_SIGPENDING);
Alan Cox's avatar
Alan Cox committed
369
370
	ret = -ERESTARTSYS;
out:
371
372
	return ret;
out_unlock:
Alan Cox's avatar
Alan Cox committed
373
374
	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
	return ret;
Linus Torvalds's avatar
Linus Torvalds committed
375
376
377
378
}

EXPORT_SYMBOL(tty_check_change);

379
static ssize_t hung_up_tty_read(struct file *file, char __user *buf,
Linus Torvalds's avatar
Linus Torvalds committed
380
381
382
383
384
				size_t count, loff_t *ppos)
{
	return 0;
}

385
static ssize_t hung_up_tty_write(struct file *file, const char __user *buf,
Linus Torvalds's avatar
Linus Torvalds committed
386
387
388
389
390
391
				 size_t count, loff_t *ppos)
{
	return -EIO;
}

/* No kernel lock held - none needed ;) */
392
static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait)
Linus Torvalds's avatar
Linus Torvalds committed
393
394
395
396
{
	return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
}

Alan Cox's avatar
Alan Cox committed
397
398
static long hung_up_tty_ioctl(struct file *file, unsigned int cmd,
		unsigned long arg)
399
400
401
402
{
	return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
}

403
static long hung_up_tty_compat_ioctl(struct file *file,
404
				     unsigned int cmd, unsigned long arg)
Linus Torvalds's avatar
Linus Torvalds committed
405
406
407
408
{
	return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
}

409
static const struct file_operations tty_fops = {
Linus Torvalds's avatar
Linus Torvalds committed
410
411
412
413
	.llseek		= no_llseek,
	.read		= tty_read,
	.write		= tty_write,
	.poll		= tty_poll,
Alan Cox's avatar
Alan Cox committed
414
	.unlocked_ioctl	= tty_ioctl,
Paul Fulghum's avatar
Paul Fulghum committed
415
	.compat_ioctl	= tty_compat_ioctl,
Linus Torvalds's avatar
Linus Torvalds committed
416
417
418
419
420
	.open		= tty_open,
	.release	= tty_release,
	.fasync		= tty_fasync,
};

421
static const struct file_operations console_fops = {
Linus Torvalds's avatar
Linus Torvalds committed
422
423
424
425
	.llseek		= no_llseek,
	.read		= tty_read,
	.write		= redirected_tty_write,
	.poll		= tty_poll,
Alan Cox's avatar
Alan Cox committed
426
	.unlocked_ioctl	= tty_ioctl,
Paul Fulghum's avatar
Paul Fulghum committed
427
	.compat_ioctl	= tty_compat_ioctl,
Linus Torvalds's avatar
Linus Torvalds committed
428
429
430
431
432
	.open		= tty_open,
	.release	= tty_release,
	.fasync		= tty_fasync,
};

433
static const struct file_operations hung_up_tty_fops = {
Linus Torvalds's avatar
Linus Torvalds committed
434
435
436
437
	.llseek		= no_llseek,
	.read		= hung_up_tty_read,
	.write		= hung_up_tty_write,
	.poll		= hung_up_tty_poll,
Alan Cox's avatar
Alan Cox committed
438
	.unlocked_ioctl	= hung_up_tty_ioctl,
439
	.compat_ioctl	= hung_up_tty_compat_ioctl,
Linus Torvalds's avatar
Linus Torvalds committed
440
441
442
443
444
445
446
447
448
449
450
451
452
453
	.release	= tty_release,
};

static DEFINE_SPINLOCK(redirect_lock);
static struct file *redirect;

/**
 *	tty_wakeup	-	request more data
 *	@tty: terminal
 *
 *	Internal and external helper for wakeups of tty. This function
 *	informs the line discipline if present that the driver is ready
 *	to receive more output data.
 */
454

Linus Torvalds's avatar
Linus Torvalds committed
455
456
457
void tty_wakeup(struct tty_struct *tty)
{
	struct tty_ldisc *ld;
458

Linus Torvalds's avatar
Linus Torvalds committed
459
460
	if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
		ld = tty_ldisc_ref(tty);
461
		if (ld) {
Alan Cox's avatar
Alan Cox committed
462
463
			if (ld->ops->write_wakeup)
				ld->ops->write_wakeup(tty);
Linus Torvalds's avatar
Linus Torvalds committed
464
465
466
			tty_ldisc_deref(ld);
		}
	}
467
	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
Linus Torvalds's avatar
Linus Torvalds committed
468
469
470
471
}

EXPORT_SYMBOL_GPL(tty_wakeup);

472
473
/**
 *	do_tty_hangup		-	actual handler for hangup events
474
 *	@work: tty device
475
 *
Alan Cox's avatar
Alan Cox committed
476
 *	This can be called by the "eventd" kernel thread.  That is process
477
478
479
480
481
482
483
484
485
486
 *	synchronous but doesn't hold any locks, so we need to make sure we
 *	have the appropriate locks for what we're doing.
 *
 *	The hangup event clears any pending redirections onto the hung up
 *	device. It ensures future writes will error and it does the needed
 *	line discipline hangup and signal delivery. The tty object itself
 *	remains intact.
 *
 *	Locking:
 *		BKL
487
488
489
490
491
492
 *		  redirect lock for undoing redirection
 *		  file list lock for manipulating list of ttys
 *		  tty_ldisc_lock from called functions
 *		  termios_mutex resetting termios data
 *		  tasklist_lock to walk task list for hangup event
 *		    ->siglock to protect ->signal/->sighand
Linus Torvalds's avatar
Linus Torvalds committed
493
 */
494
static void do_tty_hangup(struct work_struct *work)
Linus Torvalds's avatar
Linus Torvalds committed
495
{
496
497
	struct tty_struct *tty =
		container_of(work, struct tty_struct, hangup_work);
498
	struct file *cons_filp = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
499
500
501
	struct file *filp, *f = NULL;
	struct task_struct *p;
	int    closecount = 0, n;
Alan Cox's avatar
Alan Cox committed
502
	unsigned long flags;
Alan Cox's avatar
Alan Cox committed
503
	int refs = 0;
Linus Torvalds's avatar
Linus Torvalds committed
504
505
506
507
508
509
510
511
512
513
514

	if (!tty)
		return;


	spin_lock(&redirect_lock);
	if (redirect && redirect->private_data == tty) {
		f = redirect;
		redirect = NULL;
	}
	spin_unlock(&redirect_lock);
515

516
517
	/* inuse_filps is protected by the single kernel lock */
	lock_kernel();
Linus Torvalds's avatar
Linus Torvalds committed
518
519
520
	check_tty_count(tty, "do_tty_hangup");
	file_list_lock();
	/* This breaks for file handles being sent over AF_UNIX sockets ? */
521
	list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) {
Linus Torvalds's avatar
Linus Torvalds committed
522
523
524
525
526
527
528
529
530
		if (filp->f_op->write == redirected_tty_write)
			cons_filp = filp;
		if (filp->f_op->write != tty_write)
			continue;
		closecount++;
		tty_fasync(-1, filp, 0);	/* can't block */
		filp->f_op = &hung_up_tty_fops;
	}
	file_list_unlock();
531

Alan Cox's avatar
Alan Cox committed
532
	tty_ldisc_hangup(tty);
533

Linus Torvalds's avatar
Linus Torvalds committed
534
	read_lock(&tasklist_lock);
535
536
	if (tty->session) {
		do_each_pid_task(tty->session, PIDTYPE_SID, p) {
537
			spin_lock_irq(&p->sighand->siglock);
Alan Cox's avatar
Alan Cox committed
538
			if (p->signal->tty == tty) {
Linus Torvalds's avatar
Linus Torvalds committed
539
				p->signal->tty = NULL;
Alan Cox's avatar
Alan Cox committed
540
541
542
543
				/* We defer the dereferences outside fo
				   the tasklist lock */
				refs++;
			}
544
545
			if (!p->signal->leader) {
				spin_unlock_irq(&p->sighand->siglock);
Linus Torvalds's avatar
Linus Torvalds committed
546
				continue;
547
548
549
			}
			__group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
			__group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
550
			put_pid(p->signal->tty_old_pgrp);  /* A noop */
Alan Cox's avatar
Alan Cox committed
551
			spin_lock_irqsave(&tty->ctrl_lock, flags);
552
553
			if (tty->pgrp)
				p->signal->tty_old_pgrp = get_pid(tty->pgrp);
Alan Cox's avatar
Alan Cox committed
554
			spin_unlock_irqrestore(&tty->ctrl_lock, flags);
555
			spin_unlock_irq(&p->sighand->siglock);
556
		} while_each_pid_task(tty->session, PIDTYPE_SID, p);
Linus Torvalds's avatar
Linus Torvalds committed
557
558
559
	}
	read_unlock(&tasklist_lock);

Alan Cox's avatar
Alan Cox committed
560
	spin_lock_irqsave(&tty->ctrl_lock, flags);
Alan Cox's avatar
Alan Cox committed
561
562
563
	clear_bit(TTY_THROTTLED, &tty->flags);
	clear_bit(TTY_PUSH, &tty->flags);
	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
564
565
	put_pid(tty->session);
	put_pid(tty->pgrp);
566
567
	tty->session = NULL;
	tty->pgrp = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
568
	tty->ctrl_status = 0;
Alan Cox's avatar
Alan Cox committed
569
	set_bit(TTY_HUPPED, &tty->flags);
Alan Cox's avatar
Alan Cox committed
570
571
	spin_unlock_irqrestore(&tty->ctrl_lock, flags);

Alan Cox's avatar
Alan Cox committed
572
573
574
575
	/* Account for the p->signal references we killed */
	while (refs--)
		tty_kref_put(tty);

Linus Torvalds's avatar
Linus Torvalds committed
576
	/*
577
578
579
580
	 * If one of the devices matches a console pointer, we
	 * cannot just call hangup() because that will cause
	 * tty->count and state->count to go out of sync.
	 * So we just call close() the right number of times.
Linus Torvalds's avatar
Linus Torvalds committed
581
582
	 */
	if (cons_filp) {
Alan Cox's avatar
Alan Cox committed
583
		if (tty->ops->close)
Linus Torvalds's avatar
Linus Torvalds committed
584
			for (n = 0; n < closecount; n++)
Alan Cox's avatar
Alan Cox committed
585
586
587
				tty->ops->close(tty, cons_filp);
	} else if (tty->ops->hangup)
		(tty->ops->hangup)(tty);
588
589
590
591
592
593
	/*
	 * We don't want to have driver/ldisc interactions beyond
	 * the ones we did here. The driver layer expects no
	 * calls after ->hangup() from the ldisc side. However we
	 * can't yet guarantee all that.
	 */
Linus Torvalds's avatar
Linus Torvalds committed
594
	set_bit(TTY_HUPPED, &tty->flags);
Alan Cox's avatar
Alan Cox committed
595
	tty_ldisc_enable(tty);
Linus Torvalds's avatar
Linus Torvalds committed
596
597
598
599
600
	unlock_kernel();
	if (f)
		fput(f);
}

601
602
603
604
605
606
607
608
/**
 *	tty_hangup		-	trigger a hangup event
 *	@tty: tty to hangup
 *
 *	A carrier loss (virtual or otherwise) has occurred on this like
 *	schedule a hangup sequence to run after this event.
 */

609
void tty_hangup(struct tty_struct *tty)
Linus Torvalds's avatar
Linus Torvalds committed
610
611
612
613
614
615
616
617
618
619
{
#ifdef TTY_DEBUG_HANGUP
	char	buf[64];
	printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf));
#endif
	schedule_work(&tty->hangup_work);
}

EXPORT_SYMBOL(tty_hangup);

620
621
622
623
624
625
/**
 *	tty_vhangup		-	process vhangup
 *	@tty: tty to hangup
 *
 *	The user has asked via system call for the terminal to be hung up.
 *	We do this synchronously so that when the syscall returns the process
626
 *	is complete. That guarantee is necessary for security reasons.
627
628
 */

629
void tty_vhangup(struct tty_struct *tty)
Linus Torvalds's avatar
Linus Torvalds committed
630
631
632
633
634
635
{
#ifdef TTY_DEBUG_HANGUP
	char	buf[64];

	printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
#endif
636
	do_tty_hangup(&tty->hangup_work);
Linus Torvalds's avatar
Linus Torvalds committed
637
}
638

Linus Torvalds's avatar
Linus Torvalds committed
639
640
EXPORT_SYMBOL(tty_vhangup);

Alan Cox's avatar
Alan Cox committed
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
/**
 *	tty_vhangup_self	-	process vhangup for own ctty
 *
 *	Perform a vhangup on the current controlling tty
 */

void tty_vhangup_self(void)
{
	struct tty_struct *tty;

	tty = get_current_tty();
	if (tty) {
		tty_vhangup(tty);
		tty_kref_put(tty);
	}
}

658
659
660
661
662
663
664
665
/**
 *	tty_hung_up_p		-	was tty hung up
 *	@filp: file pointer of tty
 *
 *	Return true if the tty has been subject to a vhangup or a carrier
 *	loss
 */

666
int tty_hung_up_p(struct file *filp)
Linus Torvalds's avatar
Linus Torvalds committed
667
668
669
670
671
672
{
	return (filp->f_op == &hung_up_tty_fops);
}

EXPORT_SYMBOL(tty_hung_up_p);

673
static void session_clear_tty(struct pid *session)
674
675
{
	struct task_struct *p;
676
	do_each_pid_task(session, PIDTYPE_SID, p) {
677
		proc_clear_tty(p);
678
	} while_each_pid_task(session, PIDTYPE_SID, p);
679
680
}

681
682
683
/**
 *	disassociate_ctty	-	disconnect controlling tty
 *	@on_exit: true if exiting so need to "hang up" the session
Linus Torvalds's avatar
Linus Torvalds committed
684
 *
685
686
687
688
 *	This function is typically called only by the session leader, when
 *	it wants to disassociate itself from its controlling tty.
 *
 *	It performs the following functions:
Linus Torvalds's avatar
Linus Torvalds committed
689
690
691
692
693
 * 	(1)  Sends a SIGHUP and SIGCONT to the foreground process group
 * 	(2)  Clears the tty from being controlling the session
 * 	(3)  Clears the controlling tty for all processes in the
 * 		session group.
 *
694
695
696
 *	The argument on_exit is set to 1 if called when a process is
 *	exiting; it is 0 if called by the ioctl TIOCNOTTY.
 *
697
 *	Locking:
698
 *		BKL is taken for hysterical raisins
699
700
701
702
 *		  tty_mutex is taken to protect tty
 *		  ->siglock is taken to protect ->signal/->sighand
 *		  tasklist_lock is taken to walk process list for sessions
 *		    ->siglock is taken to protect ->signal/->sighand
Linus Torvalds's avatar
Linus Torvalds committed
703
 */
704

Linus Torvalds's avatar
Linus Torvalds committed
705
706
707
void disassociate_ctty(int on_exit)
{
	struct tty_struct *tty;
708
	struct pid *tty_pgrp = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
709
710


711
	tty = get_current_tty();
Linus Torvalds's avatar
Linus Torvalds committed
712
	if (tty) {
713
		tty_pgrp = get_pid(tty->pgrp);
714
		lock_kernel();
Linus Torvalds's avatar
Linus Torvalds committed
715
716
		if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
			tty_vhangup(tty);
Alan Cox's avatar
Alan Cox committed
717
		unlock_kernel();
718
		tty_kref_put(tty);
719
	} else if (on_exit) {
720
		struct pid *old_pgrp;
721
722
		spin_lock_irq(&current->sighand->siglock);
		old_pgrp = current->signal->tty_old_pgrp;
723
		current->signal->tty_old_pgrp = NULL;
724
		spin_unlock_irq(&current->sighand->siglock);
725
		if (old_pgrp) {
726
727
728
			kill_pgrp(old_pgrp, SIGHUP, on_exit);
			kill_pgrp(old_pgrp, SIGCONT, on_exit);
			put_pid(old_pgrp);
Linus Torvalds's avatar
Linus Torvalds committed
729
730
731
		}
		return;
	}
732
733
	if (tty_pgrp) {
		kill_pgrp(tty_pgrp, SIGHUP, on_exit);
Linus Torvalds's avatar
Linus Torvalds committed
734
		if (!on_exit)
735
736
			kill_pgrp(tty_pgrp, SIGCONT, on_exit);
		put_pid(tty_pgrp);
Linus Torvalds's avatar
Linus Torvalds committed
737
738
	}

739
	spin_lock_irq(&current->sighand->siglock);
740
	put_pid(current->signal->tty_old_pgrp);
Randy Dunlap's avatar
Randy Dunlap committed
741
	current->signal->tty_old_pgrp = NULL;
742
743
744
745
	spin_unlock_irq(&current->sighand->siglock);

	tty = get_current_tty();
	if (tty) {
Alan Cox's avatar
Alan Cox committed
746
747
		unsigned long flags;
		spin_lock_irqsave(&tty->ctrl_lock, flags);
748
749
750
751
		put_pid(tty->session);
		put_pid(tty->pgrp);
		tty->session = NULL;
		tty->pgrp = NULL;
Alan Cox's avatar
Alan Cox committed
752
		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
753
		tty_kref_put(tty);
754
755
756
757
758
759
	} else {
#ifdef TTY_DEBUG_HANGUP
		printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
		       " = NULL", tty);
#endif
	}
Linus Torvalds's avatar
Linus Torvalds committed
760
761
762

	/* Now clear signal->tty under the lock */
	read_lock(&tasklist_lock);
763
	session_clear_tty(task_session(current));
Linus Torvalds's avatar
Linus Torvalds committed
764
765
766
	read_unlock(&tasklist_lock);
}

767
768
769
770
771
772
773
/**
 *
 *	no_tty	- Ensure the current process does not have a controlling tty
 */
void no_tty(void)
{
	struct task_struct *tsk = current;
Alan Cox's avatar
Alan Cox committed
774
	lock_kernel();
775
776
	if (tsk->signal->leader)
		disassociate_ctty(0);
Alan Cox's avatar
Alan Cox committed
777
	unlock_kernel();
778
779
780
	proc_clear_tty(tsk);
}

781
782

/**
783
 *	stop_tty	-	propagate flow control
784
785
786
 *	@tty: tty to stop
 *
 *	Perform flow control to the driver. For PTY/TTY pairs we
787
 *	must also propagate the TIOCKPKT status. May be called
788
789
790
791
792
793
794
795
796
 *	on an already stopped device and will not re-call the driver
 *	method.
 *
 *	This functionality is used by both the line disciplines for
 *	halting incoming flow and by the driver. It may therefore be
 *	called from any context, may be under the tty atomic_write_lock
 *	but not always.
 *
 *	Locking:
Alan Cox's avatar
Alan Cox committed
797
 *		Uses the tty control lock internally
798
799
 */

Linus Torvalds's avatar
Linus Torvalds committed
800
801
void stop_tty(struct tty_struct *tty)
{
Alan Cox's avatar
Alan Cox committed
802
803
804
805
	unsigned long flags;
	spin_lock_irqsave(&tty->ctrl_lock, flags);
	if (tty->stopped) {
		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
806
		return;
Alan Cox's avatar
Alan Cox committed
807
	}
Linus Torvalds's avatar
Linus Torvalds committed
808
809
810
811
	tty->stopped = 1;
	if (tty->link && tty->link->packet) {
		tty->ctrl_status &= ~TIOCPKT_START;
		tty->ctrl_status |= TIOCPKT_STOP;
812
		wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
Linus Torvalds's avatar
Linus Torvalds committed
813
	}
Alan Cox's avatar
Alan Cox committed
814
	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Alan Cox's avatar
Alan Cox committed
815
816
	if (tty->ops->stop)
		(tty->ops->stop)(tty);
Linus Torvalds's avatar
Linus Torvalds committed
817
818
819
820
}

EXPORT_SYMBOL(stop_tty);

821
/**
822
 *	start_tty	-	propagate flow control
823
824
825
 *	@tty: tty to start
 *
 *	Start a tty that has been stopped if at all possible. Perform
826
 *	any necessary wakeups and propagate the TIOCPKT status. If this
827
828
829
830
 *	is the tty was previous stopped and is being started then the
 *	driver start method is invoked and the line discipline woken.
 *
 *	Locking:
Alan Cox's avatar
Alan Cox committed
831
 *		ctrl_lock
832
833
 */

Linus Torvalds's avatar
Linus Torvalds committed
834
835
void start_tty(struct tty_struct *tty)
{
Alan Cox's avatar
Alan Cox committed
836
837
838
839
	unsigned long flags;
	spin_lock_irqsave(&tty->ctrl_lock, flags);
	if (!tty->stopped || tty->flow_stopped) {
		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
840
		return;
Alan Cox's avatar
Alan Cox committed
841
	}
Linus Torvalds's avatar
Linus Torvalds committed
842
843
844
845
	tty->stopped = 0;
	if (tty->link && tty->link->packet) {
		tty->ctrl_status &= ~TIOCPKT_STOP;
		tty->ctrl_status |= TIOCPKT_START;
846
		wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
Linus Torvalds's avatar
Linus Torvalds committed
847
	}
Alan Cox's avatar
Alan Cox committed
848
	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
Alan Cox's avatar
Alan Cox committed
849
850
	if (tty->ops->start)
		(tty->ops->start)(tty);
Linus Torvalds's avatar
Linus Torvalds committed
851
852
853
854
855
856
	/* If we have a running line discipline it may need kicking */
	tty_wakeup(tty);
}

EXPORT_SYMBOL(start_tty);

857
858
859
860
861
862
863
864
865
866
867
/**
 *	tty_read	-	read method for tty device files
 *	@file: pointer to tty file
 *	@buf: user buffer
 *	@count: size of user buffer
 *	@ppos: unused
 *
 *	Perform the read system call function on this terminal device. Checks
 *	for hung up devices before calling the line discipline method.
 *
 *	Locking:
Alan Cox's avatar
Alan Cox committed
868
869
 *		Locks the line discipline internally while needed. Multiple
 *	read calls may be outstanding in parallel.
870
871
 */

872
static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
Linus Torvalds's avatar
Linus Torvalds committed
873
874
875
			loff_t *ppos)
{
	int i;
876
	struct tty_struct *tty;
Linus Torvalds's avatar
Linus Torvalds committed
877
878
879
880
	struct inode *inode;
	struct tty_ldisc *ld;

	tty = (struct tty_struct *)file->private_data;
881
	inode = file->f_path.dentry->d_inode;
Linus Torvalds's avatar
Linus Torvalds committed
882
883
884
885
886
887
888
889
	if (tty_paranoia_check(tty, inode, "tty_read"))
		return -EIO;
	if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
		return -EIO;

	/* We want to wait for the line discipline to sort out in this
	   situation */
	ld = tty_ldisc_ref_wait(tty);
Alan Cox's avatar
Alan Cox committed
890
891
	if (ld->ops->read)
		i = (ld->ops->read)(tty, file, buf, count);
Linus Torvalds's avatar
Linus Torvalds committed
892
893
894
895
896
897
898
899
	else
		i = -EIO;
	tty_ldisc_deref(ld);
	if (i > 0)
		inode->i_atime = current_fs_time(inode->i_sb);
	return i;
}

900
901
902
void tty_write_unlock(struct tty_struct *tty)
{
	mutex_unlock(&tty->atomic_write_lock);
903
	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
904
905
906
907
908
909
910
911
912
913
914
915
916
}

int tty_write_lock(struct tty_struct *tty, int ndelay)
{
	if (!mutex_trylock(&tty->atomic_write_lock)) {
		if (ndelay)
			return -EAGAIN;
		if (mutex_lock_interruptible(&tty->atomic_write_lock))
			return -ERESTARTSYS;
	}
	return 0;
}

Linus Torvalds's avatar
Linus Torvalds committed
917
918
919
920
921
922
923
924
925
926
927
/*
 * Split writes up in sane blocksizes to avoid
 * denial-of-service type attacks
 */
static inline ssize_t do_tty_write(
	ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),
	struct tty_struct *tty,
	struct file *file,
	const char __user *buf,
	size_t count)
{
928
	ssize_t ret, written = 0;
Linus Torvalds's avatar
Linus Torvalds committed
929
	unsigned int chunk;
930

931
932
933
	ret = tty_write_lock(tty, file->f_flags & O_NDELAY);
	if (ret < 0)
		return ret;
Linus Torvalds's avatar
Linus Torvalds committed
934
935
936
937
938
939
940
941
942
943
944
945
946

	/*
	 * We chunk up writes into a temporary buffer. This
	 * simplifies low-level drivers immensely, since they
	 * don't have locking issues and user mode accesses.
	 *
	 * But if TTY_NO_WRITE_SPLIT is set, we should use a
	 * big chunk-size..
	 *
	 * The default chunk-size is 2kB, because the NTTY
	 * layer has problems with bigger chunks. It will
	 * claim to be able to handle more characters than
	 * it actually does.
947
948
949
	 *
	 * FIXME: This can probably go away now except that 64K chunks
	 * are too likely to fail unless switched to vmalloc...
Linus Torvalds's avatar
Linus Torvalds committed
950
951
952
953
954
955
956
	 */
	chunk = 2048;
	if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags))
		chunk = 65536;
	if (count < chunk)
		chunk = count;

Ingo Molnar's avatar
Ingo Molnar committed
957
	/* write_buf/write_cnt is protected by the atomic_write_lock mutex */
Linus Torvalds's avatar
Linus Torvalds committed
958
	if (tty->write_cnt < chunk) {
959
		unsigned char *buf_chunk;
Linus Torvalds's avatar
Linus Torvalds committed
960
961
962
963

		if (chunk < 1024)
			chunk = 1024;

964
965
		buf_chunk = kmalloc(chunk, GFP_KERNEL);
		if (!buf_chunk) {
966
967
			ret = -ENOMEM;
			goto out;
Linus Torvalds's avatar
Linus Torvalds committed
968
969
970
		}
		kfree(tty->write_buf);
		tty->write_cnt = chunk;
971
		tty->write_buf = buf_chunk;
Linus Torvalds's avatar
Linus Torvalds committed
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
	}

	/* Do the write .. */
	for (;;) {
		size_t size = count;
		if (size > chunk)
			size = chunk;
		ret = -EFAULT;
		if (copy_from_user(tty->write_buf, buf, size))
			break;
		ret = write(tty, file, tty->write_buf, size);
		if (ret <= 0)
			break;
		written += ret;
		buf += ret;
		count -= ret;
		if (!count)
			break;
		ret = -ERESTARTSYS;
		if (signal_pending(current))
			break;
		cond_resched();
	}
	if (written) {
996
		struct inode *inode = file->f_path.dentry->d_inode;
Linus Torvalds's avatar
Linus Torvalds committed
997
998
999
		inode->i_mtime = current_fs_time(inode->i_sb);
		ret = written;
	}
1000
1001
out:
	tty_write_unlock(tty);
Linus Torvalds's avatar
Linus Torvalds committed
1002
1003
1004
	return ret;
}

1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
/**
 * tty_write_message - write a message to a certain tty, not just the console.
 * @tty: the destination tty_struct
 * @msg: the message to write
 *
 * This is used for messages that need to be redirected to a specific tty.
 * We don't put it into the syslog queue right now maybe in the future if
 * really needed.
 *
 * We must still hold the BKL and test the CLOSING flag for the moment.
 */

void tty_write_message(struct tty_struct *tty, char *msg)
{
	if (tty) {
		mutex_lock(&tty->atomic_write_lock);
1021
1022
1023
		lock_kernel();
		if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) {
			unlock_kernel();
1024
			tty->ops->write(tty, msg, strlen(msg));
1025
1026
		} else
			unlock_kernel();
1027
1028
1029
1030
1031
		tty_write_unlock(tty);
	}
	return;
}

Linus Torvalds's avatar
Linus Torvalds committed
1032

1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
/**
 *	tty_write		-	write method for tty device file
 *	@file: tty file pointer
 *	@buf: user data to write
 *	@count: bytes to write
 *	@ppos: unused
 *
 *	Write data to a tty device via the line discipline.
 *
 *	Locking:
 *		Locks the line discipline as required
 *		Writes to the tty driver are serialized by the atomic_write_lock
 *	and are then processed in chunks to the device. The line discipline
1046
 *	write method will not be invoked in parallel for each device.
1047
1048
 */

1049
1050
static ssize_t tty_write(struct file *file, const char __user *buf,
						size_t count, loff_t *ppos)
Linus Torvalds's avatar
Linus Torvalds committed
1051
{
1052
	struct tty_struct *tty;
1053
	struct inode *inode = file->f_path.dentry->d_inode;
Linus Torvalds's avatar
Linus Torvalds committed
1054
1055
	ssize_t ret;
	struct tty_ldisc *ld;
1056

Linus Torvalds's avatar
Linus Torvalds committed
1057
1058
1059
	tty = (struct tty_struct *)file->private_data;
	if (tty_paranoia_check(tty, inode, "tty_write"))
		return -EIO;
Alan Cox's avatar
Alan Cox committed
1060
	if (!tty || !tty->ops->write ||
1061
1062
		(test_bit(TTY_IO_ERROR, &tty->flags)))
			return -EIO;
Alan Cox's avatar
Alan Cox committed
1063
1064
1065
1066
	/* Short term debug to catch buggy drivers */
	if (tty->ops->write_room == NULL)
		printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
			tty->driver->name);
1067
	ld = tty_ldisc_ref_wait(tty);
Alan Cox's avatar
Alan Cox committed
1068
	if (!ld->ops->write)
Linus Torvalds's avatar
Linus Torvalds committed
1069
1070
		ret = -EIO;
	else
Alan Cox's avatar
Alan Cox committed
1071
		ret = do_tty_write(ld->ops->write, tty, file, buf, count);
Linus Torvalds's avatar
Linus Torvalds committed
1072
1073
1074
1075
	tty_ldisc_deref(ld);
	return ret;
}

1076
1077
ssize_t redirected_tty_write(struct file *file, const char __user *buf,
						size_t count, loff_t *ppos)
Linus Torvalds's avatar
Linus Torvalds committed
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
{
	struct file *p = NULL;

	spin_lock(&redirect_lock);
	if (redirect) {
		get_file(redirect);
		p = redirect;
	}
	spin_unlock(&redirect_lock);

	if (p) {
		ssize_t res;
		res = vfs_write(p, buf, count, &p->f_pos);
		fput(p);
		return res;
	}
	return tty_write(file, buf, count, ppos);
}

static char ptychar[] = "pqrstuvwxyzabcde";

1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
/**
 *	pty_line_name	-	generate name for a pty
 *	@driver: the tty driver in use
 *	@index: the minor number
 *	@p: output buffer of at least 6 bytes
 *
 *	Generate a name from a driver reference and write it to the output
 *	buffer.
 *
 *	Locking: None
 */
static void pty_line_name(struct tty_driver *driver, int index, char *p)
Linus Torvalds's avatar
Linus Torvalds committed
1111
1112
1113
1114
{
	int i = index + driver->name_base;
	/* ->name is initialized to "ttyp", but "tty" is expected */
	sprintf(p, "%s%c%x",
1115
1116
		driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name,
		ptychar[i >> 4 & 0xf], i & 0xf);
Linus Torvalds's avatar
Linus Torvalds committed
1117
1118
}

1119
/**
Alan Cox's avatar
Alan Cox committed
1120
 *	tty_line_name	-	generate name for a tty
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
 *	@driver: the tty driver in use
 *	@index: the minor number
 *	@p: output buffer of at least 7 bytes
 *
 *	Generate a name from a driver reference and write it to the output
 *	buffer.
 *
 *	Locking: None
 */
static void tty_line_name(struct tty_driver *driver, int index, char *p)
Linus Torvalds's avatar
Linus Torvalds committed
1131
1132
1133
1134
{
	sprintf(p, "%s%d", driver->name, index + driver->name_base);
}

1135
1136
1137
1138
/**
 *	tty_driver_lookup_tty() - find an existing tty, if any
 *	@driver: the driver for the tty
 *	@idx:	 the minor number
1139
 *
1140
 *	Return the tty, if found or ERR_PTR() otherwise.
1141
 *
1142
1143
1144
 *	Locking: tty_mutex must be held. If tty is found, the mutex must
 *	be held until the 'fast-open' is also done. Will change once we
 *	have refcounting in the driver and per driver locking
1145
 */
1146
static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
1147
		struct inode *inode, int idx)
1148
1149
1150
{
	struct tty_struct *tty;

1151
	if (driver->ops->lookup)
1152
		return driver->ops->lookup(driver, inode, idx);
1153

Alan Cox's avatar
Alan Cox committed
1154
	tty = driver->ttys[idx];
1155
1156
1157
	return tty;
}

1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
/**
 *	tty_init_termios	-  helper for termios setup
 *	@tty: the tty to set up
 *
 *	Initialise the termios structures for this tty. Thus runs under
 *	the tty_mutex currently so we can be relaxed about ordering.
 */

int tty_init_termios(struct tty_struct *tty)
{
Alan Cox's avatar
Alan Cox committed
1168
	struct ktermios *tp;
1169
1170
1171
1172
	int idx = tty->index;

	tp = tty->driver->termios[idx];
	if (tp == NULL) {
Alan Cox's avatar
Alan Cox committed
1173
1174
		tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
		if (tp == NULL)
1175
1176
1177
1178
1179
1180
			return -ENOMEM;
		memcpy(tp, &tty->driver->init_termios,
						sizeof(struct ktermios));
		tty->driver->termios[idx] = tp;
	}
	tty->termios = tp;
Alan Cox's avatar
Alan Cox committed
1181
	tty->termios_locked = tp + 1;
1182
1183
1184
1185
1186
1187

	/* Compatibility until drivers always set this */
	tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
	tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
	return 0;
}
Alan Cox's avatar
Alan Cox committed
1188
EXPORT_SYMBOL_GPL(tty_init_termios);
1189

1190
/**
Alan Cox's avatar
Alan Cox committed
1191
1192
1193
1194
1195
 *	tty_driver_install_tty() - install a tty entry in the driver
 *	@driver: the driver for the tty
 *	@tty: the tty
 *
 *	Install a tty object into the driver tables. The tty->index field
1196
1197
1198
 *	will be set by the time this is called. This method is responsible
 *	for ensuring any need additional structures are allocated and
 *	configured.
Alan Cox's avatar
Alan Cox committed
1199
1200
1201
1202
1203
1204
 *
 *	Locking: tty_mutex for now
 */
static int tty_driver_install_tty(struct tty_driver *driver,
						struct tty_struct *tty)
{
1205
	int idx = tty->index;
1206
	int ret;
1207

1208
1209
1210
1211
1212
1213
	if (driver->ops->install) {
		lock_kernel();
		ret = driver->ops->install(driver, tty);
		unlock_kernel();
		return ret;
	}
1214
1215

	if (tty_init_termios(tty) == 0) {
1216
		lock_kernel();
1217
1218
1219
		tty_driver_kref_get(driver);
		tty->count++;
		driver->ttys[idx] = tty;
1220
		unlock_kernel();
1221
1222
1223
		return 0;
	}
	return -ENOMEM;
Alan Cox's avatar
Alan Cox committed
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
}

/**
 *	tty_driver_remove_tty() - remove a tty from the driver tables
 *	@driver: the driver for the tty
 *	@idx:	 the minor number
 *
 *	Remvoe a tty object from the driver tables. The tty->index field
 *	will be set by the time this is called.
 *
 *	Locking: tty_mutex for now
 */
static void tty_driver_remove_tty(struct tty_driver *driver,
						struct tty_struct *tty)
{
	if (driver->ops->remove)
		driver->ops->remove(driver, tty);
	else
		driver->ttys[tty->index] = NULL;
}

/*
 * 	tty_reopen()	- fast re-open of an open tty
 * 	@tty	- the tty to open
1248
 *
1249
 *	Return 0 on success, -errno on error.
1250
 *
1251
1252
 *	Locking: tty_mutex must be held from the time the tty was found
 *		 till this open completes.
1253
 */
1254
static int tty_reopen(struct tty_struct *tty)
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
{
	struct tty_driver *driver = tty->driver;

	if (test_bit(TTY_CLOSING, &tty->flags))
		return -EIO;

	if (driver->type == TTY_DRIVER_TYPE_PTY &&
	    driver->subtype == PTY_TYPE_MASTER) {
		/*
		 * special case for PTY masters: only one open permitted,
		 * and the slave side open count is incremented as well.
		 */
		if (tty->count)
			return -EIO;

		tty->link->count++;
	}
	tty->count++;
	tty->driver = driver; /* N.B. why do this every time?? */

Alan Cox's avatar
Alan Cox committed
1275
	mutex_lock(&tty->ldisc_mutex);
1276
	WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
Alan Cox's avatar
Alan Cox committed
1277
	mutex_unlock(&tty->ldisc_mutex);
1278
1279
1280
1281

	return 0;
}

1282
/**
1283
 *	tty_init_dev		-	initialise a tty device
1284
1285
 *	@driver: tty driver we are opening a device on
 *	@idx: device index
1286
1287
 *	@ret_tty: returned tty structure
 *	@first_ok: ok to open a new device (used by ptmx)
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
 *
 *	Prepare a tty device. This may not be a "new" clean device but
 *	could also be an active device. The pty drivers require special
 *	handling because of this.
 *
 *	Locking:
 *		The function is called under the tty_mutex, which
 *	protects us from the tty struct or driver itself going away.
 *
 *	On exit the tty device has the line discipline attached and
 *	a reference count of 1. If a pair was created for pty/tty use
 *	and the other was a pty master then it too has a reference count of 1.
 *
Linus Torvalds's avatar
Linus Torvalds committed
1301
 * WSH 06/09/97: Rewritten to remove races and properly clean up after a
Ingo Molnar's avatar
Ingo Molnar committed
1302
1303
 * failed open.  The new code protects the open with a mutex, so it's
 * really quite straightforward.  The mutex locking can probably be
Linus Torvalds's avatar
Linus Torvalds committed
1304
1305
 * relaxed for the (most common) case of reopening a tty.
 */
1306

1307
1308
struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
								int first_ok)
Linus Torvalds's avatar
Linus Torvalds committed
1309
{
1310
	struct tty_struct *tty;
1311
	int retval;
Linus Torvalds's avatar
Linus Torvalds committed
1312

1313
	lock_kernel();
1314
	/* Check if pty master is being opened multiple times */
1315
	if (driver->subtype == PTY_TYPE_MASTER &&