aboutsummaryrefslogtreecommitdiff
path: root/coreutils/stty.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/stty.c')
-rw-r--r--coreutils/stty.c151
1 files changed, 148 insertions, 3 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c
index c88ef07f4..c064ad90a 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -20,14 +20,29 @@
20//kbuild:lib-$(CONFIG_STTY) += stty.o 20//kbuild:lib-$(CONFIG_STTY) += stty.o
21 21
22//usage:#define stty_trivial_usage 22//usage:#define stty_trivial_usage
23//usage: IF_NOT_PLATFORM_MINGW32(
23//usage: "[-a|g] [-F DEVICE] [SETTING]..." 24//usage: "[-a|g] [-F DEVICE] [SETTING]..."
25//usage: )
26//usage: IF_PLATFORM_MINGW32(
27//usage: "[-a] [SETTING]..."
28//usage: )
24//usage:#define stty_full_usage "\n\n" 29//usage:#define stty_full_usage "\n\n"
30//usage: IF_NOT_PLATFORM_MINGW32(
25//usage: "Without arguments, prints baud rate, line discipline,\n" 31//usage: "Without arguments, prints baud rate, line discipline,\n"
26//usage: "and deviations from stty sane\n" 32//usage: "and deviations from stty sane\n"
27//usage: "\n -F DEVICE Open device instead of stdin" 33//usage: "\n -F DEVICE Open device instead of stdin"
34//usage: )
35//usage: IF_PLATFORM_MINGW32(
36//usage: "Without arguments, prints deviations from stty sane\n"
37//usage: )
28//usage: "\n -a Print all current settings in human-readable form" 38//usage: "\n -a Print all current settings in human-readable form"
39//usage: IF_NOT_PLATFORM_MINGW32(
29//usage: "\n -g Print in stty-readable form" 40//usage: "\n -g Print in stty-readable form"
30//usage: "\n [SETTING] See manpage" 41//usage: "\n [SETTING] See manpage"
42//usage: )
43//usage: IF_PLATFORM_MINGW32(
44//usage: "\n [SETTING] [-]echo [-]cooked [-]raw sane size"
45//usage: )
31 46
32/* If no args are given, write to stdout the baud rate and settings that 47/* If no args are given, write to stdout the baud rate and settings that
33 * have been changed from their defaults. Mode reading and changes 48 * have been changed from their defaults. Mode reading and changes
@@ -294,6 +309,7 @@ struct mode_info {
294 const tcflag_t bits; /* Bits to set for this mode */ 309 const tcflag_t bits; /* Bits to set for this mode */
295}; 310};
296 311
312#if !ENABLE_PLATFORM_MINGW32
297enum { 313enum {
298 /* Must match mode_name[] and mode_info[] order! */ 314 /* Must match mode_name[] and mode_info[] order! */
299 IDX_evenp = 0, 315 IDX_evenp = 0,
@@ -320,19 +336,30 @@ enum {
320 IDX_LCASE, 336 IDX_LCASE,
321#endif 337#endif
322}; 338};
339#else
340enum {
341 /* Must match mode_name[] and mode_info[] order! */
342 IDX_sane = 0,
343 IDX_cooked,
344 IDX_raw,
345};
346#endif
323 347
324#define MI_ENTRY(N,T,F,B,M) N "\0" 348#define MI_ENTRY(N,T,F,B,M) N "\0"
325 349
326/* Mode names given on command line */ 350/* Mode names given on command line */
327static const char mode_name[] ALIGN1 = 351static const char mode_name[] ALIGN1 =
352#if !ENABLE_PLATFORM_MINGW32
328 MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 ) 353 MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 )
329 MI_ENTRY("parity", combination, REV | OMIT, 0, 0 ) 354 MI_ENTRY("parity", combination, REV | OMIT, 0, 0 )
330 MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 ) 355 MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 )
331 MI_ENTRY("nl", combination, REV | OMIT, 0, 0 ) 356 MI_ENTRY("nl", combination, REV | OMIT, 0, 0 )
332 MI_ENTRY("ek", combination, OMIT, 0, 0 ) 357 MI_ENTRY("ek", combination, OMIT, 0, 0 )
358#endif
333 MI_ENTRY("sane", combination, OMIT, 0, 0 ) 359 MI_ENTRY("sane", combination, OMIT, 0, 0 )
334 MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 ) 360 MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 )
335 MI_ENTRY("raw", combination, REV | OMIT, 0, 0 ) 361 MI_ENTRY("raw", combination, REV | OMIT, 0, 0 )
362#if !ENABLE_PLATFORM_MINGW32
336 MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 ) 363 MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 )
337 MI_ENTRY("litout", combination, REV | OMIT, 0, 0 ) 364 MI_ENTRY("litout", combination, REV | OMIT, 0, 0 )
338 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 ) 365 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
@@ -454,7 +481,9 @@ static const char mode_name[] ALIGN1 =
454#if IEXTEN 481#if IEXTEN
455 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ) 482 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
456#endif 483#endif
484#endif /* !ENABLE_PLATFORM_MINGW32 */
457 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ) 485 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
486#if !ENABLE_PLATFORM_MINGW32
458 MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 ) 487 MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 )
459 MI_ENTRY("crterase", local, OMIT | REV, ECHOE, 0 ) 488 MI_ENTRY("crterase", local, OMIT | REV, ECHOE, 0 )
460 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ) 489 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
@@ -482,6 +511,7 @@ static const char mode_name[] ALIGN1 =
482#ifdef EXTPROC 511#ifdef EXTPROC
483 MI_ENTRY("extproc", local, SANE_UNSET | REV, EXTPROC, 0 ) 512 MI_ENTRY("extproc", local, SANE_UNSET | REV, EXTPROC, 0 )
484#endif 513#endif
514#endif /* !ENABLE_PLATFORM_MINGW32 */
485 ; 515 ;
486 516
487#undef MI_ENTRY 517#undef MI_ENTRY
@@ -489,14 +519,17 @@ static const char mode_name[] ALIGN1 =
489 519
490static const struct mode_info mode_info[] ALIGN4 = { 520static const struct mode_info mode_info[] ALIGN4 = {
491 /* This should be verbatim cut-n-paste copy of the above MI_ENTRYs */ 521 /* This should be verbatim cut-n-paste copy of the above MI_ENTRYs */
522#if !ENABLE_PLATFORM_MINGW32
492 MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 ) 523 MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 )
493 MI_ENTRY("parity", combination, REV | OMIT, 0, 0 ) 524 MI_ENTRY("parity", combination, REV | OMIT, 0, 0 )
494 MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 ) 525 MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 )
495 MI_ENTRY("nl", combination, REV | OMIT, 0, 0 ) 526 MI_ENTRY("nl", combination, REV | OMIT, 0, 0 )
496 MI_ENTRY("ek", combination, OMIT, 0, 0 ) 527 MI_ENTRY("ek", combination, OMIT, 0, 0 )
528#endif
497 MI_ENTRY("sane", combination, OMIT, 0, 0 ) 529 MI_ENTRY("sane", combination, OMIT, 0, 0 )
498 MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 ) 530 MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 )
499 MI_ENTRY("raw", combination, REV | OMIT, 0, 0 ) 531 MI_ENTRY("raw", combination, REV | OMIT, 0, 0 )
532#if !ENABLE_PLATFORM_MINGW32
500 MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 ) 533 MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 )
501 MI_ENTRY("litout", combination, REV | OMIT, 0, 0 ) 534 MI_ENTRY("litout", combination, REV | OMIT, 0, 0 )
502 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 ) 535 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
@@ -618,7 +651,9 @@ static const struct mode_info mode_info[] ALIGN4 = {
618#if IEXTEN 651#if IEXTEN
619 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ) 652 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
620#endif 653#endif
654#endif /* !ENABLE_PLATFORM_MINGW32 */
621 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ) 655 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
656#if !ENABLE_PLATFORM_MINGW32
622 MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 ) 657 MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 )
623 MI_ENTRY("crterase", local, OMIT | REV, ECHOE, 0 ) 658 MI_ENTRY("crterase", local, OMIT | REV, ECHOE, 0 )
624 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ) 659 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
@@ -646,6 +681,7 @@ static const struct mode_info mode_info[] ALIGN4 = {
646#ifdef EXTPROC 681#ifdef EXTPROC
647 MI_ENTRY("extproc", local, SANE_UNSET | REV, EXTPROC, 0 ) 682 MI_ENTRY("extproc", local, SANE_UNSET | REV, EXTPROC, 0 )
648#endif 683#endif
684#endif /* !ENABLE_PLATFORM_MINGW32 */
649}; 685};
650 686
651enum { 687enum {
@@ -653,6 +689,7 @@ enum {
653}; 689};
654 690
655 691
692#if !ENABLE_PLATFORM_MINGW32
656/* Control characters */ 693/* Control characters */
657struct control_info { 694struct control_info {
658 const uint8_t saneval; /* Value to set for 'stty sane' */ 695 const uint8_t saneval; /* Value to set for 'stty sane' */
@@ -786,6 +823,7 @@ static const struct control_info control_info[] ALIGN2 = {
786enum { 823enum {
787 NUM_control_info = ARRAY_SIZE(control_info) 824 NUM_control_info = ARRAY_SIZE(control_info)
788}; 825};
826#endif
789 827
790 828
791struct globals { 829struct globals {
@@ -803,6 +841,7 @@ struct globals {
803 G.current_col = 0; /* we are noexec, must clear */ \ 841 G.current_col = 0; /* we are noexec, must clear */ \
804} while (0) 842} while (0)
805 843
844#if !ENABLE_PLATFORM_MINGW32
806static void set_speed_or_die(enum speed_setting type, const char *arg, 845static void set_speed_or_die(enum speed_setting type, const char *arg,
807 struct termios *mode) 846 struct termios *mode)
808{ 847{
@@ -817,6 +856,7 @@ static void set_speed_or_die(enum speed_setting type, const char *arg,
817 cfsetospeed(mode, baud); 856 cfsetospeed(mode, baud);
818 } 857 }
819} 858}
859#endif
820 860
821static NORETURN void perror_on_device_and_die(const char *fmt) 861static NORETURN void perror_on_device_and_die(const char *fmt)
822{ 862{
@@ -867,6 +907,7 @@ static void newline(void)
867 wrapf("\n"); 907 wrapf("\n");
868} 908}
869 909
910#if !ENABLE_PLATFORM_MINGW32
870#ifdef TIOCGWINSZ 911#ifdef TIOCGWINSZ
871static void set_window_size(int rows, int cols) 912static void set_window_size(int rows, int cols)
872{ 913{
@@ -889,6 +930,7 @@ bail:
889 perror_on_device("%s"); 930 perror_on_device("%s");
890} 931}
891#endif 932#endif
933#endif
892 934
893static void display_window_size(int fancy) 935static void display_window_size(int fancy)
894{ 936{
@@ -918,6 +960,7 @@ static const struct mode_info *find_mode(const char *name)
918 return i >= 0 ? &mode_info[i] : NULL; 960 return i >= 0 ? &mode_info[i] : NULL;
919} 961}
920 962
963#if !ENABLE_PLATFORM_MINGW32
921static const struct control_info *find_control(const char *name) 964static const struct control_info *find_control(const char *name)
922{ 965{
923 int i = index_in_strings(control_name, name); 966 int i = index_in_strings(control_name, name);
@@ -954,7 +997,32 @@ static int find_param(const char *name)
954 i |= 0x80; 997 i |= 0x80;
955 return i; 998 return i;
956} 999}
1000#else
1001enum {
1002 param_need_arg = 0x80,
1003 param_rows = 1 | 0x80,
1004 param_cols = 2 | 0x80,
1005 param_columns = 3 | 0x80,
1006 param_size = 4,
1007};
1008
1009static int find_param(const char *name)
1010{
1011 static const char params[] ALIGN1 =
1012 "rows\0" /* 1 */
1013 "cols\0" /* 2 */
1014 "columns\0" /* 3 */
1015 "size\0"; /* 4 */
1016 int i = index_in_strings(params, name) + 1;
1017 if (i == 0)
1018 return 0;
1019 if (i != 4)
1020 i |= 0x80;
1021 return i;
1022}
1023#endif
957 1024
1025#if !ENABLE_PLATFORM_MINGW32
958static int recover_mode(const char *arg, struct termios *mode) 1026static int recover_mode(const char *arg, struct termios *mode)
959{ 1027{
960 int i, n; 1028 int i, n;
@@ -1013,6 +1081,9 @@ static void display_speed(const struct termios *mode, int fancy)
1013 if (fancy) fmt_str += 9; 1081 if (fancy) fmt_str += 9;
1014 wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed)); 1082 wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed));
1015} 1083}
1084#else
1085# define display_speed(m, f) ((void)0)
1086#endif
1016 1087
1017static void do_display(const struct termios *mode, int all) 1088static void do_display(const struct termios *mode, int all)
1018{ 1089{
@@ -1030,6 +1101,7 @@ static void do_display(const struct termios *mode, int all)
1030 newline(); 1101 newline();
1031#endif 1102#endif
1032 1103
1104#if !ENABLE_PLATFORM_MINGW32
1033 for (i = 0; i != CIDX_min; ++i) { 1105 for (i = 0; i != CIDX_min; ++i) {
1034 char ch; 1106 char ch;
1035 char buf10[10]; 1107 char buf10[10];
@@ -1059,6 +1131,7 @@ static void do_display(const struct termios *mode, int all)
1059#endif 1131#endif
1060 wrapf("min = %u; time = %u;", mode->c_cc[VMIN], mode->c_cc[VTIME]); 1132 wrapf("min = %u; time = %u;", mode->c_cc[VMIN], mode->c_cc[VTIME]);
1061 newline(); 1133 newline();
1134#endif
1062 1135
1063 for (i = 0; i < NUM_mode_info; ++i) { 1136 for (i = 0; i < NUM_mode_info; ++i) {
1064 if (mode_info[i].flags & OMIT) 1137 if (mode_info[i].flags & OMIT)
@@ -1086,6 +1159,7 @@ static void do_display(const struct termios *mode, int all)
1086 1159
1087static void sane_mode(struct termios *mode) 1160static void sane_mode(struct termios *mode)
1088{ 1161{
1162#if !ENABLE_PLATFORM_MINGW32
1089 int i; 1163 int i;
1090 1164
1091 for (i = 0; i < NUM_control_info; ++i) { 1165 for (i = 0; i < NUM_control_info; ++i) {
@@ -1110,6 +1184,11 @@ static void sane_mode(struct termios *mode)
1110 *bitsp = val & ~mode_info[i].bits; 1184 *bitsp = val & ~mode_info[i].bits;
1111 } 1185 }
1112 } 1186 }
1187#else
1188 mode->c_lflag |= ECHO;
1189 mode->w_mode |= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT |
1190 ENABLE_PROCESSED_INPUT;
1191#endif
1113} 1192}
1114 1193
1115static void set_mode(const struct mode_info *info, int reversed, 1194static void set_mode(const struct mode_info *info, int reversed,
@@ -1129,6 +1208,7 @@ static void set_mode(const struct mode_info *info, int reversed,
1129 } 1208 }
1130 1209
1131 /* !bitsp - it's a "combination" mode */ 1210 /* !bitsp - it's a "combination" mode */
1211#if !ENABLE_PLATFORM_MINGW32
1132 if (info == &mode_info[IDX_evenp] || info == &mode_info[IDX_parity]) { 1212 if (info == &mode_info[IDX_evenp] || info == &mode_info[IDX_parity]) {
1133 if (reversed) 1213 if (reversed)
1134 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 1214 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
@@ -1150,9 +1230,14 @@ static void set_mode(const struct mode_info *info, int reversed,
1150 } else if (info == &mode_info[IDX_ek]) { 1230 } else if (info == &mode_info[IDX_ek]) {
1151 mode->c_cc[VERASE] = CERASE; 1231 mode->c_cc[VERASE] = CERASE;
1152 mode->c_cc[VKILL] = CKILL; 1232 mode->c_cc[VKILL] = CKILL;
1153 } else if (info == &mode_info[IDX_sane]) { 1233 }
1234 else
1235#endif /* !ENABLE_PLATFORM_MINGW32 */
1236 if (info == &mode_info[IDX_sane]) {
1154 sane_mode(mode); 1237 sane_mode(mode);
1155 } else if (info == &mode_info[IDX_cbreak]) { 1238 }
1239#if !ENABLE_PLATFORM_MINGW32
1240 else if (info == &mode_info[IDX_cbreak]) {
1156 if (reversed) 1241 if (reversed)
1157 mode->c_lflag |= ICANON; 1242 mode->c_lflag |= ICANON;
1158 else 1243 else
@@ -1175,11 +1260,14 @@ static void set_mode(const struct mode_info *info, int reversed,
1175 mode->c_iflag &= ~ISTRIP; 1260 mode->c_iflag &= ~ISTRIP;
1176 mode->c_oflag &= ~OPOST; 1261 mode->c_oflag &= ~OPOST;
1177 } 1262 }
1178 } else if (info == &mode_info[IDX_raw] || info == &mode_info[IDX_cooked]) { 1263 }
1264#endif /* !ENABLE_PLATFORM_MINGW32 */
1265 else if (info == &mode_info[IDX_raw] || info == &mode_info[IDX_cooked]) {
1179 if ((info == &mode_info[IDX_raw] && reversed) 1266 if ((info == &mode_info[IDX_raw] && reversed)
1180 || (info == &mode_info[IDX_cooked] && !reversed) 1267 || (info == &mode_info[IDX_cooked] && !reversed)
1181 ) { 1268 ) {
1182 /* Cooked mode */ 1269 /* Cooked mode */
1270#if !ENABLE_PLATFORM_MINGW32
1183 mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON; 1271 mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON;
1184 mode->c_oflag |= OPOST; 1272 mode->c_oflag |= OPOST;
1185 mode->c_lflag |= ISIG | ICANON; 1273 mode->c_lflag |= ISIG | ICANON;
@@ -1189,15 +1277,23 @@ static void set_mode(const struct mode_info *info, int reversed,
1189#if VTIME == VEOL 1277#if VTIME == VEOL
1190 mode->c_cc[VEOL] = CEOL; 1278 mode->c_cc[VEOL] = CEOL;
1191#endif 1279#endif
1280#else
1281 mode->w_mode |= ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
1282#endif
1192 } else { 1283 } else {
1193 /* Raw mode */ 1284 /* Raw mode */
1285#if !ENABLE_PLATFORM_MINGW32
1194 mode->c_iflag = 0; 1286 mode->c_iflag = 0;
1195 mode->c_oflag &= ~OPOST; 1287 mode->c_oflag &= ~OPOST;
1196 mode->c_lflag &= ~(ISIG | ICANON | XCASE); 1288 mode->c_lflag &= ~(ISIG | ICANON | XCASE);
1197 mode->c_cc[VMIN] = 1; 1289 mode->c_cc[VMIN] = 1;
1198 mode->c_cc[VTIME] = 0; 1290 mode->c_cc[VTIME] = 0;
1291#else
1292 mode->w_mode &= ~(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
1293#endif
1199 } 1294 }
1200 } 1295 }
1296#if !ENABLE_PLATFORM_MINGW32
1201#if IXANY 1297#if IXANY
1202 else if (info == &mode_info[IDX_decctlq]) { 1298 else if (info == &mode_info[IDX_decctlq]) {
1203 if (reversed) 1299 if (reversed)
@@ -1244,8 +1340,10 @@ static void set_mode(const struct mode_info *info, int reversed,
1244 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; 1340 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE;
1245 if (IXANY) mode->c_iflag &= ~IXANY; 1341 if (IXANY) mode->c_iflag &= ~IXANY;
1246 } 1342 }
1343#endif /*!ENABLE_PLATFORM_MINGW32 */
1247} 1344}
1248 1345
1346#if !ENABLE_PLATFORM_MINGW32
1249static void set_control_char_or_die(const struct control_info *info, 1347static void set_control_char_or_die(const struct control_info *info,
1250 const char *arg, struct termios *mode) 1348 const char *arg, struct termios *mode)
1251{ 1349{
@@ -1265,6 +1363,7 @@ static void set_control_char_or_die(const struct control_info *info,
1265 value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes); 1363 value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes);
1266 mode->c_cc[info->offset] = value; 1364 mode->c_cc[info->offset] = value;
1267} 1365}
1366#endif
1268 1367
1269#define STTY_require_set_attr (1 << 0) 1368#define STTY_require_set_attr (1 << 0)
1270#define STTY_speed_was_set (1 << 1) 1369#define STTY_speed_was_set (1 << 1)
@@ -1277,7 +1376,9 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1277{ 1376{
1278 struct termios mode; 1377 struct termios mode;
1279 void (*output_func)(const struct termios *, int); 1378 void (*output_func)(const struct termios *, int);
1379#if !ENABLE_PLATFORM_MINGW32
1280 const char *file_name = NULL; 1380 const char *file_name = NULL;
1381#endif
1281 int display_all = 0; 1382 int display_all = 0;
1282 int stty_state; 1383 int stty_state;
1283 int k; 1384 int k;
@@ -1291,7 +1392,9 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1291 k = 0; 1392 k = 0;
1292 while (argv[++k]) { 1393 while (argv[++k]) {
1293 const struct mode_info *mp; 1394 const struct mode_info *mp;
1395#if !ENABLE_PLATFORM_MINGW32
1294 const struct control_info *cp; 1396 const struct control_info *cp;
1397#endif
1295 const char *arg = argv[k]; 1398 const char *arg = argv[k];
1296 const char *argnext = argv[k+1]; 1399 const char *argnext = argv[k+1];
1297 int param; 1400 int param;
@@ -1314,6 +1417,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1314 output_func = do_display; 1417 output_func = do_display;
1315 display_all = 1; 1418 display_all = 1;
1316 break; 1419 break;
1420#if !ENABLE_PLATFORM_MINGW32
1317 case 'g': 1421 case 'g':
1318 stty_state |= STTY_recoverable_output; 1422 stty_state |= STTY_recoverable_output;
1319 output_func = display_recoverable; 1423 output_func = display_recoverable;
@@ -1334,11 +1438,14 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1334 } 1438 }
1335 } 1439 }
1336 goto end_option; 1440 goto end_option;
1441#endif
1337 default: 1442 default:
1338 goto invalid_argument; 1443 goto invalid_argument;
1339 } 1444 }
1340 } 1445 }
1446#if !ENABLE_PLATFORM_MINGW32
1341 end_option: 1447 end_option:
1448#endif
1342 continue; 1449 continue;
1343 } 1450 }
1344 1451
@@ -1348,6 +1455,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1348 continue; 1455 continue;
1349 } 1456 }
1350 1457
1458#if !ENABLE_PLATFORM_MINGW32
1351 cp = find_control(arg); 1459 cp = find_control(arg);
1352 if (cp) { 1460 if (cp) {
1353 if (!argnext) 1461 if (!argnext)
@@ -1358,13 +1466,16 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1358 ++k; 1466 ++k;
1359 continue; 1467 continue;
1360 } 1468 }
1469#endif
1361 1470
1362 param = find_param(arg); 1471 param = find_param(arg);
1472#if !ENABLE_PLATFORM_MINGW32
1363 if (param & param_need_arg) { 1473 if (param & param_need_arg) {
1364 if (!argnext) 1474 if (!argnext)
1365 bb_error_msg_and_die(bb_msg_requires_arg, arg); 1475 bb_error_msg_and_die(bb_msg_requires_arg, arg);
1366 ++k; 1476 ++k;
1367 } 1477 }
1478#endif
1368 1479
1369 switch (param) { 1480 switch (param) {
1370#ifdef __linux__ 1481#ifdef __linux__
@@ -1381,7 +1492,11 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1381 xatoul_range_sfx(argnext, 1, INT_MAX, stty_suffixes); 1492 xatoul_range_sfx(argnext, 1, INT_MAX, stty_suffixes);
1382 break; 1493 break;
1383 case param_size: 1494 case param_size:
1495# if ENABLE_PLATFORM_MINGW32
1496 break;
1497# endif
1384#endif 1498#endif
1499#if !ENABLE_PLATFORM_MINGW32
1385 case param_speed: 1500 case param_speed:
1386 break; 1501 break;
1387 case param_ispeed: 1502 case param_ispeed:
@@ -1392,15 +1507,19 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1392 /* called for the side effect of xfunc death only */ 1507 /* called for the side effect of xfunc death only */
1393 set_speed_or_die(output_speed, argnext, &mode); 1508 set_speed_or_die(output_speed, argnext, &mode);
1394 break; 1509 break;
1510#endif
1395 default: 1511 default:
1512#if !ENABLE_PLATFORM_MINGW32
1396 if (recover_mode(arg, &mode) == 1) break; 1513 if (recover_mode(arg, &mode) == 1) break;
1397 if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) break; 1514 if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) break;
1515#endif
1398 invalid_argument: 1516 invalid_argument:
1399 bb_error_msg_and_die("invalid argument '%s'", arg); 1517 bb_error_msg_and_die("invalid argument '%s'", arg);
1400 } 1518 }
1401 stty_state &= ~STTY_noargs; 1519 stty_state &= ~STTY_noargs;
1402 } 1520 }
1403 1521
1522#if !ENABLE_PLATFORM_MINGW32
1404 /* Specifying both -a and -g is an error */ 1523 /* Specifying both -a and -g is an error */
1405 if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) == 1524 if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) ==
1406 (STTY_verbose_output | STTY_recoverable_output) 1525 (STTY_verbose_output | STTY_recoverable_output)
@@ -1413,13 +1532,22 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1413 ) { 1532 ) {
1414 bb_simple_error_msg_and_die("modes may not be set when -a or -g is used"); 1533 bb_simple_error_msg_and_die("modes may not be set when -a or -g is used");
1415 } 1534 }
1535#else
1536 /* Specifying -a with non-options is an error */
1537 if ((stty_state & STTY_verbose_output) && !(stty_state & STTY_noargs)
1538 ) {
1539 bb_simple_error_msg_and_die("modes may not be set when -a is used");
1540 }
1541#endif
1416 1542
1543#if !ENABLE_PLATFORM_MINGW32
1417 /* Now it is safe to start doing things */ 1544 /* Now it is safe to start doing things */
1418 if (file_name) { 1545 if (file_name) {
1419 G.device_name = file_name; 1546 G.device_name = file_name;
1420 xmove_fd(xopen_nonblocking(G.device_name), STDIN_FILENO); 1547 xmove_fd(xopen_nonblocking(G.device_name), STDIN_FILENO);
1421 ndelay_off(STDIN_FILENO); 1548 ndelay_off(STDIN_FILENO);
1422 } 1549 }
1550#endif
1423 1551
1424 /* Initialize to all zeroes so there is no risk memcmp will report a 1552 /* Initialize to all zeroes so there is no risk memcmp will report a
1425 spurious difference in an uninitialized portion of the structure */ 1553 spurious difference in an uninitialized portion of the structure */
@@ -1437,9 +1565,13 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1437 k = 0; 1565 k = 0;
1438 while (argv[++k]) { 1566 while (argv[++k]) {
1439 const struct mode_info *mp; 1567 const struct mode_info *mp;
1568#if !ENABLE_PLATFORM_MINGW32
1440 const struct control_info *cp; 1569 const struct control_info *cp;
1570#endif
1441 const char *arg = argv[k]; 1571 const char *arg = argv[k];
1572#if !ENABLE_PLATFORM_MINGW32
1442 const char *argnext = argv[k+1]; 1573 const char *argnext = argv[k+1];
1574#endif
1443 int param; 1575 int param;
1444 1576
1445 if (arg[0] == '-') { 1577 if (arg[0] == '-') {
@@ -1459,6 +1591,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1459 continue; 1591 continue;
1460 } 1592 }
1461 1593
1594#if !ENABLE_PLATFORM_MINGW32
1462 cp = find_control(arg); 1595 cp = find_control(arg);
1463 if (cp) { 1596 if (cp) {
1464 ++k; 1597 ++k;
@@ -1466,6 +1599,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1466 stty_state |= STTY_require_set_attr; 1599 stty_state |= STTY_require_set_attr;
1467 continue; 1600 continue;
1468 } 1601 }
1602#endif
1469 1603
1470 param = find_param(arg); 1604 param = find_param(arg);
1471 if (param & param_need_arg) { 1605 if (param & param_need_arg) {
@@ -1479,6 +1613,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1479 stty_state |= STTY_require_set_attr; 1613 stty_state |= STTY_require_set_attr;
1480 break; 1614 break;
1481#endif 1615#endif
1616#if !ENABLE_PLATFORM_MINGW32
1482#ifdef TIOCGWINSZ 1617#ifdef TIOCGWINSZ
1483 case param_cols: 1618 case param_cols:
1484 case param_columns: 1619 case param_columns:
@@ -1510,15 +1645,24 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1510 stty_state |= (STTY_require_set_attr | STTY_speed_was_set); 1645 stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
1511 } /* else - impossible (caught in the first pass): 1646 } /* else - impossible (caught in the first pass):
1512 bb_error_msg_and_die("invalid argument '%s'", arg); */ 1647 bb_error_msg_and_die("invalid argument '%s'", arg); */
1648#endif
1513 } 1649 }
1514 } 1650 }
1515 1651
1516 if (stty_state & STTY_require_set_attr) { 1652 if (stty_state & STTY_require_set_attr) {
1653#if !ENABLE_PLATFORM_MINGW32
1517 struct termios new_mode; 1654 struct termios new_mode;
1655#else
1656 if (mode.c_lflag & ECHO)
1657 mode.w_mode |= ENABLE_ECHO_INPUT;
1658 else
1659 mode.w_mode &= ~ENABLE_ECHO_INPUT;
1660#endif
1518 1661
1519 if (tcsetattr(STDIN_FILENO, TCSADRAIN, &mode)) 1662 if (tcsetattr(STDIN_FILENO, TCSADRAIN, &mode))
1520 perror_on_device_and_die("%s"); 1663 perror_on_device_and_die("%s");
1521 1664
1665#if !ENABLE_PLATFORM_MINGW32
1522 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if 1666 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
1523 it performs *any* of the requested operations. This means it 1667 it performs *any* of the requested operations. This means it
1524 can report 'success' when it has actually failed to perform 1668 can report 'success' when it has actually failed to perform
@@ -1554,6 +1698,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1554#endif 1698#endif
1555 perror_on_device_and_die("%s: cannot perform all requested operations"); 1699 perror_on_device_and_die("%s: cannot perform all requested operations");
1556 } 1700 }
1701#endif
1557 } 1702 }
1558 1703
1559 return EXIT_SUCCESS; 1704 return EXIT_SUCCESS;