n_tty.c 61.1 KB
Newer Older
1
// SPDX-License-Identifier: GPL-1.0+
L
Linus Torvalds 已提交
2 3
/*
 * n_tty.c --- implements the N_TTY line discipline.
4
 *
L
Linus Torvalds 已提交
5 6 7 8 9 10 11
 * This code used to be in tty_io.c, but things are getting hairy
 * enough that it made sense to split things off.  (The N_TTY
 * processing has changed so much that it's hardly recognizable,
 * anyway...)
 *
 * Note that the open routine for N_TTY is guaranteed never to return
 * an error.  This is because Linux will fall back to setting a line
12
 * to N_TTY if it can not switch to any other line discipline.
L
Linus Torvalds 已提交
13 14
 *
 * Written by Theodore Ts'o, Copyright 1994.
15
 *
L
Linus Torvalds 已提交
16 17
 * This file also contains code originally written by Linus Torvalds,
 * Copyright 1991, 1992, 1993, and by Julian Cowley, Copyright 1994.
18
 *
L
Linus Torvalds 已提交
19 20
 * Reduced memory usage for older ARM systems  - Russell King.
 *
21
 * 2000/01/20   Fixed SMP locking on put_tty_queue using bits of
L
Linus Torvalds 已提交
22 23 24 25 26
 *		the patch by Andrew J. Kroll <ag784@freenet.buffalo.edu>
 *		who actually finally proved there really was a race.
 *
 * 2002/03/18   Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
 *		waiting writing processes-Sapan Bhatia <sapan@corewars.org>.
27
 *		Also fixed a bug in BLOCKING mode where n_tty_write returns
L
Linus Torvalds 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
 *		EAGAIN
 */

#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/timer.h>
#include <linux/ctype.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/bitops.h>
M
Miloslav Trmac 已提交
46 47
#include <linux/audit.h>
#include <linux/file.h>
A
Alan Cox 已提交
48
#include <linux/uaccess.h>
49
#include <linux/module.h>
50
#include <linux/ratelimit.h>
51
#include <linux/vmalloc.h>
L
Linus Torvalds 已提交
52 53 54 55 56 57 58 59 60 61 62


/* number of characters left in xmit buffer before select has we have room */
#define WAKEUP_CHARS 256

/*
 * This defines the low- and high-watermarks for throttling and
 * unthrottling the TTY driver.  These watermarks are used for
 * controlling the space in the read buffer.
 */
#define TTY_THRESHOLD_THROTTLE		128 /* now based on remaining room */
63
#define TTY_THRESHOLD_UNTHROTTLE	128
L
Linus Torvalds 已提交
64

65 66 67 68 69 70 71 72 73 74 75
/*
 * Special byte codes used in the echo buffer to represent operations
 * or special handling of characters.  Bytes in the echo buffer that
 * are not part of such special blocks are treated as normal character
 * codes.
 */
#define ECHO_OP_START 0xff
#define ECHO_OP_MOVE_BACK_COL 0x80
#define ECHO_OP_SET_CANON_COL 0x81
#define ECHO_OP_ERASE_TAB 0x82

P
Peter Hurley 已提交
76 77 78 79 80
#define ECHO_COMMIT_WATERMARK	256
#define ECHO_BLOCK		256
#define ECHO_DISCARD_WATERMARK	N_TTY_BUF_SIZE - (ECHO_BLOCK + 32)


81 82 83 84 85 86 87
#undef N_TTY_TRACE
#ifdef N_TTY_TRACE
# define n_tty_trace(f, args...)	trace_printk(f, ##args)
#else
# define n_tty_trace(f, args...)
#endif

J
Jiri Slaby 已提交
88
struct n_tty_data {
89 90
	/* producer-published */
	size_t read_head;
91
	size_t commit_head;
92
	size_t canon_head;
93 94
	size_t echo_head;
	size_t echo_commit;
95
	size_t echo_mark;
96
	DECLARE_BITMAP(char_map, 256);
97 98

	/* private to n_tty_receive_overrun (single-threaded) */
99 100 101
	unsigned long overrun_time;
	int num_overrun;

102 103 104
	/* non-atomic */
	bool no_room;

105
	/* must hold exclusive termios_rwsem to reset these */
106
	unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1;
107
	unsigned char push:1;
108

109
	/* shared by producer and consumer */
110
	char read_buf[N_TTY_BUF_SIZE];
111
	DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE);
112
	unsigned char echo_buf[N_TTY_BUF_SIZE];
113

114 115
	/* consumer-published */
	size_t read_tail;
P
Peter Hurley 已提交
116
	size_t line_start;
117 118 119

	/* protected by output lock */
	unsigned int column;
120
	unsigned int canon_column;
121
	size_t echo_tail;
122 123 124

	struct mutex atomic_read_lock;
	struct mutex output_lock;
J
Jiri Slaby 已提交
125 126
};

127 128
#define MASK(x) ((x) & (N_TTY_BUF_SIZE - 1))

129 130
static inline size_t read_cnt(struct n_tty_data *ldata)
{
P
Peter Hurley 已提交
131
	return ldata->read_head - ldata->read_tail;
132 133
}

134 135 136 137 138 139 140 141 142 143
static inline unsigned char read_buf(struct n_tty_data *ldata, size_t i)
{
	return ldata->read_buf[i & (N_TTY_BUF_SIZE - 1)];
}

static inline unsigned char *read_buf_addr(struct n_tty_data *ldata, size_t i)
{
	return &ldata->read_buf[i & (N_TTY_BUF_SIZE - 1)];
}

144 145
static inline unsigned char echo_buf(struct n_tty_data *ldata, size_t i)
{
146
	smp_rmb(); /* Matches smp_wmb() in add_echo_byte(). */
147 148 149 150 151 152 153 154
	return ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)];
}

static inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i)
{
	return &ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)];
}

P
Peter Hurley 已提交
155 156
static int tty_copy_to_user(struct tty_struct *tty, void __user *to,
			    size_t tail, size_t n)
157 158
{
	struct n_tty_data *ldata = tty->disc_data;
P
Peter Hurley 已提交
159 160 161 162 163
	size_t size = N_TTY_BUF_SIZE - tail;
	const void *from = read_buf_addr(ldata, tail);
	int uncopied;

	if (n > size) {
164
		tty_audit_add_data(tty, from, size);
P
Peter Hurley 已提交
165 166 167 168 169 170 171
		uncopied = copy_to_user(to, from, size);
		if (uncopied)
			return uncopied;
		to += size;
		n -= size;
		from = ldata->read_buf;
	}
172

173
	tty_audit_add_data(tty, from, n);
174 175 176
	return copy_to_user(to, from, n);
}

177
/**
178
 *	n_tty_kick_worker - start input worker (if required)
179 180
 *	@tty: terminal
 *
181
 *	Re-schedules the flip buffer work if it may have stopped
182
 *
183 184 185 186
 *	Caller holds exclusive termios_rwsem
 *	   or
 *	n_tty_read()/consumer path:
 *		holds non-exclusive termios_rwsem
187 188
 */

189
static void n_tty_kick_worker(struct tty_struct *tty)
190
{
191 192
	struct n_tty_data *ldata = tty->disc_data;

193 194
	/* Did the input worker stop? Restart it */
	if (unlikely(ldata->no_room)) {
195 196
		ldata->no_room = 0;

J
Jiri Slaby 已提交
197
		WARN_RATELIMIT(tty->port->itty == NULL,
198
				"scheduling with invalid itty\n");
199 200 201 202 203 204
		/* see if ldisc has been killed - if so, this means that
		 * even though the ldisc has been halted and ->buf.work
		 * cancelled, ->buf.work is about to be rescheduled
		 */
		WARN_RATELIMIT(test_bit(TTY_LDISC_HALTED, &tty->flags),
			       "scheduling buffer work for halted ldisc\n");
P
Peter Hurley 已提交
205
		tty_buffer_restart_work(tty->port);
J
Jiri Slaby 已提交
206
	}
207 208
}

209 210 211 212 213 214
static ssize_t chars_in_buffer(struct tty_struct *tty)
{
	struct n_tty_data *ldata = tty->disc_data;
	ssize_t n = 0;

	if (!ldata->icanon)
215
		n = ldata->commit_head - ldata->read_tail;
216 217 218 219 220
	else
		n = ldata->canon_head - ldata->read_tail;
	return n;
}

221 222 223 224 225 226 227 228 229 230 231
/**
 *	n_tty_write_wakeup	-	asynchronous I/O notifier
 *	@tty: tty device
 *
 *	Required for the ptys, serial driver etc. since processes
 *	that attach themselves to the master and rely on ASYNC
 *	IO must be woken up
 */

static void n_tty_write_wakeup(struct tty_struct *tty)
{
P
Peter Hurley 已提交
232 233
	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
	kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
234 235
}

236
static void n_tty_check_throttle(struct tty_struct *tty)
237
{
238 239
	struct n_tty_data *ldata = tty->disc_data;

240 241 242 243 244
	/*
	 * Check the remaining room for the input canonicalization
	 * mode.  We don't want to throttle the driver if we're in
	 * canonical mode and don't have a newline yet!
	 */
245 246 247
	if (ldata->icanon && ldata->canon_head == ldata->read_tail)
		return;

248 249 250
	while (1) {
		int throttled;
		tty_set_flow_change(tty, TTY_THROTTLE_SAFE);
251
		if (N_TTY_BUF_SIZE - read_cnt(ldata) >= TTY_THRESHOLD_THROTTLE)
252 253 254 255 256 257 258 259
			break;
		throttled = tty_throttle_safe(tty);
		if (!throttled)
			break;
	}
	__tty_set_flow_change(tty, 0);
}

260
static void n_tty_check_unthrottle(struct tty_struct *tty)
261
{
262
	if (tty->driver->type == TTY_DRIVER_TYPE_PTY) {
263 264
		if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE)
			return;
265
		n_tty_kick_worker(tty);
266
		tty_wakeup(tty->link);
267 268 269
		return;
	}

270 271 272 273 274 275 276 277 278 279 280 281 282
	/* If there is enough space in the read buffer now, let the
	 * low-level driver know. We use chars_in_buffer() to
	 * check the buffer, as it now knows about canonical mode.
	 * Otherwise, if the driver is throttled and the line is
	 * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
	 * we won't get any more characters.
	 */

	while (1) {
		int unthrottled;
		tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE);
		if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE)
			break;
283
		n_tty_kick_worker(tty);
284 285 286 287 288 289 290
		unthrottled = tty_unthrottle_safe(tty);
		if (!unthrottled)
			break;
	}
	__tty_set_flow_change(tty, 0);
}

291 292 293
/**
 *	put_tty_queue		-	add character to tty
 *	@c: character
J
Jiri Slaby 已提交
294
 *	@ldata: n_tty data
295
 *
296 297 298 299
 *	Add a character to the tty read_buf queue.
 *
 *	n_tty_receive_buf()/producer path:
 *		caller holds non-exclusive termios_rwsem
300 301
 */

302
static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
L
Linus Torvalds 已提交
303
{
304 305
	*read_buf_addr(ldata, ldata->read_head) = c;
	ldata->read_head++;
L
Linus Torvalds 已提交
306 307 308 309 310 311
}

/**
 *	reset_buffer_flags	-	reset buffer state
 *	@tty: terminal to reset
 *
312 313
 *	Reset the read buffer counters and clear the flags.
 *	Called from n_tty_open() and n_tty_flush_buffer().
314
 *
315 316
 *	Locking: caller holds exclusive termios_rwsem
 *		 (or locking is not required)
L
Linus Torvalds 已提交
317
 */
318

319
static void reset_buffer_flags(struct n_tty_data *ldata)
L
Linus Torvalds 已提交
320
{
321
	ldata->read_head = ldata->canon_head = ldata->read_tail = 0;
322
	ldata->commit_head = 0;
P
Peter Hurley 已提交
323
	ldata->line_start = 0;
324

325
	ldata->erasing = 0;
326
	bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
327
	ldata->push = 0;
L
Linus Torvalds 已提交
328 329
}

