aboutsummaryrefslogtreecommitdiff
path: root/coreutils/stty.c
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2007-01-17 19:42:30 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2007-01-17 19:42:30 +0000
commit4fa566d4adcf56d74f3ddc271fd19be61510c568 (patch)
tree25c0badea243019e72ea231ebe7fe7663dcc3dac /coreutils/stty.c
parent9e8df9354a30a9206d4cefd0d88bae5b776a0cb7 (diff)
downloadbusybox-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.c69
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)
1017int stty_main(int argc, char **argv) 1022int 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 }
1084end_option: 1079end_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;
1135invalid_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 }