diff options
| author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2007-01-17 19:42:30 +0000 |
|---|---|---|
| committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2007-01-17 19:42:30 +0000 |
| commit | 4fa566d4adcf56d74f3ddc271fd19be61510c568 (patch) | |
| tree | 25c0badea243019e72ea231ebe7fe7663dcc3dac /coreutils | |
| parent | 9e8df9354a30a9206d4cefd0d88bae5b776a0cb7 (diff) | |
| download | busybox-w32-4fa566d4adcf56d74f3ddc271fd19be61510c568.tar.gz busybox-w32-4fa566d4adcf56d74f3ddc271fd19be61510c568.tar.bz2 busybox-w32-4fa566d4adcf56d74f3ddc271fd19be61510c568.zip | |
- reuse option_mask32 for state-handling in main
- improve check for errors from fcntl
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/stty.c | 69 |
1 files changed, 33 insertions, 36 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c index c09c7c71f..fe71f3d8a 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c | |||
| @@ -1014,24 +1014,19 @@ static void set_control_char_or_die(const struct control_info *info, | |||
| 1014 | mode->c_cc[info->offset] = value; | 1014 | mode->c_cc[info->offset] = value; |
| 1015 | } | 1015 | } |
| 1016 | 1016 | ||
| 1017 | #define STTY_require_set_attr (1<<0) | ||
| 1018 | #define STTY_speed_was_set (1<<1) | ||
| 1019 | #define STTY_verbose_output (1<<2) | ||
| 1020 | #define STTY_recoverable_output (1<<3) | ||
| 1021 | #define STTY_noargs (1<<4) | ||
| 1017 | int stty_main(int argc, char **argv) | 1022 | int stty_main(int argc, char **argv) |
| 1018 | { | 1023 | { |
| 1019 | struct termios mode; | 1024 | struct termios mode; |
| 1020 | void (*output_func)(const struct termios *); | 1025 | void (*output_func)(const struct termios *); |
| 1021 | const char *file_name = NULL; | 1026 | const char *file_name = NULL; |
| 1022 | int require_set_attr; | ||
| 1023 | int speed_was_set; | ||
| 1024 | int verbose_output; | ||
| 1025 | int recoverable_output; | ||
| 1026 | int noargs; | ||
| 1027 | int k; | 1027 | int k; |
| 1028 | 1028 | option_mask32 = STTY_noargs; | |
| 1029 | output_func = display_changed; | 1029 | output_func = display_changed; |
| 1030 | noargs = 1; | ||
| 1031 | speed_was_set = 0; | ||
| 1032 | require_set_attr = 0; | ||
| 1033 | verbose_output = 0; | ||
| 1034 | recoverable_output = 0; | ||
| 1035 | 1030 | ||
| 1036 | /* First pass: only parse/verify command line params */ | 1031 | /* First pass: only parse/verify command line params */ |
| 1037 | k = 0; | 1032 | k = 0; |
| @@ -1047,8 +1042,8 @@ int stty_main(int argc, char **argv) | |||
| 1047 | mp = find_mode(arg+1); | 1042 | mp = find_mode(arg+1); |
| 1048 | if (mp) { | 1043 | if (mp) { |
| 1049 | if (!(mp->flags & REV)) | 1044 | if (!(mp->flags & REV)) |
| 1050 | bb_error_msg_and_die("invalid argument '%s'", arg); | 1045 | goto invalid_argument; |
| 1051 | noargs = 0; | 1046 | option_mask32 &= ~STTY_noargs; |
| 1052 | continue; | 1047 | continue; |
| 1053 | } | 1048 | } |
| 1054 | /* It is an option - parse it */ | 1049 | /* It is an option - parse it */ |
| @@ -1056,11 +1051,11 @@ int stty_main(int argc, char **argv) | |||
| 1056 | while (arg[++i]) { | 1051 | while (arg[++i]) { |
| 1057 | switch (arg[i]) { | 1052 | switch (arg[i]) { |
| 1058 | case 'a': | 1053 | case 'a': |
| 1059 | verbose_output = 1; | 1054 | option_mask32 |= STTY_verbose_output; |
| 1060 | output_func = display_all; | 1055 | output_func = display_all; |
| 1061 | break; | 1056 | break; |
| 1062 | case 'g': | 1057 | case 'g': |
| 1063 | recoverable_output = 1; | 1058 | option_mask32 |= STTY_recoverable_output; |
| 1064 | output_func = display_recoverable; | 1059 | output_func = display_recoverable; |
| 1065 | break; | 1060 | break; |
| 1066 | case 'F': | 1061 | case 'F': |
| @@ -1078,7 +1073,7 @@ int stty_main(int argc, char **argv) | |||
| 1078 | } | 1073 | } |
| 1079 | goto end_option; | 1074 | goto end_option; |
| 1080 | default: | 1075 | default: |
| 1081 | bb_error_msg_and_die("invalid argument '%s'", arg); | 1076 | goto invalid_argument; |
| 1082 | } | 1077 | } |
| 1083 | } | 1078 | } |
| 1084 | end_option: | 1079 | end_option: |
| @@ -1087,7 +1082,7 @@ end_option: | |||
| 1087 | 1082 | ||
| 1088 | mp = find_mode(arg); | 1083 | mp = find_mode(arg); |
| 1089 | if (mp) { | 1084 | if (mp) { |
| 1090 | noargs = 0; | 1085 | option_mask32 &= ~STTY_noargs; |
| 1091 | continue; | 1086 | continue; |
| 1092 | } | 1087 | } |
| 1093 | 1088 | ||
| @@ -1097,7 +1092,7 @@ end_option: | |||
| 1097 | bb_error_msg_and_die(bb_msg_requires_arg, arg); | 1092 | bb_error_msg_and_die(bb_msg_requires_arg, arg); |
| 1098 | /* called for the side effect of xfunc death only */ | 1093 | /* called for the side effect of xfunc death only */ |
| 1099 | set_control_char_or_die(cp, argnext, &mode); | 1094 | set_control_char_or_die(cp, argnext, &mode); |
| 1100 | noargs = 0; | 1095 | option_mask32 &= ~STTY_noargs; |
| 1101 | ++k; | 1096 | ++k; |
| 1102 | continue; | 1097 | continue; |
| 1103 | } | 1098 | } |
| @@ -1137,16 +1132,19 @@ end_option: | |||
| 1137 | default: | 1132 | default: |
| 1138 | if (recover_mode(arg, &mode) == 1) break; | 1133 | if (recover_mode(arg, &mode) == 1) break; |
| 1139 | if (string_to_baud_or_die(arg) != (speed_t) -1) break; | 1134 | if (string_to_baud_or_die(arg) != (speed_t) -1) break; |
| 1135 | invalid_argument: | ||
| 1140 | bb_error_msg_and_die("invalid argument '%s'", arg); | 1136 | bb_error_msg_and_die("invalid argument '%s'", arg); |
| 1141 | } | 1137 | } |
| 1142 | noargs = 0; | 1138 | option_mask32 &= ~STTY_noargs; |
| 1143 | } | 1139 | } |
| 1144 | 1140 | ||
| 1145 | /* Specifying both -a and -g is an error */ | 1141 | /* Specifying both -a and -g is an error */ |
| 1146 | if (verbose_output && recoverable_output) | 1142 | if ((option_mask32 & (STTY_verbose_output | STTY_recoverable_output)) == |
| 1143 | (STTY_verbose_output | STTY_recoverable_output)) | ||
| 1147 | bb_error_msg_and_die("verbose and stty-readable output styles are mutually exclusive"); | 1144 | bb_error_msg_and_die("verbose and stty-readable output styles are mutually exclusive"); |
| 1148 | /* Specifying -a or -g with non-options is an error */ | 1145 | /* Specifying -a or -g with non-options is an error */ |
| 1149 | if (!noargs && (verbose_output || recoverable_output)) | 1146 | if (!(option_mask32 & STTY_noargs) && |
| 1147 | (option_mask32 & (STTY_verbose_output | STTY_recoverable_output))) | ||
| 1150 | bb_error_msg_and_die("modes may not be set when specifying an output style"); | 1148 | bb_error_msg_and_die("modes may not be set when specifying an output style"); |
| 1151 | 1149 | ||
| 1152 | /* Now it is safe to start doing things */ | 1150 | /* Now it is safe to start doing things */ |
| @@ -1159,7 +1157,8 @@ end_option: | |||
| 1159 | close(fd); | 1157 | close(fd); |
| 1160 | } | 1158 | } |
| 1161 | fdflags = fcntl(STDIN_FILENO, F_GETFL); | 1159 | fdflags = fcntl(STDIN_FILENO, F_GETFL); |
| 1162 | if (fdflags == -1 || fcntl(STDIN_FILENO, F_SETFL, fdflags & ~O_NONBLOCK) < 0) | 1160 | if (fdflags < 0 || |
| 1161 | fcntl(STDIN_FILENO, F_SETFL, fdflags & ~O_NONBLOCK) < 0) | ||
| 1163 | perror_on_device_and_die("%s: cannot reset non-blocking mode"); | 1162 | perror_on_device_and_die("%s: cannot reset non-blocking mode"); |
| 1164 | } | 1163 | } |
| 1165 | 1164 | ||
| @@ -1169,7 +1168,7 @@ end_option: | |||
| 1169 | if (tcgetattr(STDIN_FILENO, &mode)) | 1168 | if (tcgetattr(STDIN_FILENO, &mode)) |
| 1170 | perror_on_device_and_die("%s"); | 1169 | perror_on_device_and_die("%s"); |
| 1171 | 1170 | ||
| 1172 | if (verbose_output || recoverable_output || noargs) { | 1171 | if (option_mask32 & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) { |
| 1173 | max_col = screen_columns_or_die(); | 1172 | max_col = screen_columns_or_die(); |
| 1174 | output_func(&mode); | 1173 | output_func(&mode); |
| 1175 | return EXIT_SUCCESS; | 1174 | return EXIT_SUCCESS; |
| @@ -1188,7 +1187,7 @@ end_option: | |||
| 1188 | mp = find_mode(arg+1); | 1187 | mp = find_mode(arg+1); |
| 1189 | if (mp) { | 1188 | if (mp) { |
| 1190 | set_mode(mp, 1 /* reversed */, &mode); | 1189 | set_mode(mp, 1 /* reversed */, &mode); |
| 1191 | require_set_attr = 1; | 1190 | option_mask32 |= STTY_require_set_attr; |
| 1192 | } | 1191 | } |
| 1193 | /* It is an option - already parsed. Skip it */ | 1192 | /* It is an option - already parsed. Skip it */ |
| 1194 | continue; | 1193 | continue; |
| @@ -1197,7 +1196,7 @@ end_option: | |||
| 1197 | mp = find_mode(arg); | 1196 | mp = find_mode(arg); |
| 1198 | if (mp) { | 1197 | if (mp) { |
| 1199 | set_mode(mp, 0 /* non-reversed */, &mode); | 1198 | set_mode(mp, 0 /* non-reversed */, &mode); |
| 1200 | require_set_attr = 1; | 1199 | option_mask32 |= STTY_require_set_attr; |
| 1201 | continue; | 1200 | continue; |
| 1202 | } | 1201 | } |
| 1203 | 1202 | ||
| @@ -1205,7 +1204,7 @@ end_option: | |||
| 1205 | if (cp) { | 1204 | if (cp) { |
| 1206 | ++k; | 1205 | ++k; |
| 1207 | set_control_char_or_die(cp, argnext, &mode); | 1206 | set_control_char_or_die(cp, argnext, &mode); |
| 1208 | require_set_attr = 1; | 1207 | option_mask32 |= STTY_require_set_attr; |
| 1209 | continue; | 1208 | continue; |
| 1210 | } | 1209 | } |
| 1211 | 1210 | ||
| @@ -1218,7 +1217,7 @@ end_option: | |||
| 1218 | #ifdef HAVE_C_LINE | 1217 | #ifdef HAVE_C_LINE |
| 1219 | case param_line: | 1218 | case param_line: |
| 1220 | mode.c_line = xatoul_sfx(argnext, stty_suffixes); | 1219 | mode.c_line = xatoul_sfx(argnext, stty_suffixes); |
| 1221 | require_set_attr = 1; | 1220 | option_mask32 |= STTY_require_set_attr; |
| 1222 | break; | 1221 | break; |
| 1223 | #endif | 1222 | #endif |
| 1224 | #ifdef TIOCGWINSZ | 1223 | #ifdef TIOCGWINSZ |
| @@ -1237,27 +1236,24 @@ end_option: | |||
| 1237 | break; | 1236 | break; |
| 1238 | case param_ispeed: | 1237 | case param_ispeed: |
| 1239 | set_speed_or_die(input_speed, argnext, &mode); | 1238 | set_speed_or_die(input_speed, argnext, &mode); |
| 1240 | speed_was_set = 1; | 1239 | option_mask32 |= (STTY_require_set_attr | STTY_speed_was_set); |
| 1241 | require_set_attr = 1; | ||
| 1242 | break; | 1240 | break; |
| 1243 | case param_ospeed: | 1241 | case param_ospeed: |
| 1244 | set_speed_or_die(output_speed, argnext, &mode); | 1242 | set_speed_or_die(output_speed, argnext, &mode); |
| 1245 | speed_was_set = 1; | 1243 | option_mask32 |= (STTY_require_set_attr | STTY_speed_was_set); |
| 1246 | require_set_attr = 1; | ||
| 1247 | break; | 1244 | break; |
| 1248 | default: | 1245 | default: |
| 1249 | if (recover_mode(arg, &mode) == 1) | 1246 | if (recover_mode(arg, &mode) == 1) |
| 1250 | require_set_attr = 1; | 1247 | option_mask32 |= STTY_require_set_attr; |
| 1251 | else /* true: if (string_to_baud_or_die(arg) != (speed_t) -1) */ { | 1248 | else /* true: if (string_to_baud_or_die(arg) != (speed_t) -1) */ { |
| 1252 | set_speed_or_die(both_speeds, arg, &mode); | 1249 | set_speed_or_die(both_speeds, arg, &mode); |
| 1253 | speed_was_set = 1; | 1250 | option_mask32 |= (STTY_require_set_attr | STTY_speed_was_set); |
| 1254 | require_set_attr = 1; | ||
| 1255 | } /* else - impossible (caught in the first pass): | 1251 | } /* else - impossible (caught in the first pass): |
| 1256 | bb_error_msg_and_die("invalid argument '%s'", arg); */ | 1252 | bb_error_msg_and_die("invalid argument '%s'", arg); */ |
| 1257 | } | 1253 | } |
| 1258 | } | 1254 | } |
| 1259 | 1255 | ||
| 1260 | if (require_set_attr) { | 1256 | if (option_mask32 & STTY_require_set_attr) { |
| 1261 | struct termios new_mode; | 1257 | struct termios new_mode; |
| 1262 | 1258 | ||
| 1263 | if (tcsetattr(STDIN_FILENO, TCSADRAIN, &mode)) | 1259 | if (tcsetattr(STDIN_FILENO, TCSADRAIN, &mode)) |
| @@ -1288,7 +1284,8 @@ end_option: | |||
| 1288 | error for a true failure to set the baud rate */ | 1284 | error for a true failure to set the baud rate */ |
| 1289 | 1285 | ||
| 1290 | new_mode.c_cflag &= (~CIBAUD); | 1286 | new_mode.c_cflag &= (~CIBAUD); |
| 1291 | if (speed_was_set || memcmp(&mode, &new_mode, sizeof(mode)) != 0) | 1287 | if (option_mask32 & STTY_speed_was_set || |
| 1288 | memcmp(&mode, &new_mode, sizeof(mode)) != 0) | ||
| 1292 | #endif | 1289 | #endif |
| 1293 | perror_on_device_and_die("%s: cannot perform all requested operations"); | 1290 | perror_on_device_and_die("%s: cannot perform all requested operations"); |
| 1294 | } | 1291 | } |