330 331 332 333 334
static void n_tty_packet_mode_flush(struct tty_struct *tty)
{
	unsigned long flags;

	if (tty->link->packet) {
335
		spin_lock_irqsave(&tty->ctrl_lock, flags);
336
		tty->ctrl_status |= TIOCPKT_FLUSHREAD;
337
		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
338
		wake_up_interruptible(&tty->link->read_wait);
339 340 341
	}
}

L
Linus Torvalds 已提交
342 343 344 345
/**
 *	n_tty_flush_buffer	-	clean input queue
 *	@tty:	terminal device
 *
346 347 348
 *	Flush the input buffer. Called when the tty layer wants the
 *	buffer flushed (eg at hangup) or when the N_TTY line discipline
 *	internally has to clean the pending queue (for example some signals).
L
Linus Torvalds 已提交
349
 *
350 351 352 353
 *	Holds termios_rwsem to exclude producer/consumer while
 *	buffer indices are reset.
 *
 *	Locking: ctrl_lock, exclusive termios_rwsem
L
Linus Torvalds 已提交
354
 */
355 356

static void n_tty_flush_buffer(struct tty_struct *tty)
L
Linus Torvalds 已提交
357
{
358
	down_write(&tty->termios_rwsem);
359
	reset_buffer_flags(tty->disc_data);
360
	n_tty_kick_worker(tty);
361

362 363
	if (tty->link)
		n_tty_packet_mode_flush(tty);
364
	up_write(&tty->termios_rwsem);
L
Linus Torvalds 已提交
365 366 367 368 369 370 371 372 373 374
}

/**
 *	is_utf8_continuation	-	utf8 multibyte check
 *	@c: byte to check
 *
 *	Returns true if the utf8 character 'c' is a multibyte continuation
 *	character. We use this to correctly compute the on screen size
 *	of the character when printing
 */
375

L
Linus Torvalds 已提交
376 377 378 379 380 381 382 383 384 385 386 387
static inline int is_utf8_continuation(unsigned char c)
{
	return (c & 0xc0) == 0x80;
}

/**
 *	is_continuation		-	multibyte check
 *	@c: byte to check
 *
 *	Returns true if the utf8 character 'c' is a multibyte continuation
 *	character and the terminal is in unicode mode.
 */
388

L
Linus Torvalds 已提交
389 390 391 392 393 394
static inline int is_continuation(unsigned char c, struct tty_struct *tty)
{
	return I_IUTF8(tty) && is_utf8_continuation(c);
}

/**
395
 *	do_output_char			-	output one character
L
Linus Torvalds 已提交
396 397
 *	@c: character (or partial unicode symbol)
 *	@tty: terminal device
398
 *	@space: space available in tty driver write buffer
L
Linus Torvalds 已提交
399
 *
400 401
 *	This is a helper function that handles one output character
 *	(including special characters like TAB, CR, LF, etc.),
402 403
 *	doing OPOST processing and putting the results in the
 *	tty driver's write buffer.
404 405 406 407
 *
 *	Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY
 *	and NLDLY.  They simply aren't relevant in the world today.
 *	If you ever need them, add them here.
L
Linus Torvalds 已提交
408
 *
409 410 411 412 413
 *	Returns the number of bytes of buffer space used or -1 if
 *	no space left.
 *
 *	Locking: should be called under the output_lock to protect
 *		 the column state and space left in the buffer
L
Linus Torvalds 已提交
414
 */
415

416
static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
L
Linus Torvalds 已提交
417
{
418
	struct n_tty_data *ldata = tty->disc_data;
419
	int	spaces;
L
Linus Torvalds 已提交
420 421 422

	if (!space)
		return -1;
A
Alan Cox 已提交
423

424 425 426
	switch (c) {
	case '\n':
		if (O_ONLRET(tty))
427
			ldata->column = 0;
428 429 430
		if (O_ONLCR(tty)) {
			if (space < 2)
				return -1;
431
			ldata->canon_column = ldata->column = 0;
432
			tty->ops->write(tty, "\r\n", 2);
433 434
			return 2;
		}
435
		ldata->canon_column = ldata->column;
436 437
		break;
	case '\r':
438
		if (O_ONOCR(tty) && ldata->column == 0)
439 440 441 442
			return 0;
		if (O_OCRNL(tty)) {
			c = '\n';
			if (O_ONLRET(tty))
443
				ldata->canon_column = ldata->column = 0;
L
Linus Torvalds 已提交
444
			break;
445
		}
446
		ldata->canon_column = ldata->column = 0;
447 448
		break;
	case '\t':
449
		spaces = 8 - (ldata->column & 7);
450 451 452
		if (O_TABDLY(tty) == XTABS) {
			if (space < spaces)
				return -1;
453
			ldata->column += spaces;
454 455
			tty->ops->write(tty, "        ", spaces);
			return spaces;
L
Linus Torvalds 已提交
456
		}
457
		ldata->column += spaces;
458 459
		break;
	case '\b':
460 461
		if (ldata->column > 0)
			ldata->column--;
462 463
		break;
	default:
464 465 466 467
		if (!iscntrl(c)) {
			if (O_OLCUC(tty))
				c = toupper(c);
			if (!is_continuation(c, tty))
468
				ldata->column++;
469
		}
470
		break;
L
Linus Torvalds 已提交
471
	}
472

A
Alan Cox 已提交
473
	tty_put_char(tty, c);
474 475 476 477 478 479 480 481
	return 1;
}

/**
 *	process_output			-	output post processor
 *	@c: character (or partial unicode symbol)
 *	@tty: terminal device
 *
482 483 484
 *	Output one character with OPOST processing.
 *	Returns -1 when the output device is full and the character
 *	must be retried.
485 486 487 488 489 490 491 492
 *
 *	Locking: output_lock to protect column state and space left
 *		 (also, this is called from n_tty_write under the
 *		  tty layer write lock)
 */

static int process_output(unsigned char c, struct tty_struct *tty)
{
493
	struct n_tty_data *ldata = tty->disc_data;
494 495
	int	space, retval;

496
	mutex_lock(&ldata->output_lock);
497 498 499 500

	space = tty_write_room(tty);
	retval = do_output_char(c, tty, space);

501
	mutex_unlock(&ldata->output_lock);
502 503 504 505
	if (retval < 0)
		return -1;
	else
		return 0;
L
Linus Torvalds 已提交
506 507 508
}

/**
509
 *	process_output_block		-	block post processor
L
Linus Torvalds 已提交
510
 *	@tty: terminal device
511 512 513 514 515
 *	@buf: character buffer
 *	@nr: number of bytes to output
 *
 *	Output a block of characters with OPOST processing.
 *	Returns the number of characters output.
L
Linus Torvalds 已提交
516 517 518 519 520 521
 *
 *	This path is used to speed up block console writes, among other
 *	things when processing blocks of output data. It handles only
 *	the simple cases normally found and helps to generate blocks of
 *	symbols for the console driver and thus improve performance.
 *
522 523 524
 *	Locking: output_lock to protect column state and space left
 *		 (also, this is called from n_tty_write under the
 *		  tty layer write lock)
L
Linus Torvalds 已提交
525
 */
526

527 528
static ssize_t process_output_block(struct tty_struct *tty,
				    const unsigned char *buf, unsigned int nr)
L
Linus Torvalds 已提交
529
{
530
	struct n_tty_data *ldata = tty->disc_data;
L
Linus Torvalds 已提交
531
	int	space;
532
	int	i;
L
Linus Torvalds 已提交
533 534
	const unsigned char *cp;

535
	mutex_lock(&ldata->output_lock);
536

A
Alan Cox 已提交
537
	space = tty_write_room(tty);
A
Alan Cox 已提交
538
	if (!space) {
539
		mutex_unlock(&ldata->output_lock);
L
Linus Torvalds 已提交
540
		return 0;
541
	}
L
Linus Torvalds 已提交
542 543 544 545
	if (nr > space)
		nr = space;

	for (i = 0, cp = buf; i < nr; i++, cp++) {
546 547 548
		unsigned char c = *cp;

		switch (c) {
L
Linus Torvalds 已提交
549 550
		case '\n':
			if (O_ONLRET(tty))
551
				ldata->column = 0;
L
Linus Torvalds 已提交
552 553
			if (O_ONLCR(tty))
				goto break_out;
554
			ldata->canon_column = ldata->column;
L
Linus Torvalds 已提交
555 556
			break;
		case '\r':
557
			if (O_ONOCR(tty) && ldata->column == 0)
L
Linus Torvalds 已提交
558 559 560
				goto break_out;
			if (O_OCRNL(tty))
				goto break_out;
561
			ldata->canon_column = ldata->column = 0;
L
Linus Torvalds 已提交
562 563 564 565
			break;
		case '\t':
			goto break_out;
		case '\b':
566 567
			if (ldata->column > 0)
				ldata->column--;
L
Linus Torvalds 已提交
568 569
			break;
		default:
570 571 572 573
			if (!iscntrl(c)) {
				if (O_OLCUC(tty))
					goto break_out;
				if (!is_continuation(c, tty))
574
					ldata->column++;
575
			}
L
Linus Torvalds 已提交
576 577 578 579
			break;
		}
	}
break_out:
A
Alan Cox 已提交
580
	i = tty->ops->write(tty, buf, i);
581

582
	mutex_unlock(&ldata->output_lock);
L
Linus Torvalds 已提交
583 584 585
	return i;
}

586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
/**
 *	process_echoes	-	write pending echo characters
 *	@tty: terminal device
 *
 *	Write previously buffered echo (and other ldisc-generated)
 *	characters to the tty.
 *
 *	Characters generated by the ldisc (including echoes) need to
 *	be buffered because the driver's write buffer can fill during
 *	heavy program output.  Echoing straight to the driver will
 *	often fail under these conditions, causing lost characters and
 *	resulting mismatches of ldisc state information.
 *
 *	Since the ldisc state must represent the characters actually sent
 *	to the driver at the time of the write, operations like certain
 *	changes in column state are also saved in the buffer and executed
 *	here.
 *
 *	A circular fifo buffer is used so that the most recent characters
 *	are prioritized.  Also, when control characters are echoed with a
 *	prefixed "^", the pair is treated atomically and thus not separated.
 *
608
 *	Locking: callers must hold output_lock
609 610
 */

