diff options
Diffstat (limited to 'drivers/char/n_tty.c')
-rw-r--r-- | drivers/char/n_tty.c | 792 |
1 files changed, 620 insertions, 172 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index efbfe9612658..f6f0e4ec2b51 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -47,8 +47,8 @@ | |||
47 | #include <linux/bitops.h> | 47 | #include <linux/bitops.h> |
48 | #include <linux/audit.h> | 48 | #include <linux/audit.h> |
49 | #include <linux/file.h> | 49 | #include <linux/file.h> |
50 | #include <linux/uaccess.h> | ||
50 | 51 | ||
51 | #include <asm/uaccess.h> | ||
52 | #include <asm/system.h> | 52 | #include <asm/system.h> |
53 | 53 | ||
54 | /* number of characters left in xmit buffer before select has we have room */ | 54 | /* number of characters left in xmit buffer before select has we have room */ |
@@ -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,118 @@ 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. | ||
298 | * | ||
299 | * Returns the number of bytes of buffer space used or -1 if | ||
300 | * no space left. | ||
277 | * | 301 | * |
278 | * Called from both the receive and transmit sides and can be called | 302 | * Locking: should be called under the output_lock to protect |
279 | * re-entrantly. Relies on lock_kernel() for tty->column state. | 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) | 346 | } |
335 | tty->column--; | 347 | tty->column += spaces; |
336 | break; | 348 | break; |
337 | default: | 349 | case '\b': |
350 | if (tty->column > 0) | ||
351 | tty->column--; | ||
352 | break; | ||
353 | default: | ||
354 | if (!iscntrl(c)) { | ||
338 | if (O_OLCUC(tty)) | 355 | if (O_OLCUC(tty)) |
339 | c = toupper(c); | 356 | c = toupper(c); |
340 | if (!iscntrl(c) && !is_continuation(c, tty)) | 357 | if (!is_continuation(c, tty)) |
341 | tty->column++; | 358 | tty->column++; |
342 | break; | ||
343 | } | 359 | } |
360 | break; | ||
344 | } | 361 | } |
362 | |||
345 | tty_put_char(tty, c); | 363 | tty_put_char(tty, c); |
346 | unlock_kernel(); | 364 | return 1; |
347 | return 0; | ||
348 | } | 365 | } |
349 | 366 | ||
350 | /** | 367 | /** |
351 | * opost_block - block postprocess | 368 | * process_output - output post processor |
369 | * @c: character (or partial unicode symbol) | ||
370 | * @tty: terminal device | ||
371 | * | ||
372 | * Perform OPOST processing. Returns -1 when the output device is | ||
373 | * full and the character must be retried. | ||
374 | * | ||
375 | * Locking: output_lock to protect column state and space left | ||
376 | * (also, this is called from n_tty_write under the | ||
377 | * tty layer write lock) | ||
378 | */ | ||
379 | |||
380 | static int process_output(unsigned char c, struct tty_struct *tty) | ||
381 | { | ||
382 | int space, retval; | ||
383 | |||
384 | mutex_lock(&tty->output_lock); | ||
385 | |||
386 | space = tty_write_room(tty); | ||
387 | retval = do_output_char(c, tty, space); | ||
388 | |||
389 | mutex_unlock(&tty->output_lock); | ||
390 | if (retval < 0) | ||
391 | return -1; | ||
392 | else | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * process_output_block - block post processor | ||
352 | * @tty: terminal device | 398 | * @tty: terminal device |
353 | * @inbuf: user buffer | 399 | * @inbuf: user buffer |
354 | * @nr: number of bytes | 400 | * @nr: number of bytes |
@@ -358,26 +404,32 @@ static int opost(unsigned char c, struct tty_struct *tty) | |||
358 | * the simple cases normally found and helps to generate blocks of | 404 | * the simple cases normally found and helps to generate blocks of |
359 | * symbols for the console driver and thus improve performance. | 405 | * symbols for the console driver and thus improve performance. |
360 | * | 406 | * |
361 | * Called from n_tty_write under the tty layer write lock. Relies | 407 | * Locking: output_lock to protect column state and space left |
362 | * on lock_kernel for the tty->column state. | 408 | * (also, this is called from n_tty_write under the |
409 | * tty layer write lock) | ||
363 | */ | 410 | */ |
364 | 411 | ||
365 | static ssize_t opost_block(struct tty_struct *tty, | 412 | static ssize_t process_output_block(struct tty_struct *tty, |
366 | const unsigned char *buf, unsigned int nr) | 413 | const unsigned char *buf, unsigned int nr) |
367 | { | 414 | { |
368 | int space; | 415 | int space; |
369 | int i; | 416 | int i; |
370 | const unsigned char *cp; | 417 | const unsigned char *cp; |
371 | 418 | ||
419 | mutex_lock(&tty->output_lock); | ||
420 | |||
372 | space = tty_write_room(tty); | 421 | space = tty_write_room(tty); |
373 | if (!space) | 422 | if (!space) { |
423 | mutex_unlock(&tty->output_lock); | ||
374 | return 0; | 424 | return 0; |
425 | } | ||
375 | if (nr > space) | 426 | if (nr > space) |
376 | nr = space; | 427 | nr = space; |
377 | 428 | ||
378 | lock_kernel(); | ||
379 | for (i = 0, cp = buf; i < nr; i++, cp++) { | 429 | for (i = 0, cp = buf; i < nr; i++, cp++) { |
380 | switch (*cp) { | 430 | unsigned char c = *cp; |
431 | |||
432 | switch (c) { | ||
381 | case '\n': | 433 | case '\n': |
382 | if (O_ONLRET(tty)) | 434 | if (O_ONLRET(tty)) |
383 | tty->column = 0; | 435 | tty->column = 0; |
@@ -399,54 +451,403 @@ static ssize_t opost_block(struct tty_struct *tty, | |||
399 | tty->column--; | 451 | tty->column--; |
400 | break; | 452 | break; |
401 | default: | 453 | default: |
402 | if (O_OLCUC(tty)) | 454 | if (!iscntrl(c)) { |
403 | goto break_out; | 455 | if (O_OLCUC(tty)) |
404 | if (!iscntrl(*cp)) | 456 | goto break_out; |
405 | tty->column++; | 457 | if (!is_continuation(c, tty)) |
458 | tty->column++; | ||
459 | } | ||
406 | break; | 460 | break; |
407 | } | 461 | } |
408 | } | 462 | } |
409 | break_out: | 463 | break_out: |
410 | if (tty->ops->flush_chars) | ||
411 | tty->ops->flush_chars(tty); | ||
412 | i = tty->ops->write(tty, buf, i); | 464 | i = tty->ops->write(tty, buf, i); |
413 | unlock_kernel(); | 465 | |
466 | mutex_unlock(&tty->output_lock); | ||
414 | return i; | 467 | return i; |
415 | } | 468 | } |
416 | 469 | ||
470 | /** | ||
471 | * process_echoes - write pending echo characters | ||
472 | * @tty: terminal device | ||
473 | * | ||
474 | * Write previously buffered echo (and other ldisc-generated) | ||
475 | * characters to the tty. | ||
476 | * | ||
477 | * Characters generated by the ldisc (including echoes) need to | ||
478 | * be buffered because the driver's write buffer can fill during | ||
479 | * heavy program output. Echoing straight to the driver will | ||
480 | * often fail under these conditions, causing lost characters and | ||
481 | * resulting mismatches of ldisc state information. | ||
482 | * | ||
483 | * Since the ldisc state must represent the characters actually sent | ||
484 | * to the driver at the time of the write, operations like certain | ||
485 | * changes in column state are also saved in the buffer and executed | ||
486 | * here. | ||
487 | * | ||
488 | * A circular fifo buffer is used so that the most recent characters | ||
489 | * are prioritized. Also, when control characters are echoed with a | ||
490 | * prefixed "^", the pair is treated atomically and thus not separated. | ||
491 | * | ||
492 | * Locking: output_lock to protect column state and space left, | ||
493 | * echo_lock to protect the echo buffer | ||
494 | */ | ||
495 | |||
496 | static void process_echoes(struct tty_struct *tty) | ||
497 | { | ||
498 | int space, nr; | ||
499 | unsigned char c; | ||
500 | unsigned char *cp, *buf_end; | ||
501 | |||
502 | if (!tty->echo_cnt) | ||
503 | return; | ||
504 | |||
505 | mutex_lock(&tty->output_lock); | ||
506 | mutex_lock(&tty->echo_lock); | ||
507 | |||
508 | space = tty_write_room(tty); | ||
509 | |||
510 | buf_end = tty->echo_buf + N_TTY_BUF_SIZE; | ||
511 | cp = tty->echo_buf + tty->echo_pos; | ||
512 | nr = tty->echo_cnt; | ||
513 | while (nr > 0) { | ||
514 | c = *cp; | ||
515 | if (c == ECHO_OP_START) { | ||
516 | unsigned char op; | ||
517 | unsigned char *opp; | ||
518 | int no_space_left = 0; | ||
519 | |||
520 | /* | ||
521 | * If the buffer byte is the start of a multi-byte | ||
522 | * operation, get the next byte, which is either the | ||
523 | * op code or a control character value. | ||
524 | */ | ||
525 | opp = cp + 1; | ||
526 | if (opp == buf_end) | ||
527 | opp -= N_TTY_BUF_SIZE; | ||
528 | op = *opp; | ||
529 | |||
530 | switch (op) { | ||
531 | unsigned int num_chars, num_bs; | ||
532 | |||
533 | case ECHO_OP_ERASE_TAB: | ||
534 | if (++opp == buf_end) | ||
535 | opp -= N_TTY_BUF_SIZE; | ||
536 | num_chars = *opp; | ||
537 | |||
538 | /* | ||
539 | * Determine how many columns to go back | ||
540 | * in order to erase the tab. | ||
541 | * This depends on the number of columns | ||
542 | * used by other characters within the tab | ||
543 | * area. If this (modulo 8) count is from | ||
544 | * the start of input rather than from a | ||
545 | * previous tab, we offset by canon column. | ||
546 | * Otherwise, tab spacing is normal. | ||
547 | */ | ||
548 | if (!(num_chars & 0x80)) | ||
549 | num_chars += tty->canon_column; | ||
550 | num_bs = 8 - (num_chars & 7); | ||
551 | |||
552 | if (num_bs > space) { | ||
553 | no_space_left = 1; | ||
554 | break; | ||
555 | } | ||
556 | space -= num_bs; | ||
557 | while (num_bs--) { | ||
558 | tty_put_char(tty, '\b'); | ||
559 | if (tty->column > 0) | ||
560 | tty->column--; | ||
561 | } | ||
562 | cp += 3; | ||
563 | nr -= 3; | ||
564 | break; | ||
565 | |||
566 | case ECHO_OP_SET_CANON_COL: | ||
567 | tty->canon_column = tty->column; | ||
568 | cp += 2; | ||
569 | nr -= 2; | ||
570 | break; | ||
571 | |||
572 | case ECHO_OP_MOVE_BACK_COL: | ||
573 | if (tty->column > 0) | ||
574 | tty->column--; | ||
575 | cp += 2; | ||
576 | nr -= 2; | ||
577 | break; | ||
578 | |||
579 | case ECHO_OP_START: | ||
580 | /* This is an escaped echo op start code */ | ||
581 | if (!space) { | ||
582 | no_space_left = 1; | ||
583 | break; | ||
584 | } | ||
585 | tty_put_char(tty, ECHO_OP_START); | ||
586 | tty->column++; | ||
587 | space--; | ||
588 | cp += 2; | ||
589 | nr -= 2; | ||
590 | break; | ||
591 | |||
592 | default: | ||
593 | if (iscntrl(op)) { | ||
594 | if (L_ECHOCTL(tty)) { | ||
595 | /* | ||
596 | * Ensure there is enough space | ||
597 | * for the whole ctrl pair. | ||
598 | */ | ||
599 | if (space < 2) { | ||
600 | no_space_left = 1; | ||
601 | break; | ||
602 | } | ||
603 | tty_put_char(tty, '^'); | ||
604 | tty_put_char(tty, op ^ 0100); | ||
605 | tty->column += 2; | ||
606 | space -= 2; | ||
607 | } else { | ||
608 | if (!space) { | ||
609 | no_space_left = 1; | ||
610 | break; | ||
611 | } | ||
612 | tty_put_char(tty, op); | ||
613 | space--; | ||
614 | } | ||
615 | } | ||
616 | /* | ||
617 | * If above falls through, this was an | ||
618 | * undefined op. | ||
619 | */ | ||
620 | cp += 2; | ||
621 | nr -= 2; | ||
622 | } | ||
623 | |||
624 | if (no_space_left) | ||
625 | break; | ||
626 | } else { | ||
627 | int retval; | ||
628 | |||
629 | retval = do_output_char(c, tty, space); | ||
630 | if (retval < 0) | ||
631 | break; | ||
632 | space -= retval; | ||
633 | cp += 1; | ||
634 | nr -= 1; | ||
635 | } | ||
636 | |||
637 | /* When end of circular buffer reached, wrap around */ | ||
638 | if (cp >= buf_end) | ||
639 | cp -= N_TTY_BUF_SIZE; | ||
640 | } | ||
641 | |||
642 | if (nr == 0) { | ||
643 | tty->echo_pos = 0; | ||
644 | tty->echo_cnt = 0; | ||
645 | tty->echo_overrun = 0; | ||
646 | } else { | ||
647 | int num_processed = tty->echo_cnt - nr; | ||
648 | tty->echo_pos += num_processed; | ||
649 | tty->echo_pos &= N_TTY_BUF_SIZE - 1; | ||
650 | tty->echo_cnt = nr; | ||
651 | if (num_processed > 0) | ||
652 | tty->echo_overrun = 0; | ||
653 | } | ||
654 | |||
655 | mutex_unlock(&tty->echo_lock); | ||
656 | mutex_unlock(&tty->output_lock); | ||
657 | |||
658 | if (tty->ops->flush_chars) | ||
659 | tty->ops->flush_chars(tty); | ||
660 | } | ||
417 | 661 | ||
418 | /** | 662 | /** |
419 | * echo_char - echo characters | 663 | * add_echo_byte - add a byte to the echo buffer |
664 | * @c: unicode byte to echo | ||
665 | * @tty: terminal device | ||
666 | * | ||
667 | * Add a character or operation byte to the echo buffer. | ||
668 | * | ||
669 | * Should be called under the echo lock to protect the echo buffer. | ||
670 | */ | ||
671 | |||
672 | static void add_echo_byte(unsigned char c, struct tty_struct *tty) | ||
673 | { | ||
674 | int new_byte_pos; | ||
675 | |||
676 | if (tty->echo_cnt == N_TTY_BUF_SIZE) { | ||
677 | /* Circular buffer is already at capacity */ | ||
678 | new_byte_pos = tty->echo_pos; | ||
679 | |||
680 | /* | ||
681 | * Since the buffer start position needs to be advanced, | ||
682 | * be sure to step by a whole operation byte group. | ||
683 | */ | ||
684 | if (tty->echo_buf[tty->echo_pos] == ECHO_OP_START) { | ||
685 | if (tty->echo_buf[(tty->echo_pos + 1) & | ||
686 | (N_TTY_BUF_SIZE - 1)] == | ||
687 | ECHO_OP_ERASE_TAB) { | ||
688 | tty->echo_pos += 3; | ||
689 | tty->echo_cnt -= 2; | ||
690 | } else { | ||
691 | tty->echo_pos += 2; | ||
692 | tty->echo_cnt -= 1; | ||
693 | } | ||
694 | } else { | ||
695 | tty->echo_pos++; | ||
696 | } | ||
697 | tty->echo_pos &= N_TTY_BUF_SIZE - 1; | ||
698 | |||
699 | tty->echo_overrun = 1; | ||
700 | } else { | ||
701 | new_byte_pos = tty->echo_pos + tty->echo_cnt; | ||
702 | new_byte_pos &= N_TTY_BUF_SIZE - 1; | ||
703 | tty->echo_cnt++; | ||
704 | } | ||
705 | |||
706 | tty->echo_buf[new_byte_pos] = c; | ||
707 | } | ||
708 | |||
709 | /** | ||
710 | * echo_move_back_col - add operation to move back a column | ||
711 | * @tty: terminal device | ||
712 | * | ||
713 | * Add an operation to the echo buffer to move back one column. | ||
714 | * | ||
715 | * Locking: echo_lock to protect the echo buffer | ||
716 | */ | ||
717 | |||
718 | static void echo_move_back_col(struct tty_struct *tty) | ||
719 | { | ||
720 | mutex_lock(&tty->echo_lock); | ||
721 | |||
722 | add_echo_byte(ECHO_OP_START, tty); | ||
723 | add_echo_byte(ECHO_OP_MOVE_BACK_COL, tty); | ||
724 | |||
725 | mutex_unlock(&tty->echo_lock); | ||
726 | } | ||
727 | |||
728 | /** | ||
729 | * echo_set_canon_col - add operation to set the canon column | ||
730 | * @tty: terminal device | ||
731 | * | ||
732 | * Add an operation to the echo buffer to set the canon column | ||
733 | * to the current column. | ||
734 | * | ||
735 | * Locking: echo_lock to protect the echo buffer | ||
736 | */ | ||
737 | |||
738 | static void echo_set_canon_col(struct tty_struct *tty) | ||
739 | { | ||
740 | mutex_lock(&tty->echo_lock); | ||
741 | |||
742 | add_echo_byte(ECHO_OP_START, tty); | ||
743 | add_echo_byte(ECHO_OP_SET_CANON_COL, tty); | ||
744 | |||
745 | mutex_unlock(&tty->echo_lock); | ||
746 | } | ||
747 | |||
748 | /** | ||
749 | * echo_erase_tab - add operation to erase a tab | ||
750 | * @num_chars: number of character columns already used | ||
751 | * @after_tab: true if num_chars starts after a previous tab | ||
752 | * @tty: terminal device | ||
753 | * | ||
754 | * Add an operation to the echo buffer to erase a tab. | ||
755 | * | ||
756 | * Called by the eraser function, which knows how many character | ||
757 | * columns have been used since either a previous tab or the start | ||
758 | * of input. This information will be used later, along with | ||
759 | * canon column (if applicable), to go back the correct number | ||
760 | * of columns. | ||
761 | * | ||
762 | * Locking: echo_lock to protect the echo buffer | ||
763 | */ | ||
764 | |||
765 | static void echo_erase_tab(unsigned int num_chars, int after_tab, | ||
766 | struct tty_struct *tty) | ||
767 | { | ||
768 | mutex_lock(&tty->echo_lock); | ||
769 | |||
770 | add_echo_byte(ECHO_OP_START, tty); | ||
771 | add_echo_byte(ECHO_OP_ERASE_TAB, tty); | ||
772 | |||
773 | /* We only need to know this modulo 8 (tab spacing) */ | ||
774 | num_chars &= 7; | ||
775 | |||
776 | /* Set the high bit as a flag if num_chars is after a previous tab */ | ||
777 | if (after_tab) | ||
778 | num_chars |= 0x80; | ||
779 | |||
780 | add_echo_byte(num_chars, tty); | ||
781 | |||
782 | mutex_unlock(&tty->echo_lock); | ||
783 | } | ||
784 | |||
785 | /** | ||
786 | * echo_char_raw - echo a character raw | ||
420 | * @c: unicode byte to echo | 787 | * @c: unicode byte to echo |
421 | * @tty: terminal device | 788 | * @tty: terminal device |
422 | * | 789 | * |
423 | * Echo user input back onto the screen. This must be called only when | 790 | * 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. | 791 | * L_ECHO(tty) is true. Called from the driver receive_buf path. |
425 | * | 792 | * |
426 | * Relies on BKL for tty column locking | 793 | * This variant does not treat control characters specially. |
794 | * | ||
795 | * Locking: echo_lock to protect the echo buffer | ||
796 | */ | ||
797 | |||
798 | static void echo_char_raw(unsigned char c, struct tty_struct *tty) | ||
799 | { | ||
800 | mutex_lock(&tty->echo_lock); | ||
801 | |||
802 | if (c == ECHO_OP_START) { | ||
803 | add_echo_byte(ECHO_OP_START, tty); | ||
804 | add_echo_byte(ECHO_OP_START, tty); | ||
805 | } else { | ||
806 | add_echo_byte(c, tty); | ||
807 | } | ||
808 | |||
809 | mutex_unlock(&tty->echo_lock); | ||
810 | } | ||
811 | |||
812 | /** | ||
813 | * echo_char - echo a character | ||
814 | * @c: unicode byte to echo | ||
815 | * @tty: terminal device | ||
816 | * | ||
817 | * Echo user input back onto the screen. This must be called only when | ||
818 | * L_ECHO(tty) is true. Called from the driver receive_buf path. | ||
819 | * | ||
820 | * This variant tags control characters to be possibly echoed as | ||
821 | * as "^X" (where X is the letter representing the control char). | ||
822 | * | ||
823 | * Locking: echo_lock to protect the echo buffer | ||
427 | */ | 824 | */ |
428 | 825 | ||
429 | static void echo_char(unsigned char c, struct tty_struct *tty) | 826 | static void echo_char(unsigned char c, struct tty_struct *tty) |
430 | { | 827 | { |
431 | if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') { | 828 | mutex_lock(&tty->echo_lock); |
432 | tty_put_char(tty, '^'); | 829 | |
433 | tty_put_char(tty, c ^ 0100); | 830 | if (c == ECHO_OP_START) { |
434 | tty->column += 2; | 831 | add_echo_byte(ECHO_OP_START, tty); |
435 | } else | 832 | add_echo_byte(ECHO_OP_START, tty); |
436 | opost(c, tty); | 833 | } else { |
834 | if (iscntrl(c) && c != '\t') | ||
835 | add_echo_byte(ECHO_OP_START, tty); | ||
836 | add_echo_byte(c, tty); | ||
837 | } | ||
838 | |||
839 | mutex_unlock(&tty->echo_lock); | ||
437 | } | 840 | } |
438 | 841 | ||
439 | /** | 842 | /** |
440 | * finsh_erasing - complete erase | 843 | * finish_erasing - complete erase |
441 | * @tty: tty doing the erase | 844 | * @tty: tty doing the erase |
442 | * | ||
443 | * Relies on BKL for tty column locking | ||
444 | */ | 845 | */ |
846 | |||
445 | static inline void finish_erasing(struct tty_struct *tty) | 847 | static inline void finish_erasing(struct tty_struct *tty) |
446 | { | 848 | { |
447 | if (tty->erasing) { | 849 | if (tty->erasing) { |
448 | tty_put_char(tty, '/'); | 850 | echo_char_raw('/', tty); |
449 | tty->column++; | ||
450 | tty->erasing = 0; | 851 | tty->erasing = 0; |
451 | } | 852 | } |
452 | } | 853 | } |
@@ -460,7 +861,7 @@ static inline void finish_erasing(struct tty_struct *tty) | |||
460 | * present in the stream from the driver layer. Handles the complexities | 861 | * present in the stream from the driver layer. Handles the complexities |
461 | * of UTF-8 multibyte symbols. | 862 | * of UTF-8 multibyte symbols. |
462 | * | 863 | * |
463 | * Locking: read_lock for tty buffers, BKL for column/erasing state | 864 | * Locking: read_lock for tty buffers |
464 | */ | 865 | */ |
465 | 866 | ||
466 | static void eraser(unsigned char c, struct tty_struct *tty) | 867 | static void eraser(unsigned char c, struct tty_struct *tty) |
@@ -471,7 +872,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
471 | 872 | ||
472 | /* FIXME: locking needed ? */ | 873 | /* FIXME: locking needed ? */ |
473 | if (tty->read_head == tty->canon_head) { | 874 | if (tty->read_head == tty->canon_head) { |
474 | /* opost('\a', tty); */ /* what do you think? */ | 875 | /* process_output('\a', tty); */ /* what do you think? */ |
475 | return; | 876 | return; |
476 | } | 877 | } |
477 | if (c == ERASE_CHAR(tty)) | 878 | if (c == ERASE_CHAR(tty)) |
@@ -497,7 +898,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
497 | echo_char(KILL_CHAR(tty), tty); | 898 | echo_char(KILL_CHAR(tty), tty); |
498 | /* Add a newline if ECHOK is on and ECHOKE is off. */ | 899 | /* Add a newline if ECHOK is on and ECHOKE is off. */ |
499 | if (L_ECHOK(tty)) | 900 | if (L_ECHOK(tty)) |
500 | opost('\n', tty); | 901 | echo_char_raw('\n', tty); |
501 | return; | 902 | return; |
502 | } | 903 | } |
503 | kill_type = KILL; | 904 | kill_type = KILL; |
@@ -533,67 +934,61 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
533 | if (L_ECHO(tty)) { | 934 | if (L_ECHO(tty)) { |
534 | if (L_ECHOPRT(tty)) { | 935 | if (L_ECHOPRT(tty)) { |
535 | if (!tty->erasing) { | 936 | if (!tty->erasing) { |
536 | tty_put_char(tty, '\\'); | 937 | echo_char_raw('\\', tty); |
537 | tty->column++; | ||
538 | tty->erasing = 1; | 938 | tty->erasing = 1; |
539 | } | 939 | } |
540 | /* if cnt > 1, output a multi-byte character */ | 940 | /* if cnt > 1, output a multi-byte character */ |
541 | echo_char(c, tty); | 941 | echo_char(c, tty); |
542 | while (--cnt > 0) { | 942 | while (--cnt > 0) { |
543 | head = (head+1) & (N_TTY_BUF_SIZE-1); | 943 | head = (head+1) & (N_TTY_BUF_SIZE-1); |
544 | tty_put_char(tty, tty->read_buf[head]); | 944 | echo_char_raw(tty->read_buf[head], tty); |
945 | echo_move_back_col(tty); | ||
545 | } | 946 | } |
546 | } else if (kill_type == ERASE && !L_ECHOE(tty)) { | 947 | } else if (kill_type == ERASE && !L_ECHOE(tty)) { |
547 | echo_char(ERASE_CHAR(tty), tty); | 948 | echo_char(ERASE_CHAR(tty), tty); |
548 | } else if (c == '\t') { | 949 | } else if (c == '\t') { |
549 | unsigned int col = tty->canon_column; | 950 | unsigned int num_chars = 0; |
550 | unsigned long tail = tty->canon_head; | 951 | int after_tab = 0; |
551 | 952 | unsigned long tail = tty->read_head; | |
552 | /* Find the column of the last char. */ | 953 | |
553 | while (tail != tty->read_head) { | 954 | /* |
955 | * Count the columns used for characters | ||
956 | * since the start of input or after a | ||
957 | * previous tab. | ||
958 | * This info is used to go back the correct | ||
959 | * number of columns. | ||
960 | */ | ||
961 | while (tail != tty->canon_head) { | ||
962 | tail = (tail-1) & (N_TTY_BUF_SIZE-1); | ||
554 | c = tty->read_buf[tail]; | 963 | c = tty->read_buf[tail]; |
555 | if (c == '\t') | 964 | if (c == '\t') { |
556 | col = (col | 7) + 1; | 965 | after_tab = 1; |
557 | else if (iscntrl(c)) { | 966 | break; |
967 | } else if (iscntrl(c)) { | ||
558 | if (L_ECHOCTL(tty)) | 968 | if (L_ECHOCTL(tty)) |
559 | col += 2; | 969 | num_chars += 2; |
560 | } else if (!is_continuation(c, tty)) | 970 | } else if (!is_continuation(c, tty)) { |
561 | col++; | 971 | num_chars++; |
562 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | 972 | } |
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 | } | 973 | } |
974 | echo_erase_tab(num_chars, after_tab, tty); | ||
576 | } else { | 975 | } else { |
577 | if (iscntrl(c) && L_ECHOCTL(tty)) { | 976 | if (iscntrl(c) && L_ECHOCTL(tty)) { |
578 | tty_put_char(tty, '\b'); | 977 | echo_char_raw('\b', tty); |
579 | tty_put_char(tty, ' '); | 978 | echo_char_raw(' ', tty); |
580 | tty_put_char(tty, '\b'); | 979 | echo_char_raw('\b', tty); |
581 | if (tty->column > 0) | ||
582 | tty->column--; | ||
583 | } | 980 | } |
584 | if (!iscntrl(c) || L_ECHOCTL(tty)) { | 981 | if (!iscntrl(c) || L_ECHOCTL(tty)) { |
585 | tty_put_char(tty, '\b'); | 982 | echo_char_raw('\b', tty); |
586 | tty_put_char(tty, ' '); | 983 | echo_char_raw(' ', tty); |
587 | tty_put_char(tty, '\b'); | 984 | echo_char_raw('\b', tty); |
588 | if (tty->column > 0) | ||
589 | tty->column--; | ||
590 | } | 985 | } |
591 | } | 986 | } |
592 | } | 987 | } |
593 | if (kill_type == ERASE) | 988 | if (kill_type == ERASE) |
594 | break; | 989 | break; |
595 | } | 990 | } |
596 | if (tty->read_head == tty->canon_head) | 991 | if (tty->read_head == tty->canon_head && L_ECHO(tty)) |
597 | finish_erasing(tty); | 992 | finish_erasing(tty); |
598 | } | 993 | } |
599 | 994 | ||
@@ -712,6 +1107,7 @@ static inline void n_tty_receive_parity_error(struct tty_struct *tty, | |||
712 | static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | 1107 | static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) |
713 | { | 1108 | { |
714 | unsigned long flags; | 1109 | unsigned long flags; |
1110 | int parmrk; | ||
715 | 1111 | ||
716 | if (tty->raw) { | 1112 | if (tty->raw) { |
717 | put_tty_queue(c, tty); | 1113 | put_tty_queue(c, tty); |
@@ -721,18 +1117,21 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
721 | if (I_ISTRIP(tty)) | 1117 | if (I_ISTRIP(tty)) |
722 | c &= 0x7f; | 1118 | c &= 0x7f; |
723 | if (I_IUCLC(tty) && L_IEXTEN(tty)) | 1119 | if (I_IUCLC(tty) && L_IEXTEN(tty)) |
724 | c=tolower(c); | 1120 | c = tolower(c); |
725 | 1121 | ||
726 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && | 1122 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && |
727 | ((I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty)) || | 1123 | I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) && |
728 | c == INTR_CHAR(tty) || c == QUIT_CHAR(tty) || c == SUSP_CHAR(tty))) | 1124 | c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) { |
729 | start_tty(tty); | 1125 | start_tty(tty); |
1126 | process_echoes(tty); | ||
1127 | } | ||
730 | 1128 | ||
731 | if (tty->closing) { | 1129 | if (tty->closing) { |
732 | if (I_IXON(tty)) { | 1130 | if (I_IXON(tty)) { |
733 | if (c == START_CHAR(tty)) | 1131 | if (c == START_CHAR(tty)) { |
734 | start_tty(tty); | 1132 | start_tty(tty); |
735 | else if (c == STOP_CHAR(tty)) | 1133 | process_echoes(tty); |
1134 | } else if (c == STOP_CHAR(tty)) | ||
736 | stop_tty(tty); | 1135 | stop_tty(tty); |
737 | } | 1136 | } |
738 | return; | 1137 | return; |
@@ -745,19 +1144,23 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
745 | * up. | 1144 | * up. |
746 | */ | 1145 | */ |
747 | if (!test_bit(c, tty->process_char_map) || tty->lnext) { | 1146 | if (!test_bit(c, tty->process_char_map) || tty->lnext) { |
748 | finish_erasing(tty); | ||
749 | tty->lnext = 0; | 1147 | tty->lnext = 0; |
1148 | parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; | ||
1149 | if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { | ||
1150 | /* beep if no space */ | ||
1151 | if (L_ECHO(tty)) | ||
1152 | process_output('\a', tty); | ||
1153 | return; | ||
1154 | } | ||
750 | if (L_ECHO(tty)) { | 1155 | if (L_ECHO(tty)) { |
751 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { | 1156 | finish_erasing(tty); |
752 | tty_put_char(tty, '\a'); /* beep if no space */ | ||
753 | return; | ||
754 | } | ||
755 | /* Record the column of first canon char. */ | 1157 | /* Record the column of first canon char. */ |
756 | if (tty->canon_head == tty->read_head) | 1158 | if (tty->canon_head == tty->read_head) |
757 | tty->canon_column = tty->column; | 1159 | echo_set_canon_col(tty); |
758 | echo_char(c, tty); | 1160 | echo_char(c, tty); |
1161 | process_echoes(tty); | ||
759 | } | 1162 | } |
760 | if (I_PARMRK(tty) && c == (unsigned char) '\377') | 1163 | if (parmrk) |
761 | put_tty_queue(c, tty); | 1164 | put_tty_queue(c, tty); |
762 | put_tty_queue(c, tty); | 1165 | put_tty_queue(c, tty); |
763 | return; | 1166 | return; |
@@ -766,6 +1169,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
766 | if (I_IXON(tty)) { | 1169 | if (I_IXON(tty)) { |
767 | if (c == START_CHAR(tty)) { | 1170 | if (c == START_CHAR(tty)) { |
768 | start_tty(tty); | 1171 | start_tty(tty); |
1172 | process_echoes(tty); | ||
769 | return; | 1173 | return; |
770 | } | 1174 | } |
771 | if (c == STOP_CHAR(tty)) { | 1175 | if (c == STOP_CHAR(tty)) { |
@@ -786,7 +1190,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
786 | if (c == SUSP_CHAR(tty)) { | 1190 | if (c == SUSP_CHAR(tty)) { |
787 | send_signal: | 1191 | send_signal: |
788 | /* | 1192 | /* |
789 | * Echo character, and then send the signal. | ||
790 | * Note that we do not use isig() here because we want | 1193 | * Note that we do not use isig() here because we want |
791 | * the order to be: | 1194 | * the order to be: |
792 | * 1) flush, 2) echo, 3) signal | 1195 | * 1) flush, 2) echo, 3) signal |
@@ -795,8 +1198,12 @@ send_signal: | |||
795 | n_tty_flush_buffer(tty); | 1198 | n_tty_flush_buffer(tty); |
796 | tty_driver_flush_buffer(tty); | 1199 | tty_driver_flush_buffer(tty); |
797 | } | 1200 | } |
798 | if (L_ECHO(tty)) | 1201 | if (I_IXON(tty)) |
1202 | start_tty(tty); | ||
1203 | if (L_ECHO(tty)) { | ||
799 | echo_char(c, tty); | 1204 | echo_char(c, tty); |
1205 | process_echoes(tty); | ||
1206 | } | ||
800 | if (tty->pgrp) | 1207 | if (tty->pgrp) |
801 | kill_pgrp(tty->pgrp, signal, 1); | 1208 | kill_pgrp(tty->pgrp, signal, 1); |
802 | return; | 1209 | return; |
@@ -815,6 +1222,7 @@ send_signal: | |||
815 | if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || | 1222 | if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || |
816 | (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { | 1223 | (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { |
817 | eraser(c, tty); | 1224 | eraser(c, tty); |
1225 | process_echoes(tty); | ||
818 | return; | 1226 | return; |
819 | } | 1227 | } |
820 | if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { | 1228 | if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { |
@@ -822,8 +1230,9 @@ send_signal: | |||
822 | if (L_ECHO(tty)) { | 1230 | if (L_ECHO(tty)) { |
823 | finish_erasing(tty); | 1231 | finish_erasing(tty); |
824 | if (L_ECHOCTL(tty)) { | 1232 | if (L_ECHOCTL(tty)) { |
825 | tty_put_char(tty, '^'); | 1233 | echo_char_raw('^', tty); |
826 | tty_put_char(tty, '\b'); | 1234 | echo_char_raw('\b', tty); |
1235 | process_echoes(tty); | ||
827 | } | 1236 | } |
828 | } | 1237 | } |
829 | return; | 1238 | return; |
@@ -834,22 +1243,29 @@ send_signal: | |||
834 | 1243 | ||
835 | finish_erasing(tty); | 1244 | finish_erasing(tty); |
836 | echo_char(c, tty); | 1245 | echo_char(c, tty); |
837 | opost('\n', tty); | 1246 | echo_char_raw('\n', tty); |
838 | while (tail != tty->read_head) { | 1247 | while (tail != tty->read_head) { |
839 | echo_char(tty->read_buf[tail], tty); | 1248 | echo_char(tty->read_buf[tail], tty); |
840 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); | 1249 | tail = (tail+1) & (N_TTY_BUF_SIZE-1); |
841 | } | 1250 | } |
1251 | process_echoes(tty); | ||
842 | return; | 1252 | return; |
843 | } | 1253 | } |
844 | if (c == '\n') { | 1254 | if (c == '\n') { |
1255 | if (tty->read_cnt >= N_TTY_BUF_SIZE) { | ||
1256 | if (L_ECHO(tty)) | ||
1257 | process_output('\a', tty); | ||
1258 | return; | ||
1259 | } | ||
845 | if (L_ECHO(tty) || L_ECHONL(tty)) { | 1260 | if (L_ECHO(tty) || L_ECHONL(tty)) { |
846 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) | 1261 | echo_char_raw('\n', tty); |
847 | tty_put_char(tty, '\a'); | 1262 | process_echoes(tty); |
848 | opost('\n', tty); | ||
849 | } | 1263 | } |
850 | goto handle_newline; | 1264 | goto handle_newline; |
851 | } | 1265 | } |
852 | if (c == EOF_CHAR(tty)) { | 1266 | if (c == EOF_CHAR(tty)) { |
1267 | if (tty->read_cnt >= N_TTY_BUF_SIZE) | ||
1268 | return; | ||
853 | if (tty->canon_head != tty->read_head) | 1269 | if (tty->canon_head != tty->read_head) |
854 | set_bit(TTY_PUSH, &tty->flags); | 1270 | set_bit(TTY_PUSH, &tty->flags); |
855 | c = __DISABLED_CHAR; | 1271 | c = __DISABLED_CHAR; |
@@ -857,22 +1273,28 @@ send_signal: | |||
857 | } | 1273 | } |
858 | if ((c == EOL_CHAR(tty)) || | 1274 | if ((c == EOL_CHAR(tty)) || |
859 | (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) { | 1275 | (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) { |
1276 | parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) | ||
1277 | ? 1 : 0; | ||
1278 | if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) { | ||
1279 | if (L_ECHO(tty)) | ||
1280 | process_output('\a', tty); | ||
1281 | return; | ||
1282 | } | ||
860 | /* | 1283 | /* |
861 | * XXX are EOL_CHAR and EOL2_CHAR echoed?!? | 1284 | * XXX are EOL_CHAR and EOL2_CHAR echoed?!? |
862 | */ | 1285 | */ |
863 | if (L_ECHO(tty)) { | 1286 | if (L_ECHO(tty)) { |
864 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) | ||
865 | tty_put_char(tty, '\a'); | ||
866 | /* Record the column of first canon char. */ | 1287 | /* Record the column of first canon char. */ |
867 | if (tty->canon_head == tty->read_head) | 1288 | if (tty->canon_head == tty->read_head) |
868 | tty->canon_column = tty->column; | 1289 | echo_set_canon_col(tty); |
869 | echo_char(c, tty); | 1290 | echo_char(c, tty); |
1291 | process_echoes(tty); | ||
870 | } | 1292 | } |
871 | /* | 1293 | /* |
872 | * XXX does PARMRK doubling happen for | 1294 | * XXX does PARMRK doubling happen for |
873 | * EOL_CHAR and EOL2_CHAR? | 1295 | * EOL_CHAR and EOL2_CHAR? |
874 | */ | 1296 | */ |
875 | if (I_PARMRK(tty) && c == (unsigned char) '\377') | 1297 | if (parmrk) |
876 | put_tty_queue(c, tty); | 1298 | put_tty_queue(c, tty); |
877 | 1299 | ||
878 | handle_newline: | 1300 | handle_newline: |
@@ -889,23 +1311,27 @@ handle_newline: | |||
889 | } | 1311 | } |
890 | } | 1312 | } |
891 | 1313 | ||
892 | finish_erasing(tty); | 1314 | parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; |
1315 | if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { | ||
1316 | /* beep if no space */ | ||
1317 | if (L_ECHO(tty)) | ||
1318 | process_output('\a', tty); | ||
1319 | return; | ||
1320 | } | ||
893 | if (L_ECHO(tty)) { | 1321 | if (L_ECHO(tty)) { |
894 | if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { | 1322 | finish_erasing(tty); |
895 | tty_put_char(tty, '\a'); /* beep if no space */ | ||
896 | return; | ||
897 | } | ||
898 | if (c == '\n') | 1323 | if (c == '\n') |
899 | opost('\n', tty); | 1324 | echo_char_raw('\n', tty); |
900 | else { | 1325 | else { |
901 | /* Record the column of first canon char. */ | 1326 | /* Record the column of first canon char. */ |
902 | if (tty->canon_head == tty->read_head) | 1327 | if (tty->canon_head == tty->read_head) |
903 | tty->canon_column = tty->column; | 1328 | echo_set_canon_col(tty); |
904 | echo_char(c, tty); | 1329 | echo_char(c, tty); |
905 | } | 1330 | } |
1331 | process_echoes(tty); | ||
906 | } | 1332 | } |
907 | 1333 | ||
908 | if (I_PARMRK(tty) && c == (unsigned char) '\377') | 1334 | if (parmrk) |
909 | put_tty_queue(c, tty); | 1335 | put_tty_queue(c, tty); |
910 | 1336 | ||
911 | put_tty_queue(c, tty); | 1337 | put_tty_queue(c, tty); |
@@ -923,10 +1349,11 @@ handle_newline: | |||
923 | 1349 | ||
924 | static void n_tty_write_wakeup(struct tty_struct *tty) | 1350 | static void n_tty_write_wakeup(struct tty_struct *tty) |
925 | { | 1351 | { |
926 | if (tty->fasync) { | 1352 | /* Write out any echoed characters that are still pending */ |
927 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 1353 | process_echoes(tty); |
1354 | |||
1355 | if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) | ||
928 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); | 1356 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); |
929 | } | ||
930 | } | 1357 | } |
931 | 1358 | ||
932 | /** | 1359 | /** |
@@ -1134,6 +1561,10 @@ static void n_tty_close(struct tty_struct *tty) | |||
1134 | free_buf(tty->read_buf); | 1561 | free_buf(tty->read_buf); |
1135 | tty->read_buf = NULL; | 1562 | tty->read_buf = NULL; |
1136 | } | 1563 | } |
1564 | if (tty->echo_buf) { | ||
1565 | free_buf(tty->echo_buf); | ||
1566 | tty->echo_buf = NULL; | ||
1567 | } | ||
1137 | } | 1568 | } |
1138 | 1569 | ||
1139 | /** | 1570 | /** |
@@ -1151,13 +1582,19 @@ static int n_tty_open(struct tty_struct *tty) | |||
1151 | if (!tty) | 1582 | if (!tty) |
1152 | return -EINVAL; | 1583 | return -EINVAL; |
1153 | 1584 | ||
1154 | /* This one is ugly. Currently a malloc failure here can panic */ | 1585 | /* These are ugly. Currently a malloc failure here can panic */ |
1155 | if (!tty->read_buf) { | 1586 | if (!tty->read_buf) { |
1156 | tty->read_buf = alloc_buf(); | 1587 | tty->read_buf = alloc_buf(); |
1157 | if (!tty->read_buf) | 1588 | if (!tty->read_buf) |
1158 | return -ENOMEM; | 1589 | return -ENOMEM; |
1159 | } | 1590 | } |
1591 | if (!tty->echo_buf) { | ||
1592 | tty->echo_buf = alloc_buf(); | ||
1593 | if (!tty->echo_buf) | ||
1594 | return -ENOMEM; | ||
1595 | } | ||
1160 | memset(tty->read_buf, 0, N_TTY_BUF_SIZE); | 1596 | memset(tty->read_buf, 0, N_TTY_BUF_SIZE); |
1597 | memset(tty->echo_buf, 0, N_TTY_BUF_SIZE); | ||
1161 | reset_buffer_flags(tty); | 1598 | reset_buffer_flags(tty); |
1162 | tty->column = 0; | 1599 | tty->column = 0; |
1163 | n_tty_set_termios(tty, NULL); | 1600 | n_tty_set_termios(tty, NULL); |
@@ -1487,16 +1924,23 @@ do_it_again: | |||
1487 | * @buf: userspace buffer pointer | 1924 | * @buf: userspace buffer pointer |
1488 | * @nr: size of I/O | 1925 | * @nr: size of I/O |
1489 | * | 1926 | * |
1490 | * Write function of the terminal device. This is serialized with | 1927 | * Write function of the terminal device. This is serialized with |
1491 | * respect to other write callers but not to termios changes, reads | 1928 | * 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 | 1929 | * and other such events. Since the receive code will echo characters, |
1493 | * code will echo characters, thus calling driver write methods. | 1930 | * thus calling driver write methods, the output_lock is used in |
1931 | * the output processing functions called here as well as in the | ||
1932 | * echo processing function to protect the column state and space | ||
1933 | * left in the buffer. | ||
1494 | * | 1934 | * |
1495 | * This code must be sure never to sleep through a hangup. | 1935 | * This code must be sure never to sleep through a hangup. |
1936 | * | ||
1937 | * Locking: output_lock to protect column state and space left | ||
1938 | * (note that the process_output*() functions take this | ||
1939 | * lock themselves) | ||
1496 | */ | 1940 | */ |
1497 | 1941 | ||
1498 | static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | 1942 | static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, |
1499 | const unsigned char *buf, size_t nr) | 1943 | const unsigned char *buf, size_t nr) |
1500 | { | 1944 | { |
1501 | const unsigned char *b = buf; | 1945 | const unsigned char *b = buf; |
1502 | DECLARE_WAITQUEUE(wait, current); | 1946 | DECLARE_WAITQUEUE(wait, current); |
@@ -1510,6 +1954,9 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | |||
1510 | return retval; | 1954 | return retval; |
1511 | } | 1955 | } |
1512 | 1956 | ||
1957 | /* Write out any echoed characters that are still pending */ | ||
1958 | process_echoes(tty); | ||
1959 | |||
1513 | add_wait_queue(&tty->write_wait, &wait); | 1960 | add_wait_queue(&tty->write_wait, &wait); |
1514 | while (1) { | 1961 | while (1) { |
1515 | set_current_state(TASK_INTERRUPTIBLE); | 1962 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -1523,7 +1970,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | |||
1523 | } | 1970 | } |
1524 | if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) { | 1971 | if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) { |
1525 | while (nr > 0) { | 1972 | while (nr > 0) { |
1526 | ssize_t num = opost_block(tty, b, nr); | 1973 | ssize_t num = process_output_block(tty, b, nr); |
1527 | if (num < 0) { | 1974 | if (num < 0) { |
1528 | if (num == -EAGAIN) | 1975 | if (num == -EAGAIN) |
1529 | break; | 1976 | break; |
@@ -1535,7 +1982,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | |||
1535 | if (nr == 0) | 1982 | if (nr == 0) |
1536 | break; | 1983 | break; |
1537 | c = *b; | 1984 | c = *b; |
1538 | if (opost(c, tty) < 0) | 1985 | if (process_output(c, tty) < 0) |
1539 | break; | 1986 | break; |
1540 | b++; nr--; | 1987 | b++; nr--; |
1541 | } | 1988 | } |
@@ -1565,6 +2012,8 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | |||
1565 | break_out: | 2012 | break_out: |
1566 | __set_current_state(TASK_RUNNING); | 2013 | __set_current_state(TASK_RUNNING); |
1567 | remove_wait_queue(&tty->write_wait, &wait); | 2014 | remove_wait_queue(&tty->write_wait, &wait); |
2015 | if (b - buf != nr && tty->fasync) | ||
2016 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | ||
1568 | return (b - buf) ? b - buf : retval; | 2017 | return (b - buf) ? b - buf : retval; |
1569 | } | 2018 | } |
1570 | 2019 | ||
@@ -1663,4 +2112,3 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { | |||
1663 | .receive_buf = n_tty_receive_buf, | 2112 | .receive_buf = n_tty_receive_buf, |
1664 | .write_wakeup = n_tty_write_wakeup | 2113 | .write_wakeup = n_tty_write_wakeup |
1665 | }; | 2114 | }; |
1666 | |||