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/stty.c | |
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/stty.c')
-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 | } |