diff options
-rw-r--r-- | drivers/char/n_tty.c | 736 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 6 | ||||
-rw-r--r-- | drivers/char/vt.c | 2 | ||||
-rw-r--r-- | include/linux/tty.h | 6 |
4 files changed, 594 insertions, 156 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index efbfe9612658..a9bc5764fe75 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -62,6 +62,17 @@ | |||
62 | #define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */ | 62 | #define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */ |
63 | #define TTY_THRESHOLD_UNTHROTTLE 128 | 63 | #define TTY_THRESHOLD_UNTHROTTLE 128 |
64 | 64 | ||
65 | /* | ||
66 | * Special byte codes used in the echo buffer to represent operations | ||
67 | * or special handling of characters. Bytes in the echo buffer that | ||
68 | * are not part of such special blocks are treated as normal character | ||
69 | * codes. | ||
70 | */ | ||
71 | #define ECHO_OP_START 0xff | ||
72 | #define ECHO_OP_MOVE_BACK_COL 0x80 | ||
73 | #define ECHO_OP_SET_CANON_COL 0x81 | ||
74 | #define ECHO_OP_ERASE_TAB 0x82 | ||
75 | |||
65 | static inline unsigned char *alloc_buf(void) | 76 | static inline unsigned char *alloc_buf(void) |
66 | { | 77 | { |
67 | gfp_t prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; | 78 | gfp_t prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; |
@@ -169,6 +180,7 @@ static void check_unthrottle(struct tty_struct *tty) | |||
169 | * | 180 | * |
170 | * Locking: tty_read_lock for read fields. | 181 | * Locking: tty_read_lock for read fields. |
171 | */ | 182 | */ |
183 | |||
172 | static void reset_buffer_flags(struct tty_struct *tty) | 184 | static void reset_buffer_flags(struct tty_struct *tty) |
173 | { | 185 | { |
174 | unsigned long flags; | 186 | unsigned long flags; |
@@ -176,6 +188,11 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
176 | spin_lock_irqsave(&tty->read_lock, flags); | 188 | spin_lock_irqsave(&tty->read_lock, flags); |
177 | tty->read_head = tty->read_tail = tty->read_cnt = 0; | 189 | tty->read_head = tty->read_tail = tty->read_cnt = 0; |
178 | spin_unlock_irqrestore(&tty->read_lock, flags); | 190 | spin_unlock_irqrestore(&tty->read_lock, flags); |
191 | |||
192 | mutex_lock(&tty->echo_lock); | ||
193 | tty->echo_pos = tty->echo_cnt = tty->echo_overrun = 0; | ||
194 | mutex_unlock(&tty->echo_lock); | ||
195 | |||
179 | tty->canon_head = tty->canon_data = tty->erasing = 0; | 196 | tty->canon_head = tty->canon_data = tty->erasing = 0; |
180 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 197 | memset(&tty->read_flags, 0, sizeof tty->read_flags); |
181 | n_tty_set_room(tty); | 198 | n_tty_set_room(tty); |
@@ -266,89 +283,116 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty) | |||
266 | } | 283 | } |
267 | 284 | ||
268 | /** | 285 | /** |
269 | * opost - output post processor | 286 | * do_output_char - output one character |
270 | * @c: character (or partial unicode symbol) | 287 | * @c: character (or partial unicode symbol) |
271 | * @tty: terminal device | 288 | * @tty: terminal device |
289 | * @space: space available in tty driver write buffer | ||
272 | * | 290 | * |
273 | * Perform OPOST processing. Returns -1 when the output device is | 291 | * This is a helper function that handles one output character |
274 | * full and the character must be retried. Note that Linux currently | 292 | * (including special characters like TAB, CR, LF, etc.), |
275 | * ignores TABDLY, CRDLY, VTDLY, FFDLY and NLDLY. They simply aren't | 293 | * putting the results in the tty driver's write buffer. |
276 | * relevant in the world today. If you ever need them, add them here. | 294 | * |
295 | * Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY | ||
296 | * and NLDLY. They simply aren't relevant in the world today. | ||
297 | * If you ever need them, add them here. | ||
277 | * | 298 | * |
278 | * Called from both the receive and transmit sides and can be called | 299 | * Returns the number of bytes of buffer space used or -1 if |
279 | * re-entrantly. Relies on lock_kernel() for tty->column state. | 300 | * no space left. |
301 | * | ||
302 | * Locking: should be called under the output_lock to protect | ||
303 | * the column state and space left in the buffer | ||
280 | */ | 304 | */ |
281 | 305 | ||
282 | static int opost(unsigned char c, struct tty_struct *tty) | 306 | static int do_output_char(unsigned char c, struct tty_struct *tty, int space) |
283 | { | 307 | { |
284 | int space, spaces; | 308 | int spaces; |
285 | 309 | ||
286 | space = tty_write_room(tty); | ||
287 | if (!space) | 310 | if (!space) |
288 | return -1; | 311 | return -1; |
289 | 312 | ||
290 | lock_kernel(); | 313 | switch (c) { |
291 | if (O_OPOST(tty)) { | 314 | case '\n': |
292 | switch (c) { | 315 | if (O_ONLRET(tty)) |
293 | case '\n': | 316 | tty->column = 0; |
294 | if (O_ONLRET(tty)) | 317 | if (O_ONLCR(tty)) { |
295 | tty->column = 0; | 318 | if (space < 2) |
296 | if (O_ONLCR(tty)) { | 319 | return -1; |
297 | if (space < 2) { | ||
298 | unlock_kernel(); | ||
299 | return -1; | ||
300 | } | ||
301 | tty_put_char(tty, '\r'); | ||
302 | tty->column = 0; | ||
303 | } | ||
304 | tty->canon_column = tty->column; | ||
305 | break; | ||
306 | case '\r': | ||
307 | if (O_ONOCR(tty) && tty->column == 0) { | ||
308 | unlock_kernel(); | ||
309 | return 0; | ||
310 | } | ||
311 | if (O_OCRNL(tty)) { | ||
312 | c = '\n'; | ||
313 | if (O_ONLRET(tty)) | ||
314 | tty->canon_column = tty->column = 0; | ||
315 | break; | ||
316 | } | ||
317 | tty->canon_column = tty->column = 0; | 320 | tty->canon_column = tty->column = 0; |
321 | tty_put_char(tty, '\r'); | ||
322 | tty_put_char(tty, c); | ||
323 | return 2; | ||
324 | } | ||
325 | tty->canon_column = tty->column; | ||
326 | break; | ||
327 | case '\r': | ||
328 | if (O_ONOCR(tty) && tty->column == 0) | ||
329 | return 0; | ||
330 | if (O_OCRNL(tty)) { | ||
331 | c = '\n'; | ||
332 | if (O_ONLRET(tty)) | ||
333 | tty->canon_column = tty->column = 0; | ||
318 | break; | 334 | break; |
319 | case '\t': | 335 | } |
320 | spaces = 8 - (tty->column & 7); | 336 | tty->canon_column = tty->column = 0; |
321 | if (O_TABDLY(tty) == XTABS) { | 337 | break; |
322 | if (space < spaces) { | 338 | case '\t': |
323 | unlock_kernel(); | 339 | spaces = 8 - (tty->column & 7); |
324 | return -1; | 340 | if (O_TABDLY(tty) == XTABS) { |
325 | } | 341 | if (space < spaces) |
326 | tty->column += spaces; | 342 | return -1; |
327 | tty->ops->write(tty, " ", spaces); | ||
328 | unlock_kernel(); | ||
329 | return 0; | ||
330 | } | ||
331 | tty->column += spaces; | 343 | tty->column += spaces; |
332 | break; | 344 | tty->ops->write(tty, " ", spaces); |
333 | case '\b': | 345 | return spaces; |
334 | if (tty->column > 0) | ||
335 | tty->column--; | ||
336 | break; | ||
337 | default: | ||
338 | if (O_OLCUC(tty)) | ||
339 | c = toupper(c); | ||
340 | if (!iscntrl(c) && !is_continuation(c, tty)) | ||
341 | tty->column++; | ||
342 | break; | ||
343 | } | 346 | } |
347 | tty->column += spaces; | ||
348 | break; | ||
349 | case '\b': | ||
350 | if (tty->column > 0) | ||
351 | tty->column--; | ||
352 | break; | ||
353 | default: | ||
354 | if (O_OLCUC(tty)) | ||
355 | c = toupper(c); | ||
356 | if (!iscntrl(c) && !is_continuation(c, tty)) | ||
357 | tty->column++; | ||
358 | break; | ||
344 | } | 359 | } |
360 | |||
345 | tty_put_char(tty, c); | 361 | tty_put_char(tty, c); |
346 | unlock_kernel(); | 362 | return 1; |
347 | return 0; | 363 | } |
364 | |||
365 | /** | ||
366 | * process_output - output post processor | ||
367 | * @c: character (or partial unicode symbol) | ||
368 | * @tty: terminal device | ||
369 | * | ||
370 | * Perform OPOST processing. Returns -1 when the output device is | ||
371 | * full and the character must be retried. | ||
372 | * | ||
373 | * Locking: output_lock to protect column state and space left | ||
374 | * (also, this is called from n_tty_write under the | ||
375 | * tty layer write lock) | ||
376 | */ | ||
377 | |||
378 | static int process_output(unsigned char c, struct tty_struct *tty) | ||
379 | { | ||
380 | int space, retval; | ||
381 | |||
382 | mutex_lock(&tty->output_lock); | ||
383 | |||
384 | space = tty_write_room(tty); | ||
385 | retval = do_output_char(c, tty, space); | ||
386 | |||
387 | mutex_unlock(&tty->output_lock); | ||
388 | if (retval < 0) | ||
389 | return -1; | ||
390 | else | ||
391 | return 0; | ||
348 | } | 392 | } |
349 | 393 | ||
350 | /** | 394 | /** |
351 | * opost_block - block postprocess | 395 | * process_output_block - block post processor |
352 | * @tty: terminal device | 396 | * @tty: terminal device |
353 | * @inbuf: user buffer | 397 | * @inbuf: user buffer |
354 | * @nr: number of bytes | 398 | * @nr: number of bytes |
@@ -358,24 +402,29 @@ static int opost(unsigned char c, struct tty_struct *tty) | |||
358 | * the simple cases normally found and helps to generate blocks of | 402 | * the simple cases normally found and helps to generate blocks of |
359 | * symbols for the console driver and thus improve performance. | 403 | * symbols for the console driver and thus improve performance. |
360 | * | 404 | * |
361 | * Called from n_tty_write under the tty layer write lock. Relies | 405 | * Locking: output_lock to protect column state and space left |
362 | * on lock_kernel for the tty->column state. | 406 | * (also, this is called from n_tty_write under the |
407 | * tty layer write lock) | ||
363 | */ | 408 | */ |
364 | 409 | ||
365 | static ssize_t opost_block(struct tty_struct *tty, | 410 | static ssize_t process_output_block(struct tty_struct *tty, |
366 | const unsigned char *buf, unsigned int nr) | 411 | const unsigned char *buf, unsigned int nr) |
367 | { | 412 | { |
368 | int space; | 413 | int space; |
369 | int i; | 414 | int i; |
370 | const unsigned char *cp; | 415 | const unsigned char *cp; |
371 | 416 | ||
417 | mutex_lock(&tty->output_lock); | ||
418 | |||
372 | space = tty_write_room(tty); | 419 | space = tty_write_room(tty); |
373 | if (!space) | 420 | if (!space) |
421 | { | ||
422 | mutex_unlock(&tty->output_lock); | ||
374 | return 0; | 423 | return 0; |
424 | } | ||
375 | if (nr > space) | 425 | if (nr > space) |
376 | nr = space; | 426 | nr = space; |
377 | 427 | ||
378 | lock_kernel(); | ||
379 | for (i = 0, cp = buf; i < nr; i++, cp++) { | 428 | for (i = 0, cp = buf; i < nr; i++, cp++) { |
380 | switch (*cp) { | 429 | switch (*cp) { |
381 | case '\n': | 430 | case '\n': |
@@ -407,46 +456,393 @@ static ssize_t opost_block(struct tty_struct *tty, | |||
407 | } | 456 | } |
408 | } | 457 | } |
409 | break_out: | 458 | break_out: |
410 | if (tty->ops->flush_chars) | ||
411 | tty->ops->flush_chars(tty); | ||
412 | i = tty->ops->write(tty, buf, i); | 459 | i = tty->ops->write(tty, buf, i); |
413 | unlock_kernel(); | 460 | |
461 | mutex_unlock(&tty->output_lock); | ||
414 | return i; | 462 | return i; |
415 | } | 463 | } |
416 | 464 | ||
465 | /** | ||
466 | * process_echoes - write pending echo characters | ||
467 | * @tty: terminal device | ||
468 | * | ||
469 | * Write previously buffered echo (and other ldisc-generated) | ||
470 | * characters to the tty. | ||
471 | * | ||
472 | * Characters generated by the ldisc (including echoes) need to | ||
473 | * be buffered because the driver's write buffer can fill during | ||
474 | * heavy program output. Echoing straight to the driver will | ||
475 | * often fail under these conditions, causing lost characters and | ||
476 | * resulting mismatches of ldisc state information. | ||
477 | * | ||
478 | * Since the ldisc state must represent the characters actually sent | ||
479 | * to the driver at the time of the write, operations like certain | ||
480 | * changes in column state are also saved in the buffer and executed | ||
481 | * here. | ||
482 | * | ||
483 | * A circular fifo buffer is used so that the most recent characters | ||
484 | * are prioritized. Also, when control characters are echoed with a | ||
485 | * prefixed "^", the pair is treated atomically and thus not separated. | ||
486 | * | ||
487 | * Locking: output_lock to protect column state and space left, | ||
488 | * echo_lock to protect the echo buffer | ||
489 | */ | ||
490 | |||
491 | static void process_echoes(struct tty_struct *tty) | ||
492 | { | ||
493 | int space, nr; | ||
494 | unsigned char c; | ||
495 | unsigned char *cp, *buf_end; | ||
496 | |||
497 | if (!tty->echo_cnt) | ||
498 | return; | ||
499 | |||
500 | mutex_lock(&tty->output_lock); | ||
501 | mutex_lock(&tty->echo_lock); | ||
502 | |||
503 | space = tty_write_room(tty); | ||
504 | |||
505 | buf_end = tty->echo_buf + N_TTY_BUF_SIZE; | ||
506 | cp = tty->echo_buf + tty->echo_pos; | ||
507 | nr = tty->echo_cnt; | ||
508 | while (nr > 0) { | ||
509 | c = *cp; | ||
510 | if (c == ECHO_OP_START) { | ||
511 | unsigned char op; | ||
512 | unsigned char *opp; | ||
513 | int no_space_left = 0; | ||
514 | |||
515 | /* | ||
516 | * If the buffer byte is the start of a multi-byte | ||
517 | * operation, get the next byte, which is either the | ||
518 | * op code or a control character value. | ||
519 | */ | ||
520 | opp = cp + 1; | ||
521 | if (opp == buf_end) | ||
522 | opp -= N_TTY_BUF_SIZE; | ||
523 | op = *opp; | ||
524 | |||
525 | switch (op) { | ||
526 | unsigned int num_chars, num_bs; | ||
527 | |||
528 | case ECHO_OP_ERASE_TAB: | ||
529 | if (++opp == buf_end) | ||
530 | opp -= N_TTY_BUF_SIZE; | ||
531 | num_chars = *opp; | ||
532 | |||
533 | /* | ||
534 | * Determine how many columns to go back | ||
535 | * in order to erase the tab. | ||
536 | * This depends on the number of columns | ||
537 | * used by other characters within the tab | ||
538 | * area. If this (modulo 8) count is from | ||
539 | * the start of input rather than from a | ||
540 | * previous tab, we offset by canon column. | ||
541 | * Otherwise, tab spacing is normal. | ||
542 | */ | ||
543 | if (!(num_chars & 0x80)) | ||
544 | num_chars += tty->canon_column; | ||
545 | num_bs = 8 - (num_chars & 7); | ||
546 | |||
547 | if (num_bs > space) { | ||
548 | no_space_left = 1; | ||
549 | break; | ||
550 | } | ||
551 | space -= num_bs; | ||
552 | while (num_bs--) { | ||
553 | tty_put_char(tty, '\b'); | ||
554 | if (tty->column > 0) | ||
555 | tty->column--; | ||
556 | } | ||
557 | cp += 3; | ||
558 | nr -= 3; | ||
559 | break; | ||
560 | |||
561 | case ECHO_OP_SET_CANON_COL: | ||
562 | tty->canon_column = tty->column; | ||
563 | cp += 2; | ||
564 | nr -= 2; | ||
565 | break; | ||
566 | |||
567 | case ECHO_OP_MOVE_BACK_COL: | ||
568 | if (tty->column > 0) | ||
569 | tty->column--; | ||
570 | cp += 2; | ||
571 | nr -= 2; | ||
572 | break; | ||
573 | |||
574 | case ECHO_OP_START: | ||
575 | /* This is an escaped echo op start code */ | ||
576 | if (!space) { | ||
577 | no_space_left = 1; | ||
578 | break; | ||
579 | } | ||
580 | tty_put_char(tty, ECHO_OP_START); | ||
581 | tty->column++; | ||
582 | space--; | ||
583 | cp += 2; | ||
584 | nr -= 2; | ||
585 | break; | ||
586 | |||
587 | default: | ||
588 | if (iscntrl(op)) { | ||
589 | if (L_ECHOCTL(tty)) { | ||
590 | /* | ||
591 | * Ensure there is enough space | ||
592 | * for the whole ctrl pair. | ||
593 | */ | ||
594 | if (space < 2) { | ||
595 | no_space_left = 1; | ||
596 | break; | ||
597 | } | ||
598 | tty_put_char(tty, '^'); | ||
599 | tty_put_char(tty, op ^ 0100); | ||
600 | tty->column += 2; | ||
601 | space -= 2; | ||
602 | } else { | ||
603 | if (!space) { | ||
604 | no_space_left = 1; | ||
605 | break; | ||
606 | } | ||
607 | tty_put_char(tty, op); | ||
608 | space--; | ||
609 | } | ||
610 | } | ||
611 | /* | ||
612 | * If above falls through, this was an | ||
613 | * undefined op. | ||
614 | */ | ||
615 | cp += 2; | ||
616 | nr -= 2; | ||
617 | } | ||
618 | |||
619 | if (no_space_left) | ||
620 | break; | ||
621 | } else { | ||
622 | int retval; | ||
623 | |||
624 | if ((retval = do_output_char(c, tty, space)) < 0) | ||
625 | break; | ||
626 | space -= retval; | ||
627 | cp += 1; | ||
628 | nr -= 1; | ||
629 | } | ||
630 | |||
631 | /* When end of circular buffer reached, wrap around */ | ||
632 | if (cp >= buf_end) | ||
633 | cp -= N_TTY_BUF_SIZE; | ||
634 | } | ||
635 | |||
636 | if (nr == 0) { | ||
637 | tty->echo_pos = 0; | ||
638 | tty->echo_cnt = 0; | ||
639 | tty->echo_overrun = 0; | ||
640 | } else { | ||
641 | int num_processed = tty->echo_cnt - nr; | ||
642 | tty->echo_pos += num_processed; | ||
643 | tty->echo_pos &= N_TTY_BUF_SIZE - 1; | ||
644 | tty->echo_cnt = nr; | ||
645 | if (num_processed > 0) | ||
646 | tty->echo_overrun = 0; | ||
647 | } | ||
648 | |||
649 | mutex_unlock(&tty->echo_lock); | ||
650 | mutex_unlock(&tty->output_lock); | ||
651 | |||
652 | if (tty->ops->flush_chars) | ||
653 | tty->ops->flush_chars(tty); | ||
654 | } | ||
655 | |||
656 | /** | ||
657 | * add_echo_byte - add a byte to the echo buffer | ||
658 | * @c: unicode byte to echo | ||
659 | * @tty: terminal device | ||
660 | * | ||
661 | * Add a character or operation byte to the echo buffer. | ||
662 | * | ||
663 | * Should be called under the echo lock to protect the echo buffer. | ||
664 | */ | ||
665 | |||
666 | static void add_echo_byte(unsigned char c, struct tty_struct *tty) | ||
667 | { | ||
668 | int new_byte_pos; | ||
669 | |||
670 | if (tty->echo_cnt == N_TTY_BUF_SIZE) { | ||
671 | /* Circular buffer is already at capacity */ | ||
672 | new_byte_pos = tty->echo_pos; | ||
673 | |||
674 | /* | ||
675 | * Since the buffer start position needs to be advanced, | ||
676 | * be sure to step by a whole operation byte group. | ||
677 | */ | ||
678 | if (tty->echo_buf[tty->echo_pos] == ECHO_OP_START) | ||
679 | { | ||
680 | if (tty->echo_buf[(tty->echo_pos + 1) & | ||
681 | (N_TTY_BUF_SIZE - 1)] == | ||
682 | ECHO_OP_ERASE_TAB) { | ||
683 | tty->echo_pos += 3; | ||
684 | tty->echo_cnt -= 2; | ||
685 | } else { | ||
686 | tty->echo_pos += 2; | ||
687 | tty->echo_cnt -= 1; | ||
688 | } | ||
689 | } else { | ||
690 | tty->echo_pos++; | ||
691 | } | ||
692 | tty->echo_pos &= N_TTY_BUF_SIZE - 1; | ||
693 | |||
694 | tty->echo_overrun = 1; | ||
695 | } else { | ||
696 | new_byte_pos = tty->echo_pos + tty->echo_cnt; | ||
697 | new_byte_pos &= N_TTY_BUF_SIZE - 1; | ||
698 | tty->echo_cnt++; | ||
699 | } | ||
700 | |||
701 | tty->echo_buf[new_byte_pos] = c; | ||
702 | } | ||
703 | |||
704 | /** | ||
705 | * echo_move_back_col - add operation to move back a column | ||
706 | * @tty: terminal device | ||
707 | * | ||
708 | * Add an operation to the echo buffer to move back one column. | ||
709 | * | ||
710 | * Locking: echo_lock to protect the echo buffer | ||
711 | */ | ||
712 | |||
713 | static void echo_move_back_col(struct tty_struct *tty) | ||
714 | { | ||
715 | mutex_lock(&tty->echo_lock); | ||
716 | |||
717 | add_echo_byte(ECHO_OP_START, tty); | ||
718 | add_echo_byte(ECHO_OP_MOVE_BACK_COL, tty); | ||
719 | |||
720 | mutex_unlock(&tty->echo_lock); | ||
721 | } | ||
722 | |||
723 | /** | ||
724 | * echo_set_canon_col - add operation to set the canon column | ||
725 | * @tty: terminal device | ||
726 | * | ||
727 | * Add an operation to the echo buffer to set the canon column | ||
728 | * to the current column. | ||
729 | * | ||
730 | * Locking: echo_lock to protect the echo buffer | ||
731 | */ | ||
732 | |||
733 | static void echo_set_canon_col(struct tty_struct *tty) | ||
734 | { | ||
735 | mutex_lock(&tty->echo_lock); | ||
736 | |||
737 | add_echo_byte(ECHO_OP_START, tty); | ||
738 | add_echo_byte(ECHO_OP_SET_CANON_COL, tty); | ||
739 | |||
740 | mutex_unlock(&tty->echo_lock); | ||
741 | } | ||
742 | |||
743 | /** | ||
744 | * echo_erase_tab - add operation to erase a tab | ||
745 | * @num_chars: number of character columns already used | ||
746 | * @after_tab: true if num_chars starts after a previous tab | ||
747 | * @tty: terminal device | ||
748 | * | ||
749 | * Add an operation to the echo buffer to erase a tab. | ||
750 | * | ||
751 | * Called by the eraser function, which knows how many character | ||
752 | * columns have been used since either a previous tab or the start | ||
753 | * of input. This information will be used later, along with | ||
754 | * canon column (if applicable), to go back the correct number | ||
755 | * of columns. | ||
756 | * | ||
757 | * Locking: echo_lock to protect the echo buffer | ||
758 | */ | ||
759 | |||
760 | static void echo_erase_tab(unsigned int num_chars, int after_tab, | ||
761 | struct tty_struct *tty) | ||
762 | { | ||
763 | mutex_lock(&tty->echo_lock); | ||
764 | |||
765 | add_echo_byte(ECHO_OP_START, tty); | ||
766 | add_echo_byte(ECHO_OP_ERASE_TAB, tty); | ||
767 | |||
768 | /* We only need to know this modulo 8 (tab spacing) */ | ||
769 | num_chars &= 7; | ||
770 | |||
771 | /* Set the high bit as a flag if num_chars is after a previous tab */ | ||
772 | if (after_tab) | ||
773 | num_chars |= 0x80; | ||
774 | |||
775 | add_echo_byte(num_chars, tty); | ||
776 | |||
777 | mutex_unlock(&tty->echo_lock); | ||
778 | } | ||
779 | |||
780 | /** | ||
781 | * echo_char_raw - echo a character raw | ||
782 | * @c: unicode byte to echo | ||
783 | * @tty: terminal device | ||
784 | * | ||
785 | * Echo user input back onto the screen. This must be called only when | ||
786 | * L_ECHO(tty) is true. Called from the driver receive_buf path. | ||
787 | * | ||
788 | * This variant does not treat control characters specially. | ||
789 | * | ||
790 | * Locking: echo_lock to protect the echo buffer | ||
791 | */ | ||
792 | |||
793 | static void echo_char_raw(unsigned char c, struct tty_struct *tty) | ||
794 | { | ||
795 | mutex_lock(&tty->echo_lock); | ||
796 | |||
797 | if (c == ECHO_OP_START) { | ||
798 | add_echo_byte(ECHO_OP_START, tty); | ||
799 | add_echo_byte(ECHO_OP_START, tty); | ||
800 | } else { | ||
801 | add_echo_byte(c, tty); | ||
802 | } | ||
803 | |||
804 | mutex_unlock(&tty->echo_lock); | ||
805 | } | ||
417 | 806 | ||
418 | /** | 807 | /** |
419 | * echo_char - echo characters | 808 | * echo_char - echo a character |
420 | * @c: unicode byte to echo | 809 | * @c: unicode byte to echo |
421 | * @tty: terminal device | 810 | * @tty: terminal device |
422 | * | 811 | * |
423 | * Echo user input back onto the screen. This must be called only when | 812 | * Echo user input back onto the screen. This must be called only when |
424 | * L_ECHO(tty) is true. Called from the driver receive_buf path. | 813 | * L_ECHO(tty) is true. Called from the driver receive_buf path. |
425 | * | 814 | * |
426 | * Relies on BKL for tty column locking | 815 | * This variant tags control characters to be possibly echoed as |
816 | * as "^X" (where X is the letter representing the control char). | ||
817 | * | ||
818 | * Locking: echo_lock to protect the echo buffer | ||
427 | */ | 819 | */ |
428 | 820 | ||
429 | static void echo_char(unsigned char c, struct tty_struct *tty) | 821 | static void echo_char(unsigned char c, struct tty_struct *tty) |
430 | { | 822 | { |
431 | if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') { | 823 | mutex_lock(&tty->echo_lock); |
432 | tty_put_char(tty, '^'); | 824 | |
433 | tty_put_char(tty, c ^ 0100); | 825 | if (c == ECHO_OP_START) { |
434 | tty->column += 2; | 826 | add_echo_byte(ECHO_OP_START, tty); |
435 | } else | 827 | add_echo_byte(ECHO_OP_START, tty); |
436 | opost(c, tty); | 828 | } else { |
829 | if (iscntrl(c) && c != '\t') | ||
830 | add_echo_byte(ECHO_OP_START, tty); | ||
831 | add_echo_byte(c, tty); | ||
832 | } | ||
833 | |||
834 | mutex_unlock(&tty->echo_lock); | ||
437 | } | 835 | } |
438 | 836 | ||
439 | /** | 837 | /** |
440 | * finsh_erasing - complete erase | 838 | * finish_erasing - complete erase |
441 | * @tty: tty doing the erase | 839 | * @tty: tty doing the erase |
442 | * | ||
443 | * Relies on BKL for tty column locking | ||
444 | */ | 840 | */ |
841 | |||
445 | static inline void finish_erasing(struct tty_struct *tty) | 842 | static inline void finish_erasing(struct tty_struct *tty) |
446 | { | 843 | { |
447 | if (tty->erasing) { | 844 | if (tty->erasing) { |
448 | tty_put_char(tty, '/'); | 845 | echo_char_raw('/', tty); |
449 | tty->column++; | ||
450 | tty->erasing = 0; | 846 | tty->erasing = 0; |
451 | } | 847 | } |
452 | } | 848 | } |
@@ -460,7 +856,7 @@ static inline void finish_erasing(struct tty_struct *tty) | |||
460 | * present in the stream from the driver layer. Handles the complexities | 856 | * present in the stream from the driver layer. Handles the complexities |
461 | * of UTF-8 multibyte symbols. | 857 | * of UTF-8 multibyte symbols. |
462 | * | 858 | * |
463 | * Locking: read_lock for tty buffers, BKL for column/erasing state | 859 | * Locking: read_lock for tty buffers |
464 | */ | 860 | */ |
465 | 861 | ||
466 | static void eraser(unsigned char c, struct tty_struct *tty) | 862 | static void eraser(unsigned char c, struct tty_struct *tty) |
@@ -471,7 +867,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
471 | 867 | ||
472 | /* FIXME: locking needed ? */ | 868 | /* FIXME: locking needed ? */ |
473 | if (tty->read_head == tty->canon_head) { | 869 | if (tty->read_head == tty->canon_head) { |
474 | /* opost('\a', tty); */ /* what do you think? */ | 870 | /* echo_char_raw('\a', tty); */ /* what do you think? */ |
475 | return; | 871 | return; |
476 | } | 872 | } |
477 | if (c == ERASE_CHAR(tty)) | 873 | if (c == ERASE_CHAR(tty)) |
@@ -497,7 +893,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
497 | echo_char(KILL_CHAR(tty), tty); | 893 | echo_char(KILL_CHAR(tty), tty); |
498 | /* Add a newline if ECHOK is on and ECHOKE is off. */ | 894 | /* Add a newline if ECHOK is on and ECHOKE is off. */ |
499 | if (L_ECHOK(tty)) | 895 | if (L_ECHOK(tty)) |
500 | opost('\n', tty); | 896 | echo_char_raw('\n', tty); |
501 | return; | 897 | return; |
502 | } | 898 | } |
503 | kill_type = KILL; | 899 | kill_type = KILL; |
@@ -533,67 +929,62 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
533 | if (L_ECHO(tty)) { | 929 | if (L_ECHO(tty)) { |
534 | if (L_ECHOPRT(tty)) { | 930 | if (L_ECHOPRT(tty)) { |
535 | if (!tty->erasing) { | 931 | if (!tty->erasing) { |
536 | tty_put_char(tty, '\\'); | 932 | echo_char_raw('\\', tty); |
537 | tty->column++; | ||
538 | tty->erasing = 1; | 933 | tty->erasing = 1; |
539 | } | 934 | } |
540 | /* if cnt > 1, output a multi-byte character */ | 935 | /* if cnt > 1, output a multi-byte character */ |
541 | echo_char(c, tty); | 936 | echo_char(c, tty); |
542 | while (--cnt > 0) { | 937 | while (--cnt > 0) { |
543 | head = (head+1) & (N_TTY_BUF_SIZE-1); | 938 | head = (head+1) & (N_TTY_BUF_SIZE-1); |
544 | tty_put_char(tty, tty->read_buf[head]); | 939 | echo_char_raw(tty->read_buf[head], tty); |
940 | echo_move_back_col(tty); | ||
545 | } | 941 | } |
546 | } else if (kill_type == ERASE && !L_ECHOE(tty)) { | 942 | } else if (kill_type == ERASE && !L_ECHOE(tty)) { |
547 | echo_char(ERASE_CHAR(tty), tty); | 943 | echo_char(ERASE_CHAR(tty), tty); |
548 | } else if (c == '\t') { | 944 | } else if (c == '\t') { |
549 | unsigned int col = tty->canon_column; | 945 | unsigned int num_chars = 0; |
550 | unsigned long tail = tty->canon_head; | 946 | int after_tab = 0; |
551 | 947 | unsigned long tail = tty->read_head; | |
552 | /* Find the column of the last char. */ | 948 | |
553 | while (tail != tty->read_head) { | 949 | /* |
950 | * Count the columns used for characters | ||
951 | * since the start of input or after a | ||
952 | * previous tab. | ||
953 | * This info is used to go back the correct | ||
954 | * number of columns. | ||
955 | */ | ||
956 | while (tail != tty->canon_head) { | ||
957 | tail = (tail-1) & (N_TTY_BUF_SIZE-1); | ||
554 | c = tty->read_buf[tail]; | 958 | c = tty->read_buf[tail]; |
555 | if (c == '\t') | 959 | if (c == '\t') { |
556 | col = (col | 7) + 1; | 960 | after_tab = 1; |
961 | break; | ||
962 | } | ||
557 | else if (iscntrl(c)) { | 963 | else if (iscntrl(c)) { |
558 | if (L_ECHOCTL(tty)) | 964 | if (L_ECHOCTL(tty)) |
559 | col += 2; | 965 | num_chars += 2; |
560 | } else if (!is_continuation(c, tty)) | 966 | } else if (!is_continuation(c, tty)) { |
561 | col++; | 967 | num_chars++; |
562 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | 968 | } |
563 | } | ||
564 | |||
565 | /* should never happen */ | ||
566 | if (tty->column > 0x80000000) | ||
567 | tty->column = 0; | ||
568 | |||
569 | /* Now backup to that column. */ | ||
570 | while (tty->column > col) { | ||
571 | /* Can't use opost here. */ | ||
572 | tty_put_char(tty, '\b'); | ||
573 | if (tty->column > 0) | ||
574 | tty->column--; | ||
575 | } | 969 | } |
970 | echo_erase_tab(num_chars, after_tab, tty); | ||
576 | } else { | 971 | } else { |
577 | if (iscntrl(c) && L_ECHOCTL(tty)) { | 972 | if (iscntrl(c) && L_ECHOCTL(tty)) { |
578 | tty_put_char(tty, '\b'); | 973 | echo_char_raw('\b', tty); |
579 | tty_put_char(tty, ' '); | 974 | echo_char_raw(' ', tty); |
580 | tty_put_char(tty, '\b'); | 975 | echo_char_raw('\b', tty); |
581 | if (tty->column > 0) | ||
582 | tty->column--; | ||
583 | } | 976 | } |
584 | if (!iscntrl(c) || L_ECHOCTL(tty)) { | 977 | if (!iscntrl(c) || L_ECHOCTL(tty)) { |
585 | tty_put_char(tty, '\b'); | 978 | echo_char_raw('\b', tty); |
586 | tty_put_char(tty, ' '); | 979 | echo_char_raw(' ', tty); |
587 | tty_put_char(tty, '\b'); | 980 | echo_char_raw('\b', tty); |
588 | if (tty->column > 0) | ||
589 | tty->column--; | ||
590 | } | 981 | } |
591 | } | 982 | } |
592 | } | 983 | } |
593 | if (kill_type == ERASE) | 984 | if (kill_type == ERASE) |
594 | break; | 985 | break; |
595 | } | 986 | } |
596 | if (tty->read_head == tty->canon_head) | 987 | if (tty->read_head == tty->canon_head && L_ECHO(tty)) |
597 | finish_erasing(tty); | 988 | finish_erasing(tty); |
598 | } | 989 | } |
599 | 990 | ||
@@ -724,14 +1115,18 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
724 | c=tolower(c); | 1115 | c=tolower(c); |
725 | 1116 | ||
726 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && | 1117 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && |
727 | ((I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty)) || | 1118 | I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) && |
728 | c == INTR_CHAR(tty) || c == QUIT_CHAR(tty) || c == SUSP_CHAR(tty))) | 1119 | c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) { |
729 | start_tty(tty); | 1120 | start_tty(tty); |
1121 | process_echoes(tty); | ||
1122 | } | ||
730 | 1123 | ||
731 | if (tty->closing) { | 1124 | if (tty->closing) { |
732 | if (I_IXON(tty)) { | 1125 | if (I_IXON(tty)) { |
733 | if (c == START_CHAR(tty)) | 1126 | if (c == START_CHAR(tty)) { |
734 | start_tty(tty); | 1127 | start_tty(tty); |
1128 | process_echoes(tty); | ||
1129 | } | ||
735 | else if (c == STOP_CHAR(tty)) | 1130 | else if (c == STOP_CHAR(tty)) |
736 | stop_tty(tty); | 1131 | stop_tty(tty); |
737 | } | 1132 | } |
@@ -745,17 +1140,20 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
745 | * up. | 1140 | * up. |
746 | */ | 1141 | */ |
747 | if (!test_bit(c, tty->process_char_map) || tty->lnext) { | 1142 | if (!test_bit(c, tty->process_char_map) || tty->lnext) { |
748 | finish_erasing(tty); | ||
749 | tty->lnext = 0; | 1143 | tty->lnext = 0; |
750 | if (L_ECHO(tty)) { | 1144 | if (L_ECHO(tty)) { |
1145 | finish_erasing(tty); | ||
751 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { | 1146 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { |
752 | tty_put_char(tty, '\a'); /* beep if no space */ | 1147 | /* beep if no space */ |
1148 | echo_char_raw('\a', tty); | ||
1149 | process_echoes(tty); | ||
753 | return; | 1150 | return; |
754 | } | 1151 | } |
755 | /* Record the column of first canon char. */ | 1152 | /* Record the column of first canon char. */ |
756 | if (tty->canon_head == tty->read_head) | 1153 | if (tty->canon_head == tty->read_head) |
757 | tty->canon_column = tty->column; | 1154 | echo_set_canon_col(tty); |
758 | echo_char(c, tty); | 1155 | echo_char(c, tty); |
1156 | process_echoes(tty); | ||
759 | } | 1157 | } |
760 | if (I_PARMRK(tty) && c == (unsigned char) '\377') | 1158 | if (I_PARMRK(tty) && c == (unsigned char) '\377') |
761 | put_tty_queue(c, tty); | 1159 | put_tty_queue(c, tty); |
@@ -766,6 +1164,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
766 | if (I_IXON(tty)) { | 1164 | if (I_IXON(tty)) { |
767 | if (c == START_CHAR(tty)) { | 1165 | if (c == START_CHAR(tty)) { |
768 | start_tty(tty); | 1166 | start_tty(tty); |
1167 | process_echoes(tty); | ||
769 | return; | 1168 | return; |
770 | } | 1169 | } |
771 | if (c == STOP_CHAR(tty)) { | 1170 | if (c == STOP_CHAR(tty)) { |
@@ -786,7 +1185,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
786 | if (c == SUSP_CHAR(tty)) { | 1185 | if (c == SUSP_CHAR(tty)) { |
787 | send_signal: | 1186 | send_signal: |
788 | /* | 1187 | /* |
789 | * Echo character, and then send the signal. | ||
790 | * Note that we do not use isig() here because we want | 1188 | * Note that we do not use isig() here because we want |
791 | * the order to be: | 1189 | * the order to be: |
792 | * 1) flush, 2) echo, 3) signal | 1190 | * 1) flush, 2) echo, 3) signal |
@@ -795,8 +1193,12 @@ send_signal: | |||
795 | n_tty_flush_buffer(tty); | 1193 | n_tty_flush_buffer(tty); |
796 | tty_driver_flush_buffer(tty); | 1194 | tty_driver_flush_buffer(tty); |
797 | } | 1195 | } |
798 | if (L_ECHO(tty)) | 1196 | if (I_IXON(tty)) |
1197 | start_tty(tty); | ||
1198 | if (L_ECHO(tty)) { | ||
799 | echo_char(c, tty); | 1199 | echo_char(c, tty); |
1200 | process_echoes(tty); | ||
1201 | } | ||
800 | if (tty->pgrp) | 1202 | if (tty->pgrp) |
801 | kill_pgrp(tty->pgrp, signal, 1); | 1203 | kill_pgrp(tty->pgrp, signal, 1); |
802 | return; | 1204 | return; |
@@ -815,6 +1217,7 @@ send_signal: | |||
815 | if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || | 1217 | if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || |
816 | (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { | 1218 | (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { |
817 | eraser(c, tty); | 1219 | eraser(c, tty); |
1220 | process_echoes(tty); | ||
818 | return; | 1221 | return; |
819 | } | 1222 | } |
820 | if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { | 1223 | if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { |
@@ -822,8 +1225,9 @@ send_signal: | |||
822 | if (L_ECHO(tty)) { | 1225 | if (L_ECHO(tty)) { |
823 | finish_erasing(tty); | 1226 | finish_erasing(tty); |
824 | if (L_ECHOCTL(tty)) { | 1227 | if (L_ECHOCTL(tty)) { |
825 | tty_put_char(tty, '^'); | 1228 | echo_char_raw('^', tty); |
826 | tty_put_char(tty, '\b'); | 1229 | echo_char_raw('\b', tty); |
1230 | process_echoes(tty); | ||
827 | } | 1231 | } |
828 | } | 1232 | } |
829 | return; | 1233 | return; |
@@ -834,18 +1238,20 @@ send_signal: | |||
834 | 1238 | ||
835 | finish_erasing(tty); | 1239 | finish_erasing(tty); |
836 | echo_char(c, tty); | 1240 | echo_char(c, tty); |
837 | opost('\n', tty); | 1241 | echo_char_raw('\n', tty); |
838 | while (tail != tty->read_head) { | 1242 | while (tail != tty->read_head) { |
839 | echo_char(tty->read_buf[tail], tty); | 1243 | echo_char(tty->read_buf[tail], tty); |
840 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | 1244 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); |
841 | } | 1245 | } |
1246 | process_echoes(tty); | ||
842 | return; | 1247 | return; |
843 | } | 1248 | } |
844 | if (c == '\n') { | 1249 | if (c == '\n') { |
845 | if (L_ECHO(tty) || L_ECHONL(tty)) { | 1250 | if (L_ECHO(tty) || L_ECHONL(tty)) { |
846 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) | 1251 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) |
847 | tty_put_char(tty, '\a'); | 1252 | echo_char_raw('\a', tty); |
848 | opost('\n', tty); | 1253 | echo_char_raw('\n', tty); |
1254 | process_echoes(tty); | ||
849 | } | 1255 | } |
850 | goto handle_newline; | 1256 | goto handle_newline; |
851 | } | 1257 | } |
@@ -862,11 +1268,12 @@ send_signal: | |||
862 | */ | 1268 | */ |
863 | if (L_ECHO(tty)) { | 1269 | if (L_ECHO(tty)) { |
864 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) | 1270 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) |
865 | tty_put_char(tty, '\a'); | 1271 | echo_char_raw('\a', tty); |
866 | /* Record the column of first canon char. */ | 1272 | /* Record the column of first canon char. */ |
867 | if (tty->canon_head == tty->read_head) | 1273 | if (tty->canon_head == tty->read_head) |
868 | tty->canon_column = tty->column; | 1274 | echo_set_canon_col(tty); |
869 | echo_char(c, tty); | 1275 | echo_char(c, tty); |
1276 | process_echoes(tty); | ||
870 | } | 1277 | } |
871 | /* | 1278 | /* |
872 | * XXX does PARMRK doubling happen for | 1279 | * XXX does PARMRK doubling happen for |
@@ -889,20 +1296,23 @@ handle_newline: | |||
889 | } | 1296 | } |
890 | } | 1297 | } |
891 | 1298 | ||
892 | finish_erasing(tty); | ||
893 | if (L_ECHO(tty)) { | 1299 | if (L_ECHO(tty)) { |
1300 | finish_erasing(tty); | ||
894 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { | 1301 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { |
895 | tty_put_char(tty, '\a'); /* beep if no space */ | 1302 | /* beep if no space */ |
1303 | echo_char_raw('\a', tty); | ||
1304 | process_echoes(tty); | ||
896 | return; | 1305 | return; |
897 | } | 1306 | } |
898 | if (c == '\n') | 1307 | if (c == '\n') |
899 | opost('\n', tty); | 1308 | echo_char_raw('\n', tty); |
900 | else { | 1309 | else { |
901 | /* Record the column of first canon char. */ | 1310 | /* Record the column of first canon char. */ |
902 | if (tty->canon_head == tty->read_head) | 1311 | if (tty->canon_head == tty->read_head) |
903 | tty->canon_column = tty->column; | 1312 | echo_set_canon_col(tty); |
904 | echo_char(c, tty); | 1313 | echo_char(c, tty); |
905 | } | 1314 | } |
1315 | process_echoes(tty); | ||
906 | } | 1316 | } |
907 | 1317 | ||
908 | if (I_PARMRK(tty) && c == (unsigned char) '\377') | 1318 | if (I_PARMRK(tty) && c == (unsigned char) '\377') |
@@ -923,6 +1333,9 @@ handle_newline: | |||
923 | 1333 | ||
924 | static void n_tty_write_wakeup(struct tty_struct *tty) | 1334 | static void n_tty_write_wakeup(struct tty_struct *tty) |
925 | { | 1335 | { |
1336 | /* Write out any echoed characters that are still pending */ | ||
1337 | process_echoes(tty); | ||
1338 | |||
926 | if (tty->fasync) { | 1339 | if (tty->fasync) { |
927 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 1340 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
928 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); | 1341 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); |
@@ -1134,6 +1547,10 @@ static void n_tty_close(struct tty_struct *tty) | |||
1134 | free_buf(tty->read_buf); | 1547 | free_buf(tty->read_buf); |
1135 | tty->read_buf = NULL; | 1548 | tty->read_buf = NULL; |
1136 | } | 1549 | } |
1550 | if (tty->echo_buf) { | ||
1551 | free_buf(tty->echo_buf); | ||
1552 | tty->echo_buf = NULL; | ||
1553 | } | ||
1137 | } | 1554 | } |
1138 | 1555 | ||
1139 | /** | 1556 | /** |
@@ -1151,13 +1568,19 @@ static int n_tty_open(struct tty_struct *tty) | |||
1151 | if (!tty) | 1568 | if (!tty) |
1152 | return -EINVAL; | 1569 | return -EINVAL; |
1153 | 1570 | ||
1154 | /* This one is ugly. Currently a malloc failure here can panic */ | 1571 | /* These are ugly. Currently a malloc failure here can panic */ |
1155 | if (!tty->read_buf) { | 1572 | if (!tty->read_buf) { |
1156 | tty->read_buf = alloc_buf(); | 1573 | tty->read_buf = alloc_buf(); |
1157 | if (!tty->read_buf) | 1574 | if (!tty->read_buf) |
1158 | return -ENOMEM; | 1575 | return -ENOMEM; |
1159 | } | 1576 | } |
1577 | if (!tty->echo_buf) { | ||
1578 | tty->echo_buf = alloc_buf(); | ||
1579 | if (!tty->echo_buf) | ||
1580 | return -ENOMEM; | ||
1581 | } | ||
1160 | memset(tty->read_buf, 0, N_TTY_BUF_SIZE); | 1582 | memset(tty->read_buf, 0, N_TTY_BUF_SIZE); |
1583 | memset(tty->echo_buf, 0, N_TTY_BUF_SIZE); | ||
1161 | reset_buffer_flags(tty); | 1584 | reset_buffer_flags(tty); |
1162 | tty->column = 0; | 1585 | tty->column = 0; |
1163 | n_tty_set_termios(tty, NULL); | 1586 | n_tty_set_termios(tty, NULL); |
@@ -1487,16 +1910,23 @@ do_it_again: | |||
1487 | * @buf: userspace buffer pointer | 1910 | * @buf: userspace buffer pointer |
1488 | * @nr: size of I/O | 1911 | * @nr: size of I/O |
1489 | * | 1912 | * |
1490 | * Write function of the terminal device. This is serialized with | 1913 | * Write function of the terminal device. This is serialized with |
1491 | * respect to other write callers but not to termios changes, reads | 1914 | * respect to other write callers but not to termios changes, reads |
1492 | * and other such events. We must be careful with N_TTY as the receive | 1915 | * and other such events. Since the receive code will echo characters, |
1493 | * code will echo characters, thus calling driver write methods. | 1916 | * thus calling driver write methods, the output_lock is used in |
1917 | * the output processing functions called here as well as in the | ||
1918 | * echo processing function to protect the column state and space | ||
1919 | * left in the buffer. | ||
1494 | * | 1920 | * |
1495 | * This code must be sure never to sleep through a hangup. | 1921 | * This code must be sure never to sleep through a hangup. |
1922 | * | ||
1923 | * Locking: output_lock to protect column state and space left | ||
1924 | * (note that the process_output*() functions take this | ||
1925 | * lock themselves) | ||
1496 | */ | 1926 | */ |
1497 | 1927 | ||
1498 | static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | 1928 | static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, |
1499 | const unsigned char *buf, size_t nr) | 1929 | const unsigned char *buf, size_t nr) |
1500 | { | 1930 | { |
1501 | const unsigned char *b = buf; | 1931 | const unsigned char *b = buf; |
1502 | DECLARE_WAITQUEUE(wait, current); | 1932 | DECLARE_WAITQUEUE(wait, current); |
@@ -1510,6 +1940,9 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | |||
1510 | return retval; | 1940 | return retval; |
1511 | } | 1941 | } |
1512 | 1942 | ||
1943 | /* Write out any echoed characters that are still pending */ | ||
1944 | process_echoes(tty); | ||
1945 | |||
1513 | add_wait_queue(&tty->write_wait, &wait); | 1946 | add_wait_queue(&tty->write_wait, &wait); |
1514 | while (1) { | 1947 | while (1) { |
1515 | set_current_state(TASK_INTERRUPTIBLE); | 1948 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -1523,7 +1956,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | |||
1523 | } | 1956 | } |
1524 | if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) { | 1957 | if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) { |
1525 | while (nr > 0) { | 1958 | while (nr > 0) { |
1526 | ssize_t num = opost_block(tty, b, nr); | 1959 | ssize_t num = process_output_block(tty, b, nr); |
1527 | if (num < 0) { | 1960 | if (num < 0) { |
1528 | if (num == -EAGAIN) | 1961 | if (num == -EAGAIN) |
1529 | break; | 1962 | break; |
@@ -1535,7 +1968,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | |||
1535 | if (nr == 0) | 1968 | if (nr == 0) |
1536 | break; | 1969 | break; |
1537 | c = *b; | 1970 | c = *b; |
1538 | if (opost(c, tty) < 0) | 1971 | if (process_output(c, tty) < 0) |
1539 | break; | 1972 | break; |
1540 | b++; nr--; | 1973 | b++; nr--; |
1541 | } | 1974 | } |
@@ -1663,4 +2096,3 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { | |||
1663 | .receive_buf = n_tty_receive_buf, | 2096 | .receive_buf = n_tty_receive_buf, |
1664 | .write_wakeup = n_tty_write_wakeup | 2097 | .write_wakeup = n_tty_write_wakeup |
1665 | }; | 2098 | }; |
1666 | |||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index db15f9ba7c0b..d8d240c8a25a 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1111,9 +1111,7 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1111 | * Locks the line discipline as required | 1111 | * Locks the line discipline as required |
1112 | * Writes to the tty driver are serialized by the atomic_write_lock | 1112 | * Writes to the tty driver are serialized by the atomic_write_lock |
1113 | * and are then processed in chunks to the device. The line discipline | 1113 | * and are then processed in chunks to the device. The line discipline |
1114 | * write method will not be involked in parallel for each device | 1114 | * write method will not be invoked in parallel for each device. |
1115 | * The line discipline write method is called under the big | ||
1116 | * kernel lock for historical reasons. New code should not rely on this. | ||
1117 | */ | 1115 | */ |
1118 | 1116 | ||
1119 | static ssize_t tty_write(struct file *file, const char __user *buf, | 1117 | static ssize_t tty_write(struct file *file, const char __user *buf, |
@@ -2785,6 +2783,8 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2785 | INIT_WORK(&tty->hangup_work, do_tty_hangup); | 2783 | INIT_WORK(&tty->hangup_work, do_tty_hangup); |
2786 | mutex_init(&tty->atomic_read_lock); | 2784 | mutex_init(&tty->atomic_read_lock); |
2787 | mutex_init(&tty->atomic_write_lock); | 2785 | mutex_init(&tty->atomic_write_lock); |
2786 | mutex_init(&tty->output_lock); | ||
2787 | mutex_init(&tty->echo_lock); | ||
2788 | spin_lock_init(&tty->read_lock); | 2788 | spin_lock_init(&tty->read_lock); |
2789 | spin_lock_init(&tty->ctrl_lock); | 2789 | spin_lock_init(&tty->ctrl_lock); |
2790 | INIT_LIST_HEAD(&tty->tty_files); | 2790 | INIT_LIST_HEAD(&tty->tty_files); |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 008176edbd64..639e126b2bff 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -2679,7 +2679,7 @@ static int con_write_room(struct tty_struct *tty) | |||
2679 | { | 2679 | { |
2680 | if (tty->stopped) | 2680 | if (tty->stopped) |
2681 | return 0; | 2681 | return 0; |
2682 | return 4096; /* No limit, really; we're not buffering */ | 2682 | return 32768; /* No limit, really; we're not buffering */ |
2683 | } | 2683 | } |
2684 | 2684 | ||
2685 | static int con_chars_in_buffer(struct tty_struct *tty) | 2685 | static int con_chars_in_buffer(struct tty_struct *tty) |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 3f4954c55e53..dfc77ded198a 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -253,6 +253,7 @@ struct tty_struct { | |||
253 | unsigned int column; | 253 | unsigned int column; |
254 | unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1; | 254 | unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1; |
255 | unsigned char closing:1; | 255 | unsigned char closing:1; |
256 | unsigned char echo_overrun:1; | ||
256 | unsigned short minimum_to_wake; | 257 | unsigned short minimum_to_wake; |
257 | unsigned long overrun_time; | 258 | unsigned long overrun_time; |
258 | int num_overrun; | 259 | int num_overrun; |
@@ -262,11 +263,16 @@ struct tty_struct { | |||
262 | int read_tail; | 263 | int read_tail; |
263 | int read_cnt; | 264 | int read_cnt; |
264 | unsigned long read_flags[N_TTY_BUF_SIZE/(8*sizeof(unsigned long))]; | 265 | unsigned long read_flags[N_TTY_BUF_SIZE/(8*sizeof(unsigned long))]; |
266 | unsigned char *echo_buf; | ||
267 | unsigned int echo_pos; | ||
268 | unsigned int echo_cnt; | ||
265 | int canon_data; | 269 | int canon_data; |
266 | unsigned long canon_head; | 270 | unsigned long canon_head; |
267 | unsigned int canon_column; | 271 | unsigned int canon_column; |
268 | struct mutex atomic_read_lock; | 272 | struct mutex atomic_read_lock; |
269 | struct mutex atomic_write_lock; | 273 | struct mutex atomic_write_lock; |
274 | struct mutex output_lock; | ||
275 | struct mutex echo_lock; | ||
270 | unsigned char *write_buf; | 276 | unsigned char *write_buf; |
271 | int write_cnt; | 277 | int write_cnt; |
272 | spinlock_t read_lock; | 278 | spinlock_t read_lock; |