611
static size_t __process_echoes(struct tty_struct *tty)
612
{
613
	struct n_tty_data *ldata = tty->disc_data;
614
	int	space, old_space;
615
	size_t tail;
616 617
	unsigned char c;

618
	old_space = space = tty_write_room(tty);
619

620
	tail = ldata->echo_tail;
621
	while (MASK(ldata->echo_commit) != MASK(tail)) {
622
		c = echo_buf(ldata, tail);
623 624 625 626
		if (c == ECHO_OP_START) {
			unsigned char op;
			int no_space_left = 0;

627 628 629 630 631 632 633
			/*
			 * Since add_echo_byte() is called without holding
			 * output_lock, we might see only portion of multi-byte
			 * operation.
			 */
			if (MASK(ldata->echo_commit) == MASK(tail + 1))
				goto not_yet_stored;
634 635 636 637 638
			/*
			 * If the buffer byte is the start of a multi-byte
			 * operation, get the next byte, which is either the
			 * op code or a control character value.
			 */
639
			op = echo_buf(ldata, tail + 1);
A
Alan Cox 已提交
640

641 642 643 644
			switch (op) {
				unsigned int num_chars, num_bs;

			case ECHO_OP_ERASE_TAB:
645 646
				if (MASK(ldata->echo_commit) == MASK(tail + 2))
					goto not_yet_stored;
647
				num_chars = echo_buf(ldata, tail + 2);
648 649 650 651 652 653 654 655 656 657 658 659

				/*
				 * Determine how many columns to go back
				 * in order to erase the tab.
				 * This depends on the number of columns
				 * used by other characters within the tab
				 * area.  If this (modulo 8) count is from
				 * the start of input rather than from a
				 * previous tab, we offset by canon column.
				 * Otherwise, tab spacing is normal.
				 */
				if (!(num_chars & 0x80))
660
					num_chars += ldata->canon_column;
661 662 663 664 665 666 667 668 669
				num_bs = 8 - (num_chars & 7);

				if (num_bs > space) {
					no_space_left = 1;
					break;
				}
				space -= num_bs;
				while (num_bs--) {
					tty_put_char(tty, '\b');
670 671
					if (ldata->column > 0)
						ldata->column--;
672
				}
673
				tail += 3;
674 675 676
				break;

			case ECHO_OP_SET_CANON_COL:
677
				ldata->canon_column = ldata->column;
678
				tail += 2;
679 680 681
				break;

			case ECHO_OP_MOVE_BACK_COL:
682 683
				if (ldata->column > 0)
					ldata->column--;
684
				tail += 2;
685 686 687 688 689 690 691 692 693
				break;

			case ECHO_OP_START:
				/* This is an escaped echo op start code */
				if (!space) {
					no_space_left = 1;
					break;
				}
				tty_put_char(tty, ECHO_OP_START);
694
				ldata->column++;
695
				space--;
696
				tail += 2;
697 698 699 700
				break;

			default:
				/*
701 702 703 704 705 706 707
				 * If the op is not a special byte code,
				 * it is a ctrl char tagged to be echoed
				 * as "^X" (where X is the letter
				 * representing the control char).
				 * Note that we must ensure there is
				 * enough space for the whole ctrl pair.
				 *
708
				 */
709 710 711 712 713 714
				if (space < 2) {
					no_space_left = 1;
					break;
				}
				tty_put_char(tty, '^');
				tty_put_char(tty, op ^ 0100);
715
				ldata->column += 2;
716
				space -= 2;
717
				tail += 2;
718 719 720 721 722
			}

			if (no_space_left)
				break;
		} else {
P
Peter Hurley 已提交
723
			if (O_OPOST(tty)) {
724 725 726 727 728 729 730 731 732 733
				int retval = do_output_char(c, tty, space);
				if (retval < 0)
					break;
				space -= retval;
			} else {
				if (!space)
					break;
				tty_put_char(tty, c);
				space -= 1;
			}
734
			tail += 1;
735 736 737
		}
	}

P
Peter Hurley 已提交
738 739 740
	/* If the echo buffer is nearly full (so that the possibility exists
	 * of echo overrun before the next commit), then discard enough
	 * data at the tail to prevent a subsequent overrun */
741 742
	while (ldata->echo_commit > tail &&
	       ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) {
743
		if (echo_buf(ldata, tail) == ECHO_OP_START) {
744
			if (echo_buf(ldata, tail + 1) == ECHO_OP_ERASE_TAB)
P
Peter Hurley 已提交
745 746 747 748 749 750 751
				tail += 3;
			else
				tail += 2;
		} else
			tail++;
	}

752
 not_yet_stored:
753
	ldata->echo_tail = tail;
754
	return old_space - space;
755 756 757 758 759
}

static void commit_echoes(struct tty_struct *tty)
{
	struct n_tty_data *ldata = tty->disc_data;
760
	size_t nr, old, echoed;
P
Peter Hurley 已提交
761 762
	size_t head;

763
	mutex_lock(&ldata->output_lock);
P
Peter Hurley 已提交
764
	head = ldata->echo_head;
765
	ldata->echo_mark = head;
P
Peter Hurley 已提交
766 767 768 769 770 771
	old = ldata->echo_commit - ldata->echo_tail;

	/* Process committed echoes if the accumulated # of bytes
	 * is over the threshold (and try again each time another
	 * block is accumulated) */
	nr = head - ldata->echo_tail;
772 773 774
	if (nr < ECHO_COMMIT_WATERMARK ||
	    (nr % ECHO_BLOCK > old % ECHO_BLOCK)) {
		mutex_unlock(&ldata->output_lock);
P
Peter Hurley 已提交
775
		return;
776
	}
777

P
Peter Hurley 已提交
778
	ldata->echo_commit = head;
779
	echoed = __process_echoes(tty);
780
	mutex_unlock(&ldata->output_lock);
781

782
	if (echoed && tty->ops->flush_chars)
783 784 785
		tty->ops->flush_chars(tty);
}

786
static void process_echoes(struct tty_struct *tty)
P
Peter Hurley 已提交
787 788
{
	struct n_tty_data *ldata = tty->disc_data;
789
	size_t echoed;
P
Peter Hurley 已提交
790

P
Peter Hurley 已提交
791
	if (ldata->echo_mark == ldata->echo_tail)
792 793 794
		return;

	mutex_lock(&ldata->output_lock);
795
	ldata->echo_commit = ldata->echo_mark;
796
	echoed = __process_echoes(tty);
797 798
	mutex_unlock(&ldata->output_lock);

799
	if (echoed && tty->ops->flush_chars)
800
		tty->ops->flush_chars(tty);
P
Peter Hurley 已提交
801 802
}

803
/* NB: echo_mark and echo_head should be equivalent here */
P
Peter Hurley 已提交
804 805 806 807
static void flush_echoes(struct tty_struct *tty)
{
	struct n_tty_data *ldata = tty->disc_data;

P
Peter Hurley 已提交
808 809
	if ((!L_ECHO(tty) && !L_ECHONL(tty)) ||
	    ldata->echo_commit == ldata->echo_head)
P
Peter Hurley 已提交
810 811 812 813 814 815 816 817
		return;

	mutex_lock(&ldata->output_lock);
	ldata->echo_commit = ldata->echo_head;
	__process_echoes(tty);
	mutex_unlock(&ldata->output_lock);
}

818 819 820
/**
 *	add_echo_byte	-	add a byte to the echo buffer
 *	@c: unicode byte to echo
J
Jiri Slaby 已提交
821
 *	@ldata: n_tty data
822 823 824 825
 *
 *	Add a character or operation byte to the echo buffer.
 */

P
Peter Hurley 已提交
826
static inline void add_echo_byte(unsigned char c, struct n_tty_data *ldata)
827
{
828 829 830
	*echo_buf_addr(ldata, ldata->echo_head) = c;
	smp_wmb(); /* Matches smp_rmb() in echo_buf(). */
	ldata->echo_head++;
831 832 833 834
}

/**
 *	echo_move_back_col	-	add operation to move back a column
J
Jiri Slaby 已提交
835
 *	@ldata: n_tty data
836 837 838 839
 *
 *	Add an operation to the echo buffer to move back one column.
 */

J
Jiri Slaby 已提交
840
static void echo_move_back_col(struct n_tty_data *ldata)
841
{
J
Jiri Slaby 已提交
842 843
	add_echo_byte(ECHO_OP_START, ldata);
	add_echo_byte(ECHO_OP_MOVE_BACK_COL, ldata);
844 845 846 847
}

/**
 *	echo_set_canon_col	-	add operation to set the canon column
J
Jiri Slaby 已提交
848
 *	@ldata: n_tty data
849 850 851 852 853
 *
 *	Add an operation to the echo buffer to set the canon column
 *	to the current column.
 */

J
Jiri Slaby 已提交
854
static void echo_set_canon_col(struct n_tty_data *ldata)
855
{
J
Jiri Slaby 已提交
856 857
	add_echo_byte(ECHO_OP_START, ldata);
	add_echo_byte(ECHO_OP_SET_CANON_COL, ldata);
858 859 860 861 862 863
}

/**
 *	echo_erase_tab	-	add operation to erase a tab
 *	@num_chars: number of character columns already used
 *	@after_tab: true if num_chars starts after a previous tab
J
Jiri Slaby 已提交
864
 *	@ldata: n_tty data
865 866 867 868 869 870 871 872 873 874 875
 *
 *	Add an operation to the echo buffer to erase a tab.
 *
 *	Called by the eraser function, which knows how many character
 *	columns have been used since either a previous tab or the start
 *	of input.  This information will be used later, along with
 *	canon column (if applicable), to go back the correct number
 *	of columns.
 */

static void echo_erase_tab(unsigned int num_chars, int after_tab,
J
Jiri Slaby 已提交
876
			   struct n_tty_data *ldata)
877
{
J
Jiri Slaby 已提交
878 879
	add_echo_byte(ECHO_OP_START, ldata);
	add_echo_byte(ECHO_OP_ERASE_TAB, ldata);
880 881 882 883 884 885 886

	/* We only need to know this modulo 8 (tab spacing) */
	num_chars &= 7;

	/* Set the high bit as a flag if num_chars is after a previous tab */
	if (after_tab)
		num_chars |= 0x80;
A
Alan Cox 已提交
887

J
Jiri Slaby 已提交
888
	add_echo_byte(num_chars, ldata);
889 890 891 892 893 894 895 896 897 898 899 900 901
}

/**
 *	echo_char_raw	-	echo a character raw
 *	@c: unicode byte to echo
 *	@tty: terminal device
 *
 *	Echo user input back onto the screen. This must be called only when
 *	L_ECHO(tty) is true. Called from the driver receive_buf path.
 *
 *	This variant does not treat control characters specially.
 */

J
Jiri Slaby 已提交
902
static void echo_char_raw(unsigned char c, struct n_tty_data *ldata)
903 904
{
	if (c == ECHO_OP_START) {
J
Jiri Slaby 已提交
905 906
		add_echo_byte(ECHO_OP_START, ldata);
		add_echo_byte(ECHO_OP_START, ldata);
907
	} else {
J
Jiri Slaby 已提交
908
		add_echo_byte(c, ldata);
909 910
	}
}
L
Linus Torvalds 已提交
911 912

/**
913
 *	echo_char	-	echo a character
L
Linus Torvalds 已提交
914 915 916
 *	@c: unicode byte to echo
 *	@tty: terminal device
 *
917
 *	Echo user input back onto the screen. This must be called only when
L
Linus Torvalds 已提交
918
 *	L_ECHO(tty) is true. Called from the driver receive_buf path.
919
 *
920 921
 *	This variant tags control characters to be echoed as "^X"
 *	(where X is the letter representing the control char).
L
Linus Torvalds 已提交
922 923 924 925
 */

static void echo_char(unsigned char c, struct tty_struct *tty)
{
926 927
	struct n_tty_data *ldata = tty->disc_data;

928
	if (c == ECHO_OP_START) {
J
Jiri Slaby 已提交
929 930
		add_echo_byte(ECHO_OP_START, ldata);
		add_echo_byte(ECHO_OP_START, ldata);
931
	} else {
932
		if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
J
Jiri Slaby 已提交
933 934
			add_echo_byte(ECHO_OP_START, ldata);
		add_echo_byte(c, ldata);
935
	}
L
Linus Torvalds 已提交
936 937
}

938
/**
939
 *	finish_erasing		-	complete erase
J
Jiri Slaby 已提交
940
 *	@ldata: n_tty data
941
 */
942

J
Jiri Slaby 已提交
943
static inline void finish_erasing(struct n_tty_data *ldata)
L
Linus Torvalds 已提交
944
{
945
	if (ldata->erasing) {
J
Jiri Slaby 已提交
946
		echo_char_raw('/', ldata);
947
		ldata->erasing = 0;
L
Linus Torvalds 已提交
948 949 950 951 952 953 954 955
	}
}

/**
 *	eraser		-	handle erase function
 *	@c: character input
 *	@tty: terminal device
 *
956
 *	Perform erase and necessary output when an erase character is
L
Linus Torvalds 已提交
957 958
 *	present in the stream from the driver layer. Handles the complexities
 *	of UTF-8 multibyte symbols.
959
 *
960 961
 *	n_tty_receive_buf()/producer path:
 *		caller holds non-exclusive termios_rwsem
L
Linus Torvalds 已提交
962
 */
963

L
Linus Torvalds 已提交
964 965
static void eraser(unsigned char c, struct tty_struct *tty)
{
966
	struct n_tty_data *ldata = tty->disc_data;
L
Linus Torvalds 已提交
967
	enum { ERASE, WERASE, KILL } kill_type;
968 969 970
	size_t head;
	size_t cnt;
	int seen_alnums;
L
Linus Torvalds 已提交
971

972
	if (ldata->read_head == ldata->canon_head) {
973
		/* process_output('\a', tty); */ /* what do you think? */
L
Linus Torvalds 已提交
974 975 976 977 978 979 980 981
		return;
	}
	if (c == ERASE_CHAR(tty))
		kill_type = ERASE;
	else if (c == WERASE_CHAR(tty))
		kill_type = WERASE;
	else {
		if (!L_ECHO(tty)) {
982
			ldata->read_head = ldata->canon_head;
L
Linus Torvalds 已提交
983 984 985
			return;
		}
		if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
986
			ldata->read_head = ldata->canon_head;
J
Jiri Slaby 已提交
987
			finish_erasing(ldata);
L
Linus Torvalds 已提交
988 989 990
			echo_char(KILL_CHAR(tty), tty);
			/* Add a newline if ECHOK is on and ECHOKE is off. */
			if (L_ECHOK(tty))
J
Jiri Slaby 已提交
991
				echo_char_raw('\n', ldata);
L
Linus Torvalds 已提交
992 993 994 995 996 997
			return;
		}
		kill_type = KILL;
	}

	seen_alnums = 0;
