diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-19 14:16:28 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-09-19 14:16:28 +0000 |
commit | 7eab79acc58a14078a8cf14fb9be7aa5103a5d41 (patch) | |
tree | 6ac5a597a975f2b5d7cdcbc83648a34277f9c0d6 | |
parent | 85f9e32f7f00b4579abb60637495dcd3a8a8bce0 (diff) | |
download | busybox-w32-7eab79acc58a14078a8cf14fb9be7aa5103a5d41.tar.gz busybox-w32-7eab79acc58a14078a8cf14fb9be7aa5103a5d41.tar.bz2 busybox-w32-7eab79acc58a14078a8cf14fb9be7aa5103a5d41.zip |
stty: fix a longstanding FIXME (was able to die half-way setting term params)
-rw-r--r-- | coreutils/stty.c | 412 |
1 files changed, 241 insertions, 171 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c index d709bfc1e..a63c1d1fa 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c | |||
@@ -173,7 +173,7 @@ struct mode_info { | |||
173 | 173 | ||
174 | #define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B } | 174 | #define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B } |
175 | 175 | ||
176 | static const struct mode_info mode_info[] = { | 176 | static const struct mode_info mode_info[] = { |
177 | MI_ENTRY("parenb", control, REV, PARENB, 0 ), | 177 | MI_ENTRY("parenb", control, REV, PARENB, 0 ), |
178 | MI_ENTRY("parodd", control, REV, PARODD, 0 ), | 178 | MI_ENTRY("parodd", control, REV, PARODD, 0 ), |
179 | MI_ENTRY("cs5", control, 0, CS5, CSIZE), | 179 | MI_ENTRY("cs5", control, 0, CS5, CSIZE), |
@@ -333,7 +333,7 @@ struct control_info { | |||
333 | 333 | ||
334 | /* Control characters. */ | 334 | /* Control characters. */ |
335 | 335 | ||
336 | static const struct control_info control_info[] = { | 336 | static const struct control_info control_info[] = { |
337 | {"intr", CINTR, VINTR}, | 337 | {"intr", CINTR, VINTR}, |
338 | {"quit", CQUIT, VQUIT}, | 338 | {"quit", CQUIT, VQUIT}, |
339 | {"erase", CERASE, VERASE}, | 339 | {"erase", CERASE, VERASE}, |
@@ -380,9 +380,9 @@ enum { | |||
380 | #define EMT(t) ((enum mode_type)(t)) | 380 | #define EMT(t) ((enum mode_type)(t)) |
381 | 381 | ||
382 | static const char * visible(unsigned int ch); | 382 | static const char * visible(unsigned int ch); |
383 | static int recover_mode(char *arg, struct termios *mode); | 383 | static int recover_mode(const char *arg, struct termios *mode); |
384 | static int screen_columns(void); | 384 | static int screen_columns(void); |
385 | static int set_mode(const struct mode_info *info, | 385 | static void set_mode(const struct mode_info *info, |
386 | int reversed, struct termios *mode); | 386 | int reversed, struct termios *mode); |
387 | static speed_t string_to_baud(const char *arg); | 387 | static speed_t string_to_baud(const char *arg); |
388 | static tcflag_t* mode_type_flag(enum mode_type type, struct termios *mode); | 388 | static tcflag_t* mode_type_flag(enum mode_type type, struct termios *mode); |
@@ -398,7 +398,7 @@ static void set_speed(enum speed_setting type, | |||
398 | const char *arg, struct termios *mode); | 398 | const char *arg, struct termios *mode); |
399 | static void set_window_size(int rows, int cols); | 399 | static void set_window_size(int rows, int cols); |
400 | 400 | ||
401 | static const char *device_name; | 401 | static const char *device_name = bb_msg_standard_input; |
402 | 402 | ||
403 | static ATTRIBUTE_NORETURN void perror_on_device(const char *fmt) | 403 | static ATTRIBUTE_NORETURN void perror_on_device(const char *fmt) |
404 | { | 404 | { |
@@ -445,80 +445,192 @@ static const struct suffix_mult stty_suffixes[] = { | |||
445 | {NULL, 0 } | 445 | {NULL, 0 } |
446 | }; | 446 | }; |
447 | 447 | ||
448 | static const struct mode_info *find_mode(const char *name) | ||
449 | { | ||
450 | int i; | ||
451 | for (i = 0; i < NUM_mode_info; ++i) | ||
452 | if (STREQ(name, mode_info[i].name)) | ||
453 | return &mode_info[i]; | ||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | static const struct control_info *find_control(const char *name) | ||
458 | { | ||
459 | int i; | ||
460 | for (i = 0; i < NUM_control_info; ++i) | ||
461 | if (STREQ(name, control_info[i].name)) | ||
462 | return &control_info[i]; | ||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | enum { | ||
467 | param_need_arg = 0x80, | ||
468 | param_line = 1 | 0x80, | ||
469 | param_rows = 2 | 0x80, | ||
470 | param_cols = 3 | 0x80, | ||
471 | param_size = 4, | ||
472 | param_ispeed = 5 | 0x80, | ||
473 | param_ospeed = 6 | 0x80, | ||
474 | param_speed = 7, | ||
475 | }; | ||
476 | |||
477 | static int find_param(const char *name) | ||
478 | { | ||
479 | #ifdef HAVE_C_LINE | ||
480 | if (STREQ(name, "line")) return param_line; | ||
481 | #endif | ||
482 | #ifdef TIOCGWINSZ | ||
483 | if (STREQ(name, "rows")) return param_rows; | ||
484 | if (STREQ(name, "cols")) return param_cols; | ||
485 | if (STREQ(name, "columns")) return param_cols; | ||
486 | if (STREQ(name, "size")) return param_size; | ||
487 | #endif | ||
488 | if (STREQ(name, "ispeed")) return param_ispeed; | ||
489 | if (STREQ(name, "ospeed")) return param_ospeed; | ||
490 | if (STREQ(name, "speed")) return param_speed; | ||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | |||
448 | int stty_main(int argc, char **argv) | 495 | int stty_main(int argc, char **argv) |
449 | { | 496 | { |
450 | struct termios mode; | 497 | struct termios mode; |
451 | void (*output_func)(struct termios *); | 498 | void (*output_func)(struct termios *); |
452 | int optc; | 499 | const char *file_name = NULL; |
453 | int require_set_attr; | 500 | int require_set_attr; |
454 | int speed_was_set; | 501 | int speed_was_set; |
455 | int verbose_output; | 502 | int verbose_output; |
456 | int recoverable_output; | 503 | int recoverable_output; |
457 | int k; | 504 | int noargs; |
458 | int noargs = 1; | 505 | int k; |
459 | char * file_name = NULL; | ||
460 | 506 | ||
461 | output_func = display_changed; | 507 | output_func = display_changed; |
508 | noargs = 1; | ||
509 | speed_was_set = 0; | ||
510 | require_set_attr = 0; | ||
462 | verbose_output = 0; | 511 | verbose_output = 0; |
463 | recoverable_output = 0; | 512 | recoverable_output = 0; |
464 | 513 | ||
465 | /* Don't print error messages for unrecognized options. */ | 514 | /* First pass: only parse/verify command line params */ |
466 | opterr = 0; | 515 | k = 0; |
467 | 516 | while (argv[++k]) { | |
468 | while ((optc = getopt(argc, argv, "agF:")) != -1) { | 517 | const struct mode_info *mp; |
469 | switch (optc) { | 518 | const struct control_info *cp; |
470 | case 'a': | 519 | const char *arg = argv[k]; |
471 | verbose_output = 1; | 520 | const char *argnext = argv[k+1]; |
472 | output_func = display_all; | 521 | int param; |
473 | break; | 522 | |
474 | 523 | if (arg[0] == '-') { | |
475 | case 'g': | 524 | int i; |
476 | recoverable_output = 1; | 525 | mp = find_mode(arg+1); |
477 | output_func = display_recoverable; | 526 | if (mp) { |
478 | break; | 527 | if (!(mp->flags & REV)) |
528 | bb_error_msg_and_die("invalid argument '%s'", arg); | ||
529 | noargs = 0; | ||
530 | continue; | ||
531 | } | ||
532 | /* It is an option - parse it */ | ||
533 | i = 0; | ||
534 | while (arg[++i]) { | ||
535 | switch (arg[i]) { | ||
536 | case 'a': | ||
537 | verbose_output = 1; | ||
538 | output_func = display_all; | ||
539 | break; | ||
540 | case 'g': | ||
541 | recoverable_output = 1; | ||
542 | output_func = display_recoverable; | ||
543 | break; | ||
544 | case 'F': | ||
545 | if (file_name) | ||
546 | bb_error_msg_and_die("only one device may be specified"); | ||
547 | file_name = &arg[i+1]; /* "-Fdevice" ? */ | ||
548 | if (!file_name[0]) { /* nope, "-F device" */ | ||
549 | int p = k+1; /* argv[p] is argnext */ | ||
550 | file_name = argnext; | ||
551 | if (!file_name) | ||
552 | bb_error_msg_and_die(bb_msg_requires_arg, "-F"); | ||
553 | /* remove -F param from arg[vc] */ | ||
554 | --argc; | ||
555 | while (argv[p+1]) { argv[p] = argv[p+1]; ++p; } | ||
556 | } | ||
557 | goto end_option; | ||
558 | default: | ||
559 | bb_error_msg_and_die("invalid argument '%s'", arg); | ||
560 | } | ||
561 | } | ||
562 | end_option: | ||
563 | continue; | ||
564 | } | ||
479 | 565 | ||
480 | case 'F': | 566 | mp = find_mode(arg); |
481 | if (file_name) | 567 | if (mp) { |
482 | bb_error_msg_and_die("only one device may be specified"); | 568 | noargs = 0; |
483 | file_name = optarg; | 569 | continue; |
484 | break; | 570 | } |
485 | 571 | ||
486 | default: /* unrecognized option */ | 572 | cp = find_control(arg); |
573 | if (cp) { | ||
574 | if (!argnext) | ||
575 | bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||
487 | noargs = 0; | 576 | noargs = 0; |
488 | break; | 577 | ++k; |
578 | continue; | ||
489 | } | 579 | } |
490 | 580 | ||
491 | if (noargs == 0) | 581 | param = find_param(arg); |
492 | break; | 582 | if (param & param_need_arg) { |
493 | } | 583 | if (!argnext) |
584 | bb_error_msg_and_die(bb_msg_requires_arg, arg); | ||
585 | ++k; | ||
586 | } | ||
494 | 587 | ||
495 | if (optind < argc) | 588 | switch (param) { |
589 | #ifdef HAVE_C_LINE | ||
590 | case param_line: | ||
591 | bb_xparse_number(argnext, stty_suffixes); | ||
592 | break; | ||
593 | #endif | ||
594 | #ifdef TIOCGWINSZ | ||
595 | case param_rows: | ||
596 | bb_xparse_number(argnext, stty_suffixes); | ||
597 | break; | ||
598 | case param_cols: | ||
599 | bb_xparse_number(argnext, stty_suffixes); | ||
600 | break; | ||
601 | case param_size: | ||
602 | #endif | ||
603 | case param_ispeed: | ||
604 | case param_ospeed: | ||
605 | case param_speed: | ||
606 | break; | ||
607 | default: | ||
608 | if (recover_mode(arg, &mode) == 1) break; | ||
609 | if (string_to_baud(arg) != (speed_t) -1) break; | ||
610 | bb_error_msg_and_die("invalid argument '%s'", arg); | ||
611 | } | ||
496 | noargs = 0; | 612 | noargs = 0; |
613 | } | ||
497 | 614 | ||
498 | /* Specifying both -a and -g gets an error. */ | 615 | /* Specifying both -a and -g is an error */ |
499 | if (verbose_output & recoverable_output) | 616 | if (verbose_output && recoverable_output) |
500 | bb_error_msg_and_die ("verbose and stty-readable output styles are mutually exclusive"); | 617 | bb_error_msg_and_die("verbose and stty-readable output styles are mutually exclusive"); |
501 | 618 | /* Specifying -a or -g with non-options is an error */ | |
502 | /* Specifying any other arguments with -a or -g gets an error. */ | 619 | if (!noargs && (verbose_output || recoverable_output)) |
503 | if (~noargs & (verbose_output | recoverable_output)) | 620 | bb_error_msg_and_die("modes may not be set when specifying an output style"); |
504 | bb_error_msg_and_die ("modes may not be set when specifying an output style"); | ||
505 | |||
506 | /* FIXME: it'd be better not to open the file until we've verified | ||
507 | that all arguments are valid. Otherwise, we could end up doing | ||
508 | only some of the requested operations and then failing, probably | ||
509 | leaving things in an undesirable state. */ | ||
510 | 621 | ||
622 | /* Now it is safe to start doing things */ | ||
511 | if (file_name) { | 623 | if (file_name) { |
512 | int fdflags; | 624 | int fd, fdflags; |
513 | |||
514 | device_name = file_name; | 625 | device_name = file_name; |
515 | fclose(stdin); | 626 | fd = xopen(device_name, O_RDONLY | O_NONBLOCK); |
516 | xopen(device_name, O_RDONLY | O_NONBLOCK); | 627 | if (fd != 0) { |
628 | dup2(fd, 0); | ||
629 | close(fd); | ||
630 | } | ||
517 | fdflags = fcntl(STDIN_FILENO, F_GETFL); | 631 | fdflags = fcntl(STDIN_FILENO, F_GETFL); |
518 | if (fdflags == -1 || fcntl(STDIN_FILENO, F_SETFL, fdflags & ~O_NONBLOCK) < 0) | 632 | if (fdflags == -1 || fcntl(STDIN_FILENO, F_SETFL, fdflags & ~O_NONBLOCK) < 0) |
519 | perror_on_device("%s: couldn't reset non-blocking mode"); | 633 | perror_on_device("%s: couldn't reset non-blocking mode"); |
520 | } else { | ||
521 | device_name = bb_msg_standard_input; | ||
522 | } | 634 | } |
523 | 635 | ||
524 | /* Initialize to all zeroes so there is no risk memcmp will report a | 636 | /* Initialize to all zeroes so there is no risk memcmp will report a |
@@ -527,122 +639,92 @@ int stty_main(int argc, char **argv) | |||
527 | if (tcgetattr(STDIN_FILENO, &mode)) | 639 | if (tcgetattr(STDIN_FILENO, &mode)) |
528 | perror_on_device("%s"); | 640 | perror_on_device("%s"); |
529 | 641 | ||
530 | if (verbose_output | recoverable_output | noargs) { | 642 | if (verbose_output || recoverable_output || noargs) { |
531 | max_col = screen_columns(); | 643 | max_col = screen_columns(); |
532 | current_col = 0; | 644 | current_col = 0; |
533 | output_func(&mode); | 645 | output_func(&mode); |
534 | return EXIT_SUCCESS; | 646 | return EXIT_SUCCESS; |
535 | } | 647 | } |
536 | 648 | ||
537 | speed_was_set = 0; | 649 | /* Second pass: perform actions */ |
538 | require_set_attr = 0; | ||
539 | k = 0; | 650 | k = 0; |
540 | while (++k < argc) { | 651 | while (argv[++k]) { |
541 | int match_found = 0; | 652 | const struct mode_info *mp; |
542 | int reversed = 0; | 653 | const struct control_info *cp; |
543 | int i; | 654 | const char *arg = argv[k]; |
544 | 655 | const char *argnext = argv[k+1]; | |
545 | if (argv[k][0] == '-') { | 656 | int param; |
546 | char *find_dev_opt; | 657 | |
547 | 658 | if (arg[0] == '-') { | |
548 | ++argv[k]; | 659 | mp = find_mode(arg+1); |
549 | 660 | if (mp) { | |
550 | /* Handle "-a", "-ag", "-aF/dev/foo", "-aF /dev/foo", etc. | 661 | set_mode(mp, 1 /* reversed */, &mode); |
551 | Find the options that have been parsed. This is really | ||
552 | gross, but it's needed because stty SETTINGS look like options to | ||
553 | getopt(), so we need to work around things in a really horrible | ||
554 | way. If any new options are ever added to stty, the short option | ||
555 | MUST NOT be a letter which is the first letter of one of the | ||
556 | possible stty settings. | ||
557 | */ | ||
558 | find_dev_opt = strchr(argv[k], 'F'); /* find -*F* */ | ||
559 | if(find_dev_opt) { | ||
560 | if(find_dev_opt[1]==0) /* -*F /dev/foo */ | ||
561 | k++; /* skip /dev/foo */ | ||
562 | continue; /* else -*F/dev/foo - no skip */ | ||
563 | } | 662 | } |
564 | if(argv[k][0]=='a' || argv[k][0]=='g') | 663 | /* It is an option - already parsed. Skip it */ |
565 | continue; | 664 | continue; |
566 | /* Is not options - is reverse params */ | ||
567 | reversed = 1; | ||
568 | } | 665 | } |
569 | for (i = 0; i < NUM_mode_info; ++i) | ||
570 | if (STREQ(argv[k], mode_info[i].name)) { | ||
571 | match_found = set_mode(&mode_info[i], reversed, &mode); | ||
572 | require_set_attr = 1; | ||
573 | break; | ||
574 | } | ||
575 | 666 | ||
576 | if (match_found == 0 && reversed) | 667 | mp = find_mode(arg); |
577 | bb_error_msg_and_die("invalid argument `%s'", --argv[k]); | 668 | if (mp) { |
578 | 669 | set_mode(mp, 0 /* non-reversed */, &mode); | |
579 | if (match_found == 0) | 670 | continue; |
580 | for (i = 0; i < NUM_control_info; ++i) | 671 | } |
581 | if (STREQ(argv[k], control_info[i].name)) { | ||
582 | if (k == argc - 1) | ||
583 | bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); | ||
584 | match_found = 1; | ||
585 | ++k; | ||
586 | set_control_char(&control_info[i], argv[k], &mode); | ||
587 | require_set_attr = 1; | ||
588 | break; | ||
589 | } | ||
590 | 672 | ||
591 | if (match_found == 0) { | 673 | cp = find_control(arg); |
592 | if (STREQ(argv[k], "ispeed")) { | 674 | if (cp) { |
593 | if (k == argc - 1) | 675 | ++k; |
594 | bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); | 676 | set_control_char(cp, argnext, &mode); |
595 | ++k; | 677 | continue; |
596 | set_speed(input_speed, argv[k], &mode); | 678 | } |
597 | speed_was_set = 1; | 679 | |
598 | require_set_attr = 1; | 680 | param = find_param(arg); |
599 | } else if (STREQ(argv[k], "ospeed")) { | 681 | if (param & param_need_arg) { |
600 | if (k == argc - 1) | 682 | ++k; |
601 | bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); | 683 | } |
602 | ++k; | 684 | |
603 | set_speed(output_speed, argv[k], &mode); | 685 | switch (param) { |
604 | speed_was_set = 1; | ||
605 | require_set_attr = 1; | ||
606 | } | ||
607 | #ifdef TIOCGWINSZ | ||
608 | else if (STREQ(argv[k], "rows")) { | ||
609 | if (k == argc - 1) | ||
610 | bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); | ||
611 | ++k; | ||
612 | set_window_size((int) bb_xparse_number(argv[k], stty_suffixes), | ||
613 | -1); | ||
614 | } else if (STREQ(argv[k], "cols") || STREQ(argv[k], "columns")) { | ||
615 | if (k == argc - 1) | ||
616 | bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); | ||
617 | ++k; | ||
618 | set_window_size(-1, | ||
619 | (int) bb_xparse_number(argv[k], stty_suffixes)); | ||
620 | } else if (STREQ(argv[k], "size")) { | ||
621 | max_col = screen_columns(); | ||
622 | current_col = 0; | ||
623 | display_window_size(0); | ||
624 | } | ||
625 | #endif | ||
626 | #ifdef HAVE_C_LINE | 686 | #ifdef HAVE_C_LINE |
627 | else if (STREQ(argv[k], "line")) { | 687 | case param_line: |
628 | if (k == argc - 1) | 688 | mode.c_line = bb_xparse_number(argnext, stty_suffixes); |
629 | bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); | 689 | require_set_attr = 1; |
630 | ++k; | 690 | break; |
631 | mode.c_line = bb_xparse_number(argv[k], stty_suffixes); | 691 | #endif |
632 | require_set_attr = 1; | 692 | #ifdef TIOCGWINSZ |
633 | } | 693 | case param_cols: |
694 | set_window_size(-1, (int) bb_xparse_number(argnext, stty_suffixes)); | ||
695 | break; | ||
696 | case param_size: | ||
697 | max_col = screen_columns(); | ||
698 | current_col = 0; | ||
699 | display_window_size(0); | ||
700 | break; | ||
701 | case param_rows: | ||
702 | set_window_size((int) bb_xparse_number(argnext, stty_suffixes), -1); | ||
703 | break; | ||
634 | #endif | 704 | #endif |
635 | else if (STREQ(argv[k], "speed")) { | 705 | case param_ispeed: |
636 | max_col = screen_columns(); | 706 | set_speed(input_speed, argnext, &mode); |
637 | display_speed(&mode, 0); | 707 | speed_was_set = 1; |
638 | } else if (recover_mode(argv[k], &mode) == 1) | 708 | require_set_attr = 1; |
709 | break; | ||
710 | case param_ospeed: | ||
711 | set_speed(output_speed, argnext, &mode); | ||
712 | speed_was_set = 1; | ||
713 | require_set_attr = 1; | ||
714 | break; | ||
715 | case param_speed: | ||
716 | max_col = screen_columns(); | ||
717 | display_speed(&mode, 0); | ||
718 | break; | ||
719 | default: | ||
720 | if (recover_mode(arg, &mode) == 1) | ||
639 | require_set_attr = 1; | 721 | require_set_attr = 1; |
640 | else if (string_to_baud(argv[k]) != (speed_t) - 1) { | 722 | else /* true: if (string_to_baud(arg) != (speed_t) -1) */ { |
641 | set_speed(both_speeds, argv[k], &mode); | 723 | set_speed(both_speeds, arg, &mode); |
642 | speed_was_set = 1; | 724 | speed_was_set = 1; |
643 | require_set_attr = 1; | 725 | require_set_attr = 1; |
644 | } else | 726 | } /* else - impossible (caught in the first pass): |
645 | bb_error_msg_and_die("invalid argument `%s'", argv[k]); | 727 | bb_error_msg_and_die("invalid argument '%s'", arg); */ |
646 | } | 728 | } |
647 | } | 729 | } |
648 | 730 | ||
@@ -665,13 +747,6 @@ int stty_main(int argc, char **argv) | |||
665 | if (tcgetattr(STDIN_FILENO, &new_mode)) | 747 | if (tcgetattr(STDIN_FILENO, &new_mode)) |
666 | perror_on_device("%s"); | 748 | perror_on_device("%s"); |
667 | 749 | ||
668 | /* Normally, one shouldn't use memcmp to compare structures that | ||
669 | may have `holes' containing uninitialized data, but we have been | ||
670 | careful to initialize the storage of these two variables to all | ||
671 | zeroes. One might think it more efficient simply to compare the | ||
672 | modified fields, but that would require enumerating those fields -- | ||
673 | and not all systems have the same fields in this structure. */ | ||
674 | |||
675 | if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) { | 750 | if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) { |
676 | #ifdef CIBAUD | 751 | #ifdef CIBAUD |
677 | /* SunOS 4.1.3 (at least) has the problem that after this sequence, | 752 | /* SunOS 4.1.3 (at least) has the problem that after this sequence, |
@@ -695,14 +770,11 @@ int stty_main(int argc, char **argv) | |||
695 | 770 | ||
696 | /* Return 0 if not applied because not reversible; otherwise return 1. */ | 771 | /* Return 0 if not applied because not reversible; otherwise return 1. */ |
697 | 772 | ||
698 | static int | 773 | static void |
699 | set_mode(const struct mode_info *info, int reversed, struct termios *mode) | 774 | set_mode(const struct mode_info *info, int reversed, struct termios *mode) |
700 | { | 775 | { |
701 | tcflag_t *bitsp; | 776 | tcflag_t *bitsp; |
702 | 777 | ||
703 | if (reversed && (info->flags & REV) == 0) | ||
704 | return 0; | ||
705 | |||
706 | bitsp = mode_type_flag(EMT(info->type), mode); | 778 | bitsp = mode_type_flag(EMT(info->type), mode); |
707 | 779 | ||
708 | if (bitsp == NULL) { | 780 | if (bitsp == NULL) { |
@@ -861,8 +933,6 @@ set_mode(const struct mode_info *info, int reversed, struct termios *mode) | |||
861 | *bitsp = *bitsp & ~((unsigned long)info->mask) & ~info->bits; | 933 | *bitsp = *bitsp & ~((unsigned long)info->mask) & ~info->bits; |
862 | else | 934 | else |
863 | *bitsp = (*bitsp & ~((unsigned long)info->mask)) | info->bits; | 935 | *bitsp = (*bitsp & ~((unsigned long)info->mask)) | info->bits; |
864 | |||
865 | return 1; | ||
866 | } | 936 | } |
867 | 937 | ||
868 | static void | 938 | static void |
@@ -1179,7 +1249,7 @@ static void display_recoverable(struct termios *mode) | |||
1179 | putchar('\n'); | 1249 | putchar('\n'); |
1180 | } | 1250 | } |
1181 | 1251 | ||
1182 | static int recover_mode(char *arg, struct termios *mode) | 1252 | static int recover_mode(const char *arg, struct termios *mode) |
1183 | { | 1253 | { |
1184 | int i, n; | 1254 | int i, n; |
1185 | unsigned int chr; | 1255 | unsigned int chr; |
@@ -1269,5 +1339,5 @@ static const char *visible(unsigned int ch) | |||
1269 | } | 1339 | } |
1270 | 1340 | ||
1271 | *bpout = '\0'; | 1341 | *bpout = '\0'; |
1272 | return (const char *) buf; | 1342 | return buf; |
1273 | } | 1343 | } |