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 | |||