998
	while (MASK(ldata->read_head) != MASK(ldata->canon_head)) {
999
		head = ldata->read_head;
L
Linus Torvalds 已提交
1000 1001 1002

		/* erase a single possibly multibyte character */
		do {
1003 1004
			head--;
			c = read_buf(ldata, head);
1005 1006
		} while (is_continuation(c, tty) &&
			 MASK(head) != MASK(ldata->canon_head));
L
Linus Torvalds 已提交
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018

		/* do not partially erase */
		if (is_continuation(c, tty))
			break;

		if (kill_type == WERASE) {
			/* Equivalent to BSD's ALTWERASE. */
			if (isalnum(c) || c == '_')
				seen_alnums++;
			else if (seen_alnums)
				break;
		}
1019
		cnt = ldata->read_head - head;
1020
		ldata->read_head = head;
L
Linus Torvalds 已提交
1021 1022
		if (L_ECHO(tty)) {
			if (L_ECHOPRT(tty)) {
1023
				if (!ldata->erasing) {
J
Jiri Slaby 已提交
1024
					echo_char_raw('\\', ldata);
1025
					ldata->erasing = 1;
L
Linus Torvalds 已提交
1026 1027 1028 1029
				}
				/* if cnt > 1, output a multi-byte character */
				echo_char(c, tty);
				while (--cnt > 0) {
1030 1031
					head++;
					echo_char_raw(read_buf(ldata, head), ldata);
J
Jiri Slaby 已提交
1032
					echo_move_back_col(ldata);
L
Linus Torvalds 已提交
1033 1034 1035 1036
				}
			} else if (kill_type == ERASE && !L_ECHOE(tty)) {
				echo_char(ERASE_CHAR(tty), tty);
			} else if (c == '\t') {
1037 1038
				unsigned int num_chars = 0;
				int after_tab = 0;
1039
				size_t tail = ldata->read_head;
1040 1041 1042 1043 1044 1045 1046 1047

				/*
				 * Count the columns used for characters
				 * since the start of input or after a
				 * previous tab.
				 * This info is used to go back the correct
				 * number of columns.
				 */
1048
				while (MASK(tail) != MASK(ldata->canon_head)) {
1049 1050
					tail--;
					c = read_buf(ldata, tail);
1051 1052 1053
					if (c == '\t') {
						after_tab = 1;
						break;
A
Alan Cox 已提交
1054
					} else if (iscntrl(c)) {
L
Linus Torvalds 已提交
1055
						if (L_ECHOCTL(tty))
1056 1057 1058 1059
							num_chars += 2;
					} else if (!is_continuation(c, tty)) {
						num_chars++;
					}
L
Linus Torvalds 已提交
1060
				}
J
Jiri Slaby 已提交
1061
				echo_erase_tab(num_chars, after_tab, ldata);
L
Linus Torvalds 已提交
1062 1063
			} else {
				if (iscntrl(c) && L_ECHOCTL(tty)) {
J
Jiri Slaby 已提交
1064 1065 1066
					echo_char_raw('\b', ldata);
					echo_char_raw(' ', ldata);
					echo_char_raw('\b', ldata);
L
Linus Torvalds 已提交
1067 1068
				}
				if (!iscntrl(c) || L_ECHOCTL(tty)) {
J
Jiri Slaby 已提交
1069 1070 1071
					echo_char_raw('\b', ldata);
					echo_char_raw(' ', ldata);
					echo_char_raw('\b', ldata);
L
Linus Torvalds 已提交
1072 1073 1074 1075 1076 1077
				}
			}
		}
		if (kill_type == ERASE)
			break;
	}
1078
	if (ldata->read_head == ldata->canon_head && L_ECHO(tty))
J
Jiri Slaby 已提交
1079
		finish_erasing(ldata);
L
Linus Torvalds 已提交
1080 1081 1082 1083 1084 1085 1086
}

/**
 *	isig		-	handle the ISIG optio
 *	@sig: signal
 *	@tty: terminal
 *
1087 1088
 *	Called when a signal is being sent due to terminal input.
 *	Called from the driver receive_buf path so serialized.
1089
 *
1090 1091 1092 1093
 *	Performs input and output flush if !NOFLSH. In this context, the echo
 *	buffer is 'output'. The signal is processed first to alert any current
 *	readers or writers to discontinue and exit their i/o loops.
 *
1094
 *	Locking: ctrl_lock
L
Linus Torvalds 已提交
1095
 */
1096

1097
static void __isig(int sig, struct tty_struct *tty)
L
Linus Torvalds 已提交
1098
{
1099 1100 1101 1102
	struct pid *tty_pgrp = tty_get_pgrp(tty);
	if (tty_pgrp) {
		kill_pgrp(tty_pgrp, sig, 1);
		put_pid(tty_pgrp);
L
Linus Torvalds 已提交
1103
	}
1104
}
1105

1106 1107 1108 1109 1110 1111 1112 1113 1114
static void isig(int sig, struct tty_struct *tty)
{
	struct n_tty_data *ldata = tty->disc_data;

	if (L_NOFLSH(tty)) {
		/* signal only */
		__isig(sig, tty);

	} else { /* signal and flush */
1115 1116 1117
		up_read(&tty->termios_rwsem);
		down_write(&tty->termios_rwsem);

1118 1119
		__isig(sig, tty);

1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
		/* clear echo buffer */
		mutex_lock(&ldata->output_lock);
		ldata->echo_head = ldata->echo_tail = 0;
		ldata->echo_mark = ldata->echo_commit = 0;
		mutex_unlock(&ldata->output_lock);

		/* clear output buffer */
		tty_driver_flush_buffer(tty);

		/* clear input buffer */
		reset_buffer_flags(tty->disc_data);

		/* notify pty master of flush */
		if (tty->link)
			n_tty_packet_mode_flush(tty);

		up_write(&tty->termios_rwsem);
		down_read(&tty->termios_rwsem);
	}
L
Linus Torvalds 已提交
1139 1140 1141 1142 1143 1144 1145 1146 1147
}

/**
 *	n_tty_receive_break	-	handle break
 *	@tty: terminal
 *
 *	An RS232 break event has been hit in the incoming bitstream. This
 *	can cause a variety of events depending upon the termios settings.
 *
1148 1149 1150 1151
 *	n_tty_receive_buf()/producer path:
 *		caller holds non-exclusive termios_rwsem
 *
 *	Note: may get exclusive termios_rwsem if flushing input buffer
L
Linus Torvalds 已提交
1152
 */
1153

1154
static void n_tty_receive_break(struct tty_struct *tty)
L
Linus Torvalds 已提交
1155
{
J
Jiri Slaby 已提交
1156 1157
	struct n_tty_data *ldata = tty->disc_data;

L
Linus Torvalds 已提交
1158 1159 1160
	if (I_IGNBRK(tty))
		return;
	if (I_BRKINT(tty)) {
1161
		isig(SIGINT, tty);
L
Linus Torvalds 已提交
1162 1163 1164
		return;
	}
	if (I_PARMRK(tty)) {
J
Jiri Slaby 已提交
1165 1166
		put_tty_queue('\377', ldata);
		put_tty_queue('\0', ldata);
L
Linus Torvalds 已提交
1167
	}
J
Jiri Slaby 已提交
1168
	put_tty_queue('\0', ldata);
L
Linus Torvalds 已提交
1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
}

/**
 *	n_tty_receive_overrun	-	handle overrun reporting
 *	@tty: terminal
 *
 *	Data arrived faster than we could process it. While the tty
 *	driver has flagged this the bits that were missed are gone
 *	forever.
 *
 *	Called from the receive_buf path so single threaded. Does not
 *	need locking as num_overrun and overrun_time are function
 *	private.
 */
1183

1184
static void n_tty_receive_overrun(struct tty_struct *tty)
L
Linus Torvalds 已提交
1185
{
1186
	struct n_tty_data *ldata = tty->disc_data;
L
Linus Torvalds 已提交
1187

1188 1189 1190
	ldata->num_overrun++;
	if (time_after(jiffies, ldata->overrun_time + HZ) ||
			time_after(ldata->overrun_time, jiffies)) {
P
Peter Hurley 已提交
1191
		tty_warn(tty, "%d input overrun(s)\n", ldata->num_overrun);
1192 1193
		ldata->overrun_time = jiffies;
		ldata->num_overrun = 0;
L
Linus Torvalds 已提交
1194 1195 1196 1197 1198 1199 1200 1201 1202
	}
}

/**
 *	n_tty_receive_parity_error	-	error notifier
 *	@tty: terminal device
 *	@c: character
 *
 *	Process a parity error and queue the right data to indicate
1203 1204 1205 1206
 *	the error case if necessary.
 *
 *	n_tty_receive_buf()/producer path:
 *		caller holds non-exclusive termios_rwsem
L
Linus Torvalds 已提交
1207
 */
1208
static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c)
L
Linus Torvalds 已提交
1209
{
J
Jiri Slaby 已提交
1210 1211
	struct n_tty_data *ldata = tty->disc_data;

P
Peter Hurley 已提交
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
	if (I_INPCK(tty)) {
		if (I_IGNPAR(tty))
			return;
		if (I_PARMRK(tty)) {
			put_tty_queue('\377', ldata);
			put_tty_queue('\0', ldata);
			put_tty_queue(c, ldata);
		} else
			put_tty_queue('\0', ldata);
	} else
J
Jiri Slaby 已提交
1222
		put_tty_queue(c, ldata);
L
Linus Torvalds 已提交
1223 1224
}

1225 1226 1227
static void
n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c)
{
1228
	isig(signal, tty);
1229 1230 1231 1232 1233
	if (I_IXON(tty))
		start_tty(tty);
	if (L_ECHO(tty)) {
		echo_char(c, tty);
		commit_echoes(tty);
P
Peter Hurley 已提交
1234 1235
	} else
		process_echoes(tty);
1236 1237 1238
	return;
}

L
Linus Torvalds 已提交
1239 1240 1241 1242 1243 1244
/**
 *	n_tty_receive_char	-	perform processing
 *	@tty: terminal device
 *	@c: character
 *
 *	Process an individual character of input received from the driver.
1245
 *	This is serialized with respect to itself by the rules for the
L
Linus Torvalds 已提交
1246
 *	driver above.
1247 1248 1249 1250
 *
 *	n_tty_receive_buf()/producer path:
 *		caller holds non-exclusive termios_rwsem
 *		publishes canon_head if canonical mode is active
1251 1252
 *
 *	Returns 1 if LNEXT was received, else returns 0
L
Linus Torvalds 已提交
1253 1254
 */

1255
static int
P
Peter Hurley 已提交
1256
n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
L
Linus Torvalds 已提交
1257
{
1258
	struct n_tty_data *ldata = tty->disc_data;
L
Linus Torvalds 已提交
1259 1260 1261 1262

	if (I_IXON(tty)) {
		if (c == START_CHAR(tty)) {
			start_tty(tty);
P
Peter Hurley 已提交
1263
			process_echoes(tty);
1264
			return 0;
L
Linus Torvalds 已提交
1265 1266 1267
		}
		if (c == STOP_CHAR(tty)) {
			stop_tty(tty);
1268
			return 0;
L
Linus Torvalds 已提交
1269 1270
		}
	}
1271

L
Linus Torvalds 已提交
1272
	if (L_ISIG(tty)) {
1273 1274
		if (c == INTR_CHAR(tty)) {
			n_tty_receive_signal_char(tty, SIGINT, c);
1275
			return 0;
1276 1277
		} else if (c == QUIT_CHAR(tty)) {
			n_tty_receive_signal_char(tty, SIGQUIT, c);
1278
			return 0;
1279 1280
		} else if (c == SUSP_CHAR(tty)) {
			n_tty_receive_signal_char(tty, SIGTSTP, c);
1281
			return 0;
L
Linus Torvalds 已提交
1282 1283
		}
	}
1284

1285 1286 1287 1288 1289
	if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty)) {
		start_tty(tty);
		process_echoes(tty);
	}

1290 1291
	if (c == '\r') {
		if (I_IGNCR(tty))
1292
			return 0;
1293 1294 1295 1296 1297
		if (I_ICRNL(tty))
			c = '\n';
	} else if (c == '\n' && I_INLCR(tty))
		c = '\r';

1298
	if (ldata->icanon) {
L
Linus Torvalds 已提交
1299 1300 1301
		if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
		    (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
			eraser(c, tty);
P
Peter Hurley 已提交
1302
			commit_echoes(tty);
1303
			return 0;
L
Linus Torvalds 已提交
1304 1305
		}
		if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
1306
			ldata->lnext = 1;
L
Linus Torvalds 已提交
1307
			if (L_ECHO(tty)) {
J
Jiri Slaby 已提交
1308
				finish_erasing(ldata);
L
Linus Torvalds 已提交
1309
				if (L_ECHOCTL(tty)) {
J
Jiri Slaby 已提交
1310 1311
					echo_char_raw('^', ldata);
					echo_char_raw('\b', ldata);
P
Peter Hurley 已提交
1312
					commit_echoes(tty);
L
Linus Torvalds 已提交
1313 1314
				}
			}
1315
			return 1;
L
Linus Torvalds 已提交
1316
		}
1317
		if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && L_IEXTEN(tty)) {
1318
			size_t tail = ldata->canon_head;
L
Linus Torvalds 已提交
1319

J
Jiri Slaby 已提交
1320
			finish_erasing(ldata);
L
Linus Torvalds 已提交
1321
			echo_char(c, tty);
J
Jiri Slaby 已提交
1322
			echo_char_raw('\n', ldata);
1323
			while (MASK(tail) != MASK(ldata->read_head)) {
1324 1325
				echo_char(read_buf(ldata, tail), tty);
				tail++;
L
Linus Torvalds 已提交
1326
			}
P
Peter Hurley 已提交
1327
			commit_echoes(tty);
1328
			return 0;
L
Linus Torvalds 已提交
1329 1330
		}
		if (c == '\n') {
1331
			if (L_ECHO(tty) || L_ECHONL(tty)) {
J
Jiri Slaby 已提交
1332
				echo_char_raw('\n', ldata);
P
Peter Hurley 已提交
1333
				commit_echoes(tty);
L
Linus Torvalds 已提交
1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
			}
			goto handle_newline;
		}
		if (c == EOF_CHAR(tty)) {
			c = __DISABLED_CHAR;
			goto handle_newline;
		}
		if ((c == EOL_CHAR(tty)) ||
		    (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
			/*
			 * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
			 */
			if (L_ECHO(tty)) {
				/* Record the column of first canon char. */
1348
				if (ldata->canon_head == ldata->read_head)
J
Jiri Slaby 已提交
1349
					echo_set_canon_col(ldata);
L
Linus Torvalds 已提交
1350
				echo_char(c, tty);
P
Peter Hurley 已提交
1351
				commit_echoes(tty);
L
Linus Torvalds 已提交
1352 1353 1354 1355 1356
			}
			/*
			 * XXX does PARMRK doubling happen for
			 * EOL_CHAR and EOL2_CHAR?
			 */
1357
			if (c == (unsigned char) '\377' && I_PARMRK(tty))
J
Jiri Slaby 已提交
1358
				put_tty_queue(c, ldata);
L
Linus Torvalds 已提交
1359

1360
handle_newline:
1361
			set_bit(ldata->read_head & (N_TTY_BUF_SIZE - 1), ldata->read_flags);
1362
			put_tty_queue(c, ldata);
1363
			smp_store_release(&ldata->canon_head, ldata->read_head);
L
Linus Torvalds 已提交
1364
			kill_fasync(&tty->fasync, SIGIO, POLL_IN);
1365
			wake_up_interruptible_poll(&tty->read_wait, EPOLLIN);
1366
			return 0;
L
Linus Torvalds 已提交
1367 1368
		}
	}
1369

1370
	if (L_ECHO(tty)) {
J
Jiri Slaby 已提交
1371
		finish_erasing(ldata);
L
Linus Torvalds 已提交
1372
		if (c == '\n')
J
Jiri Slaby 已提交
1373
			echo_char_raw('\n', ldata);
L
Linus Torvalds 已提交
1374 1375
		else {
			/* Record the column of first canon char. */
1376
			if (ldata->canon_head == ldata->read_head)
J
Jiri Slaby 已提交
1377
				echo_set_canon_col(ldata);
L
Linus Torvalds 已提交
1378 1379
			echo_char(c, tty);
		}
P
Peter Hurley 已提交
1380
		commit_echoes(tty);
L
Linus Torvalds 已提交
1381 1382
	}

1383 1384
	/* PARMRK doubling check */
	if (c == (unsigned char) '\377' && I_PARMRK(tty))
J
Jiri Slaby 已提交
1385
		put_tty_queue(c, ldata);
L
Linus Torvalds 已提交
1386

J
Jiri Slaby 已提交
1387
	put_tty_queue(c, ldata);
1388
	return 0;
1389
}
L
Linus Torvalds 已提交
1390

1391 1392
static inline void
n_tty_receive_char_inline(struct tty_struct *tty, unsigned char c)
P
Peter Hurley 已提交
1393 1394 1395
{
	struct n_tty_data *ldata = tty->disc_data;

1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406
	if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty)) {
		start_tty(tty);
		process_echoes(tty);
	}
	if (L_ECHO(tty)) {
		finish_erasing(ldata);
		/* Record the column of first canon char. */
		if (ldata->canon_head == ldata->read_head)
			echo_set_canon_col(ldata);
		echo_char(c, tty);
		commit_echoes(tty);
P
Peter Hurley 已提交
1407
	}
1408 1409
	/* PARMRK doubling check */
	if (c == (unsigned char) '\377' && I_PARMRK(tty))
1410 1411 1412
		put_tty_queue(c, ldata);
	put_tty_queue(c, ldata);
}
P
Peter Hurley 已提交
1413

1414
static void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
1415 1416
{
	n_tty_receive_char_inline(tty, c);
P
Peter Hurley 已提交
1417 1418
}

1419 1420 1421 1422 1423
static inline void
n_tty_receive_char_fast(struct tty_struct *tty, unsigned char c)
{
	struct n_tty_data *ldata = tty->disc_data;

1424 1425 1426
	if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty)) {
		start_tty(tty);
		process_echoes(tty);
1427
	}
1428 1429 1430 1431 1432 1433 1434 1435 1436
	if (L_ECHO(tty)) {
		finish_erasing(ldata);
		/* Record the column of first canon char. */
		if (ldata->canon_head == ldata->read_head)
			echo_set_canon_col(ldata);
		echo_char(c, tty);
		commit_echoes(tty);
	}
	put_tty_queue(c, ldata);
1437 1438
}

1439
static void n_tty_receive_char_closing(struct tty_struct *tty, unsigned char c)
1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458
{
	if (I_ISTRIP(tty))
		c &= 0x7f;
	if (I_IUCLC(tty) && L_IEXTEN(tty))
		c = tolower(c);

	if (I_IXON(tty)) {
		if (c == STOP_CHAR(tty))
			stop_tty(tty);
		else if (c == START_CHAR(tty) ||
			 (tty->stopped && !tty->flow_stopped && I_IXANY(tty) &&
			  c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) &&
			  c != SUSP_CHAR(tty))) {
			start_tty(tty);
			process_echoes(tty);
		}
	}
}

1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473
static void
n_tty_receive_char_flagged(struct tty_struct *tty, unsigned char c, char flag)
{
	switch (flag) {
	case TTY_BREAK:
		n_tty_receive_break(tty);
		break;
	case TTY_PARITY:
	case TTY_FRAME:
		n_tty_receive_parity_error(tty, c);
		break;
	case TTY_OVERRUN:
		n_tty_receive_overrun(tty);
		break;
	default:
P
Peter Hurley 已提交
1474
		tty_err(tty, "unknown flag %d\n", flag);
1475 1476 1477 1478
		break;
	}
}

1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494
static void
n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag)
{
	struct n_tty_data *ldata = tty->disc_data;

	ldata->lnext = 0;
	if (likely(flag == TTY_NORMAL)) {
		if (I_ISTRIP(tty))
			c &= 0x7f;
		if (I_IUCLC(tty) && L_IEXTEN(tty))
			c = tolower(c);
		n_tty_receive_char(tty, c);
	} else
		n_tty_receive_char_flagged(tty, c, flag);
}

1495 1496 1497 1498 1499 1500 1501 1502
static void
n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp,
			   char *fp, int count)
{
	struct n_tty_data *ldata = tty->disc_data;
	size_t n, head;

	head = ldata->read_head & (N_TTY_BUF_SIZE - 1);
1503
	n = min_t(size_t, count, N_TTY_BUF_SIZE - head);
1504 1505 1506 1507 1508 1509
	memcpy(read_buf_addr(ldata, head), cp, n);
	ldata->read_head += n;
	cp += n;
	count -= n;

	head = ldata->read_head & (N_TTY_BUF_SIZE - 1);
1510
	n = min_t(size_t, count, N_TTY_BUF_SIZE - head);
1511 1512 1513 1514
	memcpy(read_buf_addr(ldata, head), cp, n);
	ldata->read_head += n;
}

1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531
static void
n_tty_receive_buf_raw(struct tty_struct *tty, const unsigned char *cp,
		      char *fp, int count)
{
	struct n_tty_data *ldata = tty->disc_data;
	char flag = TTY_NORMAL;

	while (count--) {
		if (fp)
			flag = *fp++;
		if (likely(flag == TTY_NORMAL))
			put_tty_queue(*cp++, ldata);
		else
			n_tty_receive_char_flagged(tty, *cp++, flag);
	}
}

1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545
static void
n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp,
			  char *fp, int count)
{
	char flag = TTY_NORMAL;

	while (count--) {
		if (fp)
			flag = *fp++;
		if (likely(flag == TTY_NORMAL))
			n_tty_receive_char_closing(tty, *cp++);
	}
}

1546 1547
static void
n_tty_receive_buf_standard(struct tty_struct *tty, const unsigned char *cp,
1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566
			  char *fp, int count)
{
	struct n_tty_data *ldata = tty->disc_data;
	char flag = TTY_NORMAL;

	while (count--) {
		if (fp)
			flag = *fp++;
		if (likely(flag == TTY_NORMAL)) {
			unsigned char c = *cp++;

			if (I_ISTRIP(tty))
				c &= 0x7f;
			if (I_IUCLC(tty) && L_IEXTEN(tty))
				c = tolower(c);
			if (L_EXTPROC(tty)) {
				put_tty_queue(c, ldata);
				continue;
			}
1567 1568 1569 1570 1571 1572 1573 1574
			if (!test_bit(c, ldata->char_map))
				n_tty_receive_char_inline(tty, c);
			else if (n_tty_receive_char_special(tty, c) && count) {
				if (fp)
					flag = *fp++;
				n_tty_receive_char_lnext(tty, *cp++, flag);
				count--;
			}
1575 1576 1577 1578 1579 1580 1581 1582
		} else
			n_tty_receive_char_flagged(tty, *cp++, flag);
	}
}

static void
n_tty_receive_buf_fast(struct tty_struct *tty, const unsigned char *cp,
		       char *fp, int count)
1583
{
1584
	struct n_tty_data *ldata = tty->disc_data;
1585 1586 1587 1588 1589
	char flag = TTY_NORMAL;

	while (count--) {
		if (fp)
			flag = *fp++;
1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601
		if (likely(flag == TTY_NORMAL)) {
			unsigned char c = *cp++;

			if (!test_bit(c, ldata->char_map))
				n_tty_receive_char_fast(tty, c);
			else if (n_tty_receive_char_special(tty, c) && count) {
				if (fp)
					flag = *fp++;
				n_tty_receive_char_lnext(tty, *cp++, flag);
				count--;
			}
		} else
1602 1603 1604 1605
			n_tty_receive_char_flagged(tty, *cp++, flag);
	}
}

1606 1607
static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
			  char *fp, int count)
L
Linus Torvalds 已提交
1608
{
1609
	struct n_tty_data *ldata = tty->disc_data;
1610
	bool preops = I_ISTRIP(tty) || (I_IUCLC(tty) && L_IEXTEN(tty));
L
Linus Torvalds 已提交
1611

1612 1613
	if (ldata->real_raw)
		n_tty_receive_buf_real_raw(tty, cp, fp, count);
1614
	else if (ldata->raw || (L_EXTPROC(tty) && !preops))
1615
		n_tty_receive_buf_raw(tty, cp, fp, count);
1616 1617
	else if (tty->closing && !L_EXTPROC(tty))
		n_tty_receive_buf_closing(tty, cp, fp, count);
1618
	else {
1619 1620 1621 1622 1623 1624 1625 1626 1627
		if (ldata->lnext) {
			char flag = TTY_NORMAL;

			if (fp)
				flag = *fp++;
			n_tty_receive_char_lnext(tty, *cp++, flag);
			count--;
		}

1628
		if (!preops && !I_PARMRK(tty))
1629 1630 1631
			n_tty_receive_buf_fast(tty, cp, fp, count);
		else
			n_tty_receive_buf_standard(tty, cp, fp, count);
P
Peter Hurley 已提交
1632 1633

		flush_echoes(tty);
A
Alan Cox 已提交
1634 1635
		if (tty->ops->flush_chars)
			tty->ops->flush_chars(tty);
L
Linus Torvalds 已提交
1636 1637
	}

1638 1639 1640 1641 1642 1643
	if (ldata->icanon && !L_EXTPROC(tty))
		return;

	/* publish read_head to consumer */
	smp_store_release(&ldata->commit_head, ldata->read_head);

1644
	if (read_cnt(ldata)) {
L
Linus Torvalds 已提交
1645
		kill_fasync(&tty->fasync, SIGIO, POLL_IN);
1646
		wake_up_interruptible_poll(&tty->read_wait, EPOLLIN);
L
Linus Torvalds 已提交
1647 1648 1649
	}
}

1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682
/**
 *	n_tty_receive_buf_common	-	process input
 *	@tty: device to receive input
 *	@cp: input chars
 *	@fp: flags for each char (if NULL, all chars are TTY_NORMAL)
 *	@count: number of input chars in @cp
 *
 *	Called by the terminal driver when a block of characters has
 *	been received. This function must be called from soft contexts
 *	not from interrupt context. The driver is responsible for making
 *	calls one at a time and in order (or using flush_to_ldisc)
 *
 *	Returns the # of input chars from @cp which were processed.
 *
 *	In canonical mode, the maximum line length is 4096 chars (including
 *	the line termination char); lines longer than 4096 chars are
 *	truncated. After 4095 chars, input data is still processed but
 *	not stored. Overflow processing ensures the tty can always
 *	receive more input until at least one line can be read.
 *
 *	In non-canonical mode, the read buffer will only accept 4095 chars;
 *	this provides the necessary space for a newline char if the input
 *	mode is switched to canonical.
 *
 *	Note it is possible for the read buffer to _contain_ 4096 chars
 *	in non-canonical mode: the read buffer could already contain the
 *	maximum canon line of 4096 chars when the mode is switched to
 *	non-canonical.
 *
 *	n_tty_receive_buf()/producer path:
 *		claims non-exclusive termios_rwsem
 *		publishes commit_head or canon_head
 */
P
Peter Hurley 已提交
1683 1684 1685
static int
n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
			 char *fp, int count, int flow)
1686 1687
{
	struct n_tty_data *ldata = tty->disc_data;
1688
	int room, n, rcvd = 0, overflow;
1689

1690 1691
	down_read(&tty->termios_rwsem);

1692
	while (1) {
1693
		/*
P
Peter Hurley 已提交
1694 1695
		 * When PARMRK is set, each input char may take up to 3 chars
		 * in the read buf; reduce the buffer space avail by 3x
1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707
		 *
		 * If we are doing input canonicalization, and there are no
		 * pending newlines, let characters through without limit, so
		 * that erase characters will be handled.  Other excess
		 * characters will be beeped.
		 *
		 * paired with store in *_copy_from_read_buf() -- guarantees
		 * the consumer has loaded the data in read_buf up to the new
		 * read_tail (so this producer will not overwrite unread data)
		 */
		size_t tail = smp_load_acquire(&ldata->read_tail);

1708
		room = N_TTY_BUF_SIZE - (ldata->read_head - tail);
1709
		if (I_PARMRK(tty))
1710 1711 1712 1713 1714 1715 1716 1717 1718 1719
			room = (room + 2) / 3;
		room--;
		if (room <= 0) {
			overflow = ldata->icanon && ldata->canon_head == tail;
			if (overflow && room < 0)
				ldata->read_head--;
			room = overflow;
			ldata->no_room = flow && !room;
		} else
			overflow = 0;
1720

1721
		n = min(count, room);
1722
		if (!n)
1723
			break;
1724 1725 1726 1727 1728

		/* ignore parity errors if handling overflow */
		if (!overflow || !fp || *fp != TTY_PARITY)
			__receive_buf(tty, cp, fp, n);

1729 1730 1731 1732 1733
		cp += n;
		if (fp)
			fp += n;
		count -= n;
		rcvd += n;
1734
	}
1735

1736
	tty->receive_room = room;
1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747

	/* Unthrottle if handling overflow on pty */
	if (tty->driver->type == TTY_DRIVER_TYPE_PTY) {
		if (overflow) {
			tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE);
			tty_unthrottle_safe(tty);
			__tty_set_flow_change(tty, 0);
		}
	} else
		n_tty_check_throttle(tty);

1748 1749
	up_read(&tty->termios_rwsem);

1750
	return rcvd;
1751 1752
}

P
Peter Hurley 已提交
1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
			      char *fp, int count)
{
	n_tty_receive_buf_common(tty, cp, fp, count, 0);
}

static int n_tty_receive_buf2(struct tty_struct *tty, const unsigned char *cp,
			      char *fp, int count)
{
	return n_tty_receive_buf_common(tty, cp, fp, count, 1);
}

L
Linus Torvalds 已提交
1765 1766 1767 1768 1769 1770 1771
/**
 *	n_tty_set_termios	-	termios data changed
 *	@tty: terminal
 *	@old: previous data
 *
 *	Called by the tty layer when the user changes termios flags so
 *	that the line discipline can plan ahead. This function cannot sleep
1772
 *	and is protected from re-entry by the tty layer. The user is
L
Linus Torvalds 已提交
1773 1774
 *	guaranteed that this function will not be re-entered or in progress
 *	when the ldisc is closed.
1775
 *
1776
 *	Locking: Caller holds tty->termios_rwsem
L
Linus Torvalds 已提交
1777
 */
1778 1779

static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
L
Linus Torvalds 已提交
1780
{
1781
	struct n_tty_data *ldata = tty->disc_data;
1782

1783
	if (!old || (old->c_lflag ^ tty->termios.c_lflag) & (ICANON | EXTPROC)) {
1784
		bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
1785 1786 1787 1788 1789 1790 1791 1792 1793 1794
		ldata->line_start = ldata->read_tail;
		if (!L_ICANON(tty) || !read_cnt(ldata)) {
			ldata->canon_head = ldata->read_tail;
			ldata->push = 0;
		} else {
			set_bit((ldata->read_head - 1) & (N_TTY_BUF_SIZE - 1),
				ldata->read_flags);
			ldata->canon_head = ldata->read_head;
			ldata->push = 1;
		}
1795
		ldata->commit_head = ldata->read_head;
1796
		ldata->erasing = 0;
1797
		ldata->lnext = 0;
1798 1799
	}

1800
	ldata->icanon = (L_ICANON(tty) != 0);
P
Peter Hurley 已提交
1801

L
Linus Torvalds 已提交
1802 1803 1804 1805
	if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
	    I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
	    I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
	    I_PARMRK(tty)) {
1806
		bitmap_zero(ldata->char_map, 256);
L
Linus Torvalds 已提交
1807 1808

		if (I_IGNCR(tty) || I_ICRNL(tty))
1809
			set_bit('\r', ldata->char_map);
L
Linus Torvalds 已提交
1810
		if (I_INLCR(tty))
1811
			set_bit('\n', ldata->char_map);
L
Linus Torvalds 已提交
1812 1813

		if (L_ICANON(tty)) {
1814 1815 1816 1817 1818
			set_bit(ERASE_CHAR(tty), ldata->char_map);
			set_bit(KILL_CHAR(tty), ldata->char_map);
			set_bit(EOF_CHAR(tty), ldata->char_map);
			set_bit('\n', ldata->char_map);
			set_bit(EOL_CHAR(tty), ldata->char_map);
L
Linus Torvalds 已提交
1819
			if (L_IEXTEN(tty)) {
1820 1821 1822
				set_bit(WERASE_CHAR(tty), ldata->char_map);
				set_bit(LNEXT_CHAR(tty), ldata->char_map);
				set_bit(EOL2_CHAR(tty), ldata->char_map);
L
Linus Torvalds 已提交
1823 1824
				if (L_ECHO(tty))
					set_bit(REPRINT_CHAR(tty),
1825
						ldata->char_map);
L
Linus Torvalds 已提交
1826 1827 1828
			}
		}
		if (I_IXON(tty)) {
1829 1830
			set_bit(START_CHAR(tty), ldata->char_map);
			set_bit(STOP_CHAR(tty), ldata->char_map);
L
Linus Torvalds 已提交
1831 1832
		}
		if (L_ISIG(tty)) {
1833 1834 1835
			set_bit(INTR_CHAR(tty), ldata->char_map);
			set_bit(QUIT_CHAR(tty), ldata->char_map);
			set_bit(SUSP_CHAR(tty), ldata->char_map);
L
Linus Torvalds 已提交
1836
		}
1837
		clear_bit(__DISABLED_CHAR, ldata->char_map);
1838 1839
		ldata->raw = 0;
		ldata->real_raw = 0;
L
Linus Torvalds 已提交
1840
	} else {
1841
		ldata->raw = 1;
L
Linus Torvalds 已提交
1842 1843 1844
		if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) &&
		    (I_IGNPAR(tty) || !I_INPCK(tty)) &&
		    (tty->driver->flags & TTY_DRIVER_REAL_RAW))
1845
			ldata->real_raw = 1;
L
Linus Torvalds 已提交
1846
		else
1847
			ldata->real_raw = 0;
L
Linus Torvalds 已提交
1848
	}
1849 1850 1851 1852
	/*
	 * Fix tty hang when I_IXON(tty) is cleared, but the tty
	 * been stopped by STOP_CHAR(tty) before it.
	 */
P
Peter Hurley 已提交
1853
	if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) {
1854
		start_tty(tty);
P
Peter Hurley 已提交
1855 1856
		process_echoes(tty);
	}
1857

A
Alan Cox 已提交
1858
	/* The termios change make the tty ready for I/O */
1859 1860
	wake_up_interruptible(&tty->write_wait);
	wake_up_interruptible(&tty->read_wait);
L
Linus Torvalds 已提交
1861 1862 1863 1864 1865 1866
}

/**
 *	n_tty_close		-	close the ldisc for this tty
 *	@tty: device
 *
1867 1868
 *	Called from the terminal layer when this line discipline is
 *	being shut down, either because of a close or becsuse of a
L
Linus Torvalds 已提交
1869 1870 1871
 *	discipline change. The function will not be called while other
 *	ldisc methods are in progress.
 */
1872

L
Linus Torvalds 已提交
1873 1874
static void n_tty_close(struct tty_struct *tty)
{
J
Jiri Slaby 已提交
1875 1876
	struct n_tty_data *ldata = tty->disc_data;

1877 1878 1879
	if (tty->link)
		n_tty_packet_mode_flush(tty);

1880
	vfree(ldata);
J
Jiri Slaby 已提交
1881
	tty->disc_data = NULL;
L
Linus Torvalds 已提交
1882 1883 1884 1885 1886 1887
}

/**
 *	n_tty_open		-	open an ldisc
 *	@tty: terminal to open
 *
1888
 *	Called when this line discipline is being attached to the
L
Linus Torvalds 已提交
1889 1890 1891 1892 1893 1894 1895
 *	terminal device. Can sleep. Called serialized so that no
 *	other events will occur in parallel. No further open will occur
 *	until a close.
 */

static int n_tty_open(struct tty_struct *tty)
{
J
Jiri Slaby 已提交
1896 1897
	struct n_tty_data *ldata;

1898
	/* Currently a malloc failure here can panic */
1899
	ldata = vzalloc(sizeof(*ldata));
J
Jiri Slaby 已提交
1900
	if (!ldata)
1901
		return -ENOMEM;
J
Jiri Slaby 已提交
1902

1903
	ldata->overrun_time = jiffies;
1904 1905
	mutex_init(&ldata->atomic_read_lock);
	mutex_init(&ldata->output_lock);
1906

J
Jiri Slaby 已提交
1907
	tty->disc_data = ldata;
L
Linus Torvalds 已提交
1908
	tty->closing = 0;
1909 1910 1911 1912
	/* indicate buffer work may resume */
	clear_bit(TTY_LDISC_HALTED, &tty->flags);
	n_tty_set_termios(tty, NULL);
	tty_unthrottle(tty);
L
Linus Torvalds 已提交
1913 1914 1915
	return 0;
}

1916
static inline int input_available_p(struct tty_struct *tty, int poll)
L
Linus Torvalds 已提交
1917
{
1918
	struct n_tty_data *ldata = tty->disc_data;
1919
	int amt = poll && !TIME_CHAR(tty) && MIN_CHAR(tty) ? MIN_CHAR(tty) : 1;
1920

1921 1922 1923
	if (ldata->icanon && !L_EXTPROC(tty))
		return ldata->canon_head != ldata->read_tail;
	else
1924
		return ldata->commit_head - ldata->read_tail >= amt;
L
Linus Torvalds 已提交
1925 1926 1927
}

/**
1928
 *	copy_from_read_buf	-	copy read data directly
L
Linus Torvalds 已提交
1929 1930 1931 1932
 *	@tty: terminal device
 *	@b: user data
 *	@nr: size of data
 *
1933
 *	Helper function to speed up n_tty_read.  It is only called when
L
Linus Torvalds 已提交
1934 1935 1936 1937 1938 1939
 *	ICANON is off; it copies characters straight from the tty queue to
 *	user space directly.  It can be profitably called twice; once to
 *	drain the space from the tail pointer to the (physical) end of the
 *	buffer, and once to drain the space from the (physical) beginning of
 *	the buffer to head pointer.
 *
1940
 *	Called under the ldata->atomic_read_lock sem
L
Linus Torvalds 已提交
1941
 *
1942 1943 1944
 *	n_tty_read()/consumer path:
 *		caller holds non-exclusive termios_rwsem
 *		read_tail published
L
Linus Torvalds 已提交
1945
 */
1946

A
Alan Cox 已提交
1947
static int copy_from_read_buf(struct tty_struct *tty,
L
Linus Torvalds 已提交
1948 1949 1950 1951
				      unsigned char __user **b,
				      size_t *nr)

{
1952
	struct n_tty_data *ldata = tty->disc_data;
L
Linus Torvalds 已提交
1953 1954
	int retval;
	size_t n;
1955
	bool is_eof;
1956
	size_t head = smp_load_acquire(&ldata->commit_head);
1957
	size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
L
Linus Torvalds 已提交
1958 1959

	retval = 0;
1960
	n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail);
L
Linus Torvalds 已提交
1961 1962
	n = min(*nr, n);
	if (n) {
P
Peter Hurley 已提交
1963 1964
		const unsigned char *from = read_buf_addr(ldata, tail);
		retval = copy_to_user(*b, from, n);
L
Linus Torvalds 已提交
1965
		n -= retval;
P
Peter Hurley 已提交
1966
		is_eof = n == 1 && *from == EOF_CHAR(tty);
1967
		tty_audit_add_data(tty, from, n);
1968
		smp_store_release(&ldata->read_tail, ldata->read_tail + n);
1969
		/* Turn single EOF into zero-length read */
1970 1971
		if (L_EXTPROC(tty) && ldata->icanon && is_eof &&
		    (head == ldata->read_tail))
1972
			n = 0;
L
Linus Torvalds 已提交
1973 1974 1975 1976 1977 1978
		*b += n;
		*nr -= n;
	}
	return retval;
}

1979
/**
1980
 *	canon_copy_from_read_buf	-	copy read data in canonical mode
1981 1982 1983 1984 1985
 *	@tty: terminal device
 *	@b: user data
 *	@nr: size of data
 *
 *	Helper function for n_tty_read.  It is only called when ICANON is on;
1986 1987
 *	it copies one line of input up to and including the line-delimiting
 *	character into the user-space buffer.
1988
 *
1989 1990 1991 1992 1993 1994
 *	NB: When termios is changed from non-canonical to canonical mode and
 *	the read buffer contains data, n_tty_set_termios() simulates an EOF
 *	push (as if C-d were input) _without_ the DISABLED_CHAR in the buffer.
 *	This causes data already processed as input to be immediately available
 *	as input although a newline has not been received.
 *
1995
 *	Called under the atomic_read_lock mutex
1996 1997 1998 1999
 *
 *	n_tty_read()/consumer path:
 *		caller holds non-exclusive termios_rwsem
 *		read_tail published
2000 2001
 */

2002 2003 2004
static int canon_copy_from_read_buf(struct tty_struct *tty,
				    unsigned char __user **b,
				    size_t *nr)
2005 2006
{
	struct n_tty_data *ldata = tty->disc_data;
2007
	size_t n, size, more, c;
2008 2009 2010
	size_t eol;
	size_t tail;
	int ret, found = 0;
2011 2012

	/* N.B. avoid overrun if nr == 0 */
2013
	if (!*nr)
2014
		return 0;
2015

2016 2017
	n = min(*nr + 1, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);

2018
	tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
2019 2020
	size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);

2021
	n_tty_trace("%s: nr:%zu tail:%zu n:%zu size:%zu\n",
2022 2023 2024 2025 2026 2027 2028
		    __func__, *nr, tail, n, size);

	eol = find_next_bit(ldata->read_flags, size, tail);
	more = n - (size - tail);
	if (eol == N_TTY_BUF_SIZE && more) {
		/* scan wrapped without finding set bit */
		eol = find_next_bit(ldata->read_flags, more, 0);
2029 2030 2031
		found = eol != more;
	} else
		found = eol != size;
2032

2033
	n = eol - tail;
2034 2035
	if (n > N_TTY_BUF_SIZE)
		n += N_TTY_BUF_SIZE;
2036
	c = n + found;
2037

2038 2039 2040
	if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) {
		c = min(*nr, c);
		n = c;
P
Peter Hurley 已提交
2041
	}
2042

P
Peter Hurley 已提交
2043 2044
	n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu tail:%zu more:%zu\n",
		    __func__, eol, found, n, c, tail, more);
2045

P
Peter Hurley 已提交
2046
	ret = tty_copy_to_user(tty, *b, tail, n);
2047 2048 2049 2050 2051
	if (ret)
		return -EFAULT;
	*b += n;
	*nr -= n;

2052
	if (found)
2053
		clear_bit(eol, ldata->read_flags);
2054
	smp_store_release(&ldata->read_tail, ldata->read_tail + c);
2055

P
Peter Hurley 已提交
2056
	if (found) {
2057 2058 2059 2060
		if (!ldata->push)
			ldata->line_start = ldata->read_tail;
		else
			ldata->push = 0;
2061
		tty_audit_push();
P
Peter Hurley 已提交
2062
	}
2063
	return 0;
2064 2065
}

2066
extern ssize_t redirected_tty_write(struct file *, const char __user *,
2067
							size_t, loff_t *);
L
Linus Torvalds 已提交
2068 2069 2070 2071 2072 2073 2074

/**
 *	job_control		-	check job control
 *	@tty: tty
 *	@file: file handle
 *
 *	Perform job control management checks on this file/tty descriptor
2075
 *	and if appropriate send any needed signals and return a negative
L
Linus Torvalds 已提交
2076
 *	error code if action should be taken.
A
Alan Cox 已提交
2077
 *
2078 2079 2080
 *	Locking: redirected write test is safe
 *		 current->signal->tty check is safe
 *		 ctrl_lock to safely reference tty->pgrp
L
Linus Torvalds 已提交
2081
 */
2082

L
Linus Torvalds 已提交
2083 2084 2085 2086 2087 2088 2089
static int job_control(struct tty_struct *tty, struct file *file)
{
	/* Job control check -- must be done at start and after
	   every sleep (POSIX.1 7.1.1.4). */
	/* NOTE: not yet done after every sleep pending a thorough
	   check of the logic of this change. -- jlc */
	/* don't stop on /dev/console */
2090
	if (file->f_op->write == redirected_tty_write)
2091 2092
		return 0;

2093
	return __tty_check_change(tty, SIGTTIN);
L
Linus Torvalds 已提交
2094
}
2095

L
Linus Torvalds 已提交
2096 2097

/**
2098
 *	n_tty_read		-	read function for tty
L
Linus Torvalds 已提交
2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109
 *	@tty: tty device
 *	@file: file object
 *	@buf: userspace buffer pointer
 *	@nr: size of I/O
 *
 *	Perform reads for the line discipline. We are guaranteed that the
 *	line discipline will not be closed under us but we may get multiple
 *	parallel readers and must handle this ourselves. We may also get
 *	a hangup. Always called in user context, may sleep.
 *
 *	This code must be sure never to sleep through a hangup.
2110 2111 2112 2113
 *
 *	n_tty_read()/consumer path:
 *		claims non-exclusive termios_rwsem
 *		publishes read_tail
L
Linus Torvalds 已提交
2114
 */
2115

2116
static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
L
Linus Torvalds 已提交
2117 2118
			 unsigned char __user *buf, size_t nr)
{
2119
	struct n_tty_data *ldata = tty->disc_data;
L
Linus Torvalds 已提交
2120
	unsigned char __user *b = buf;
2121
	DEFINE_WAIT_FUNC(wait, woken_wake_function);
2122
	int c;
L
Linus Torvalds 已提交
2123 2124 2125
	int minimum, time;
	ssize_t retval = 0;
	long timeout;
A
Alan Cox 已提交
2126
	int packet;
2127
	size_t tail;
L
Linus Torvalds 已提交
2128 2129

	c = job_control(tty, file);
2130
	if (c < 0)
L
Linus Torvalds 已提交
2131
		return c;
2132

2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143
	/*
	 *	Internal serialization of reads.
	 */
	if (file->f_flags & O_NONBLOCK) {
		if (!mutex_trylock(&ldata->atomic_read_lock))
			return -EAGAIN;
	} else {
		if (mutex_lock_interruptible(&ldata->atomic_read_lock))
			return -ERESTARTSYS;
	}

2144 2145
	down_read(&tty->termios_rwsem);

L
Linus Torvalds 已提交
2146 2147
	minimum = time = 0;
	timeout = MAX_SCHEDULE_TIMEOUT;
2148
	if (!ldata->icanon) {
L
Linus Torvalds 已提交
2149 2150
		minimum = MIN_CHAR(tty);
		if (minimum) {
2151
			time = (HZ / 10) * TIME_CHAR(tty);
L
Linus Torvalds 已提交
2152
		} else {
2153
			timeout = (HZ / 10) * TIME_CHAR(tty);
2154
			minimum = 1;
L
Linus Torvalds 已提交
2155 2156 2157
		}
	}

A
Alan Cox 已提交
2158
	packet = tty->packet;
2159
	tail = ldata->read_tail;
L
Linus Torvalds 已提交
2160 2161 2162 2163

	add_wait_queue(&tty->read_wait, &wait);
	while (nr) {
		/* First test for status change. */
A
Alan Cox 已提交
2164
		if (packet && tty->link->ctrl_status) {
L
Linus Torvalds 已提交
2165 2166 2167
			unsigned char cs;
			if (b != buf)
				break;
2168
			spin_lock_irq(&tty->link->ctrl_lock);
L
Linus Torvalds 已提交
2169 2170
			cs = tty->link->ctrl_status;
			tty->link->ctrl_status = 0;
2171
			spin_unlock_irq(&tty->link->ctrl_lock);
2172
			if (put_user(cs, b)) {
L
Linus Torvalds 已提交
2173 2174 2175
				retval = -EFAULT;
				break;
			}
2176
			b++;
L
Linus Torvalds 已提交
2177 2178 2179
			nr--;
			break;
		}
2180

L
Linus Torvalds 已提交
2181
		if (!input_available_p(tty, 0)) {
2182
			up_read(&tty->termios_rwsem);
2183 2184 2185 2186 2187 2188 2189 2190 2191
			tty_buffer_flush_work(tty->port);
			down_read(&tty->termios_rwsem);
			if (!input_available_p(tty, 0)) {
				if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
					retval = -EIO;
					break;
				}
				if (tty_hung_up_p(file))
					break;
2192 2193 2194 2195 2196 2197
				/*
				 * Abort readers for ttys which never actually
				 * get hung up.  See __tty_hangup().
				 */
				if (test_bit(TTY_HUPPING, &tty->flags))
					break;
2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208
				if (!timeout)
					break;
				if (file->f_flags & O_NONBLOCK) {
					retval = -EAGAIN;
					break;
				}
				if (signal_pending(current)) {
					retval = -ERESTARTSYS;
					break;
				}
				up_read(&tty->termios_rwsem);
2209

2210 2211
				timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
						timeout);
2212

2213 2214 2215
				down_read(&tty->termios_rwsem);
				continue;
			}
L
Linus Torvalds 已提交
2216 2217
		}

2218
		if (ldata->icanon && !L_EXTPROC(tty)) {
2219
			retval = canon_copy_from_read_buf(tty, &b, &nr);
2220
			if (retval)
L
Linus Torvalds 已提交
2221 2222 2223
				break;
		} else {
			int uncopied;
2224 2225 2226

			/* Deal with packet mode. */
			if (packet && b == buf) {
2227
				if (put_user(TIOCPKT_DATA, b)) {
2228 2229 2230
					retval = -EFAULT;
					break;
				}
2231
				b++;
2232 2233 2234
				nr--;
			}

L
Linus Torvalds 已提交
2235 2236 2237 2238 2239 2240 2241 2242
			uncopied = copy_from_read_buf(tty, &b, &nr);
			uncopied += copy_from_read_buf(tty, &b, &nr);
			if (uncopied) {
				retval = -EFAULT;
				break;
			}
		}

2243
		n_tty_check_unthrottle(tty);
L
Linus Torvalds 已提交
2244 2245 2246 2247 2248 2249

		if (b - buf >= minimum)
			break;
		if (time)
			timeout = time;
	}
2250 2251
	if (tail != ldata->read_tail)
		n_tty_kick_worker(tty);
2252 2253
	up_read(&tty->termios_rwsem);

L
Linus Torvalds 已提交
2254
	remove_wait_queue(&tty->read_wait, &wait);
2255 2256
	mutex_unlock(&ldata->atomic_read_lock);

P
Peter Hurley 已提交
2257 2258
	if (b - buf)
		retval = b - buf;
L
Linus Torvalds 已提交
2259 2260 2261 2262 2263

	return retval;
}

/**
2264
 *	n_tty_write		-	write function for tty
L
Linus Torvalds 已提交
2265 2266 2267 2268 2269
 *	@tty: tty device
 *	@file: file object
 *	@buf: userspace buffer pointer
 *	@nr: size of I/O
 *
2270
 *	Write function of the terminal device.  This is serialized with
L
Linus Torvalds 已提交
2271
 *	respect to other write callers but not to termios changes, reads
2272 2273 2274 2275 2276
 *	and other such events.  Since the receive code will echo characters,
 *	thus calling driver write methods, the output_lock is used in
 *	the output processing functions called here as well as in the
 *	echo processing function to protect the column state and space
 *	left in the buffer.
L
Linus Torvalds 已提交
2277 2278
 *
 *	This code must be sure never to sleep through a hangup.
2279 2280 2281 2282
 *
 *	Locking: output_lock to protect column state and space left
 *		 (note that the process_output*() functions take this
 *		  lock themselves)
L
Linus Torvalds 已提交
2283
 */
2284

2285
static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
2286
			   const unsigned char *buf, size_t nr)
L
Linus Torvalds 已提交
2287 2288
{
	const unsigned char *b = buf;
2289
	DEFINE_WAIT_FUNC(wait, woken_wake_function);
L
Linus Torvalds 已提交
2290 2291 2292 2293 2294 2295 2296 2297 2298 2299
	int c;
	ssize_t retval = 0;

	/* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
	if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) {
		retval = tty_check_change(tty);
		if (retval)
			return retval;
	}

2300 2301
	down_read(&tty->termios_rwsem);

2302 2303
	/* Write out any echoed characters that are still pending */
	process_echoes(tty);
A
Alan Cox 已提交
2304

L
Linus Torvalds 已提交
2305 2306 2307 2308 2309 2310 2311 2312 2313 2314
	add_wait_queue(&tty->write_wait, &wait);
	while (1) {
		if (signal_pending(current)) {
			retval = -ERESTARTSYS;
			break;
		}
		if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
			retval = -EIO;
			break;
		}
P
Peter Hurley 已提交
2315
		if (O_OPOST(tty)) {
L
Linus Torvalds 已提交
2316
			while (nr > 0) {
2317
				ssize_t num = process_output_block(tty, b, nr);
L
Linus Torvalds 已提交
2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328
				if (num < 0) {
					if (num == -EAGAIN)
						break;
					retval = num;
					goto break_out;
				}
				b += num;
				nr -= num;
				if (nr == 0)
					break;
				c = *b;
2329
				if (process_output(c, tty) < 0)
L
Linus Torvalds 已提交
2330 2331 2332
					break;
				b++; nr--;
			}
A
Alan Cox 已提交
2333 2334
			if (tty->ops->flush_chars)
				tty->ops->flush_chars(tty);
L
Linus Torvalds 已提交
2335
		} else {
2336 2337
			struct n_tty_data *ldata = tty->disc_data;

R
Roman Zippel 已提交
2338
			while (nr > 0) {
2339
				mutex_lock(&ldata->output_lock);
A
Alan Cox 已提交
2340
				c = tty->ops->write(tty, b, nr);
2341
				mutex_unlock(&ldata->output_lock);
R
Roman Zippel 已提交
2342 2343 2344 2345 2346 2347 2348 2349
				if (c < 0) {
					retval = c;
					goto break_out;
				}
				if (!c)
					break;
				b += c;
				nr -= c;
L
Linus Torvalds 已提交
2350 2351 2352 2353 2354 2355 2356 2357
			}
		}
		if (!nr)
			break;
		if (file->f_flags & O_NONBLOCK) {
			retval = -EAGAIN;
			break;
		}
2358 2359
		up_read(&tty->termios_rwsem);

2360
		wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
2361 2362

		down_read(&tty->termios_rwsem);
L
Linus Torvalds 已提交
2363 2364 2365
	}
break_out:
	remove_wait_queue(&tty->write_wait, &wait);
P
Peter Hurley 已提交
2366
	if (nr && tty->fasync)
2367
		set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
2368
	up_read(&tty->termios_rwsem);
L
Linus Torvalds 已提交
2369 2370 2371 2372
	return (b - buf) ? b - buf : retval;
}

/**
2373
 *	n_tty_poll		-	poll method for N_TTY
L
Linus Torvalds 已提交
2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384
 *	@tty: terminal device
 *	@file: file accessing it
 *	@wait: poll table
 *
 *	Called when the line discipline is asked to poll() for data or
 *	for special events. This code is not serialized with respect to
 *	other events save open/close.
 *
 *	This code must be sure never to sleep through a hangup.
 *	Called without the kernel lock held - fine
 */
2385

2386
static __poll_t n_tty_poll(struct tty_struct *tty, struct file *file,
2387
							poll_table *wait)
L
Linus Torvalds 已提交
2388
{
2389
	__poll_t mask = 0;
L
Linus Torvalds 已提交
2390 2391 2392

	poll_wait(file, &tty->read_wait, wait);
	poll_wait(file, &tty->write_wait, wait);
2393
	if (input_available_p(tty, 1))
2394
		mask |= EPOLLIN | EPOLLRDNORM;
2395 2396 2397
	else {
		tty_buffer_flush_work(tty->port);
		if (input_available_p(tty, 1))
2398
			mask |= EPOLLIN | EPOLLRDNORM;
2399
	}
L
Linus Torvalds 已提交
2400
	if (tty->packet && tty->link->ctrl_status)
2401
		mask |= EPOLLPRI | EPOLLIN | EPOLLRDNORM;
2402
	if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
2403
		mask |= EPOLLHUP;
L
Linus Torvalds 已提交
2404
	if (tty_hung_up_p(file))
2405
		mask |= EPOLLHUP;
A
Alan Cox 已提交
2406 2407 2408
	if (tty->ops->write && !tty_is_writelocked(tty) &&
			tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
			tty_write_room(tty) > 0)
2409
		mask |= EPOLLOUT | EPOLLWRNORM;
L
Linus Torvalds 已提交
2410 2411 2412
	return mask;
}

J
Jiri Slaby 已提交
2413
static unsigned long inq_canon(struct n_tty_data *ldata)
2414
{
2415
	size_t nr, head, tail;
2416

2417
	if (ldata->canon_head == ldata->read_tail)
2418
		return 0;
2419 2420
	head = ldata->canon_head;
	tail = ldata->read_tail;
2421
	nr = head - tail;
2422
	/* Skip EOF-chars.. */
2423
	while (MASK(head) != MASK(tail)) {
2424 2425
		if (test_bit(tail & (N_TTY_BUF_SIZE - 1), ldata->read_flags) &&
		    read_buf(ldata, tail) == __DISABLED_CHAR)
2426
			nr--;
2427
		tail++;
2428 2429 2430 2431 2432 2433 2434
	}
	return nr;
}

static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
		       unsigned int cmd, unsigned long arg)
{
2435
	struct n_tty_data *ldata = tty->disc_data;
2436 2437 2438 2439 2440 2441
	int retval;

	switch (cmd) {
	case TIOCOUTQ:
		return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
	case TIOCINQ:
2442
		down_write(&tty->termios_rwsem);
2443
		if (L_ICANON(tty) && !L_EXTPROC(tty))
J
Jiri Slaby 已提交
2444
			retval = inq_canon(ldata);
2445 2446 2447
		else
			retval = read_cnt(ldata);
		up_write(&tty->termios_rwsem);
2448 2449 2450 2451 2452 2453
		return put_user(retval, (unsigned int __user *) arg);
	default:
		return n_tty_ioctl_helper(tty, file, cmd, arg);
	}
}

2454
static struct tty_ldisc_ops n_tty_ops = {
P
Paul Fulghum 已提交
2455 2456 2457 2458 2459
	.magic           = TTY_LDISC_MAGIC,
	.name            = "n_tty",
	.open            = n_tty_open,
	.close           = n_tty_close,
	.flush_buffer    = n_tty_flush_buffer,
2460 2461
	.read            = n_tty_read,
	.write           = n_tty_write,
P
Paul Fulghum 已提交
2462 2463
	.ioctl           = n_tty_ioctl,
	.set_termios     = n_tty_set_termios,
2464
	.poll            = n_tty_poll,
P
Paul Fulghum 已提交
2465
	.receive_buf     = n_tty_receive_buf,
2466
	.write_wakeup    = n_tty_write_wakeup,
2467
	.receive_buf2	 = n_tty_receive_buf2,
L
Linus Torvalds 已提交
2468
};
2469 2470 2471 2472 2473

/**
 *	n_tty_inherit_ops	-	inherit N_TTY methods
 *	@ops: struct tty_ldisc_ops where to save N_TTY methods
 *
2474
 *	Enables a 'subclass' line discipline to 'inherit' N_TTY methods.
2475 2476 2477 2478
 */

void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
{
2479
	*ops = n_tty_ops;
2480 2481 2482 2483
	ops->owner = NULL;
	ops->refcount = ops->flags = 0;
}
EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
2484 2485 2486 2487 2488

void __init n_tty_init(void)
{
	tty_register_ldisc(N_TTY, &n_tty_ops);
}