diff options
Diffstat (limited to 'coreutils/stty.c')
-rw-r--r-- | coreutils/stty.c | 493 |
1 files changed, 206 insertions, 287 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c index a67a17c0f..a3a98d9ef 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c | |||
@@ -30,9 +30,9 @@ | |||
30 | 30 | ||
31 | //#define TEST | 31 | //#define TEST |
32 | 32 | ||
33 | #include <stddef.h> | ||
33 | #include <termios.h> | 34 | #include <termios.h> |
34 | #include <sys/ioctl.h> | 35 | #include <sys/ioctl.h> |
35 | #include <getopt.h> | ||
36 | 36 | ||
37 | #include <sys/param.h> | 37 | #include <sys/param.h> |
38 | #include <unistd.h> | 38 | #include <unistd.h> |
@@ -155,13 +155,10 @@ enum speed_setting { | |||
155 | input_speed, output_speed, both_speeds | 155 | input_speed, output_speed, both_speeds |
156 | }; | 156 | }; |
157 | 157 | ||
158 | /* What to output and how. */ | ||
159 | enum output_type { | ||
160 | changed, all, recoverable /* Default, -a, -g. */ | ||
161 | }; | ||
162 | |||
163 | /* Which member(s) of `struct termios' a mode uses. */ | 158 | /* Which member(s) of `struct termios' a mode uses. */ |
164 | enum mode_type { | 159 | enum mode_type { |
160 | /* Do NOT change the order or values, as mode_type_flag() | ||
161 | * depends on them. */ | ||
165 | control, input, output, local, combination | 162 | control, input, output, local, combination |
166 | }; | 163 | }; |
167 | 164 | ||
@@ -199,156 +196,159 @@ static const char stty_dec [] = "dec"; | |||
199 | /* Each mode. */ | 196 | /* Each mode. */ |
200 | struct mode_info { | 197 | struct mode_info { |
201 | const char *name; /* Name given on command line. */ | 198 | const char *name; /* Name given on command line. */ |
202 | enum mode_type type; /* Which structure element to change. */ | 199 | /* enum mode_type type; */ |
200 | char type; /* Which structure element to change. */ | ||
203 | char flags; /* Setting and display options. */ | 201 | char flags; /* Setting and display options. */ |
202 | unsigned short mask; /* Other bits to turn off for this mode. */ | ||
204 | unsigned long bits; /* Bits to set for this mode. */ | 203 | unsigned long bits; /* Bits to set for this mode. */ |
205 | unsigned long mask; /* Other bits to turn off for this mode. */ | ||
206 | }; | 204 | }; |
207 | 205 | ||
206 | #define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B } | ||
207 | |||
208 | static const struct mode_info mode_info[] = { | 208 | static const struct mode_info mode_info[] = { |
209 | {"parenb", control, REV, PARENB, 0 }, | 209 | MI_ENTRY("parenb", control, REV, PARENB, 0 ), |
210 | {"parodd", control, REV, PARODD, 0 }, | 210 | MI_ENTRY("parodd", control, REV, PARODD, 0 ), |
211 | {"cs5", control, 0, CS5, CSIZE}, | 211 | MI_ENTRY("cs5", control, 0, CS5, CSIZE), |
212 | {"cs6", control, 0, CS6, CSIZE}, | 212 | MI_ENTRY("cs6", control, 0, CS6, CSIZE), |
213 | {"cs7", control, 0, CS7, CSIZE}, | 213 | MI_ENTRY("cs7", control, 0, CS7, CSIZE), |
214 | {"cs8", control, 0, CS8, CSIZE}, | 214 | MI_ENTRY("cs8", control, 0, CS8, CSIZE), |
215 | {"hupcl", control, REV, HUPCL, 0 }, | 215 | MI_ENTRY("hupcl", control, REV, HUPCL, 0 ), |
216 | {"hup", control, REV | OMIT, HUPCL, 0 }, | 216 | MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 ), |
217 | {"cstopb", control, REV, CSTOPB, 0 }, | 217 | MI_ENTRY("cstopb", control, REV, CSTOPB, 0 ), |
218 | {"cread", control, SANE_SET | REV, CREAD, 0 }, | 218 | MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 ), |
219 | {"clocal", control, REV, CLOCAL, 0 }, | 219 | MI_ENTRY("clocal", control, REV, CLOCAL, 0 ), |
220 | #ifdef CRTSCTS | 220 | #ifdef CRTSCTS |
221 | {"crtscts", control, REV, CRTSCTS, 0 }, | 221 | MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 ), |
222 | #endif | 222 | #endif |
223 | {"ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 }, | 223 | MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 ), |
224 | {"brkint", input, SANE_SET | REV, BRKINT, 0 }, | 224 | MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 ), |
225 | {"ignpar", input, REV, IGNPAR, 0 }, | 225 | MI_ENTRY("ignpar", input, REV, IGNPAR, 0 ), |
226 | {"parmrk", input, REV, PARMRK, 0 }, | 226 | MI_ENTRY("parmrk", input, REV, PARMRK, 0 ), |
227 | {"inpck", input, REV, INPCK, 0 }, | 227 | MI_ENTRY("inpck", input, REV, INPCK, 0 ), |
228 | {"istrip", input, REV, ISTRIP, 0 }, | 228 | MI_ENTRY("istrip", input, REV, ISTRIP, 0 ), |
229 | {"inlcr", input, SANE_UNSET | REV, INLCR, 0 }, | 229 | MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 ), |
230 | {"igncr", input, SANE_UNSET | REV, IGNCR, 0 }, | 230 | MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 ), |
231 | {"icrnl", input, SANE_SET | REV, ICRNL, 0 }, | 231 | MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 ), |
232 | {"ixon", input, REV, IXON, 0 }, | 232 | MI_ENTRY("ixon", input, REV, IXON, 0 ), |
233 | {"ixoff", input, SANE_UNSET | REV, IXOFF, 0 }, | 233 | MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 ), |
234 | {"tandem", input, REV | OMIT, IXOFF, 0 }, | 234 | MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 ), |
235 | #ifdef IUCLC | 235 | #ifdef IUCLC |
236 | {"iuclc", input, SANE_UNSET | REV, IUCLC, 0 }, | 236 | MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 ), |
237 | #endif | 237 | #endif |
238 | #ifdef IXANY | 238 | #ifdef IXANY |
239 | {"ixany", input, SANE_UNSET | REV, IXANY, 0 }, | 239 | MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 ), |
240 | #endif | 240 | #endif |
241 | #ifdef IMAXBEL | 241 | #ifdef IMAXBEL |
242 | {"imaxbel", input, SANE_SET | REV, IMAXBEL, 0 }, | 242 | MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 ), |
243 | #endif | 243 | #endif |
244 | {"opost", output, SANE_SET | REV, OPOST, 0 }, | 244 | MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 ), |
245 | #ifdef OLCUC | 245 | #ifdef OLCUC |
246 | {"olcuc", output, SANE_UNSET | REV, OLCUC, 0 }, | 246 | MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 ), |
247 | #endif | 247 | #endif |
248 | #ifdef OCRNL | 248 | #ifdef OCRNL |
249 | {"ocrnl", output, SANE_UNSET | REV, OCRNL, 0 }, | 249 | MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 ), |
250 | #endif | 250 | #endif |
251 | #ifdef ONLCR | 251 | #ifdef ONLCR |
252 | {"onlcr", output, SANE_SET | REV, ONLCR, 0 }, | 252 | MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 ), |
253 | #endif | 253 | #endif |
254 | #ifdef ONOCR | 254 | #ifdef ONOCR |
255 | {"onocr", output, SANE_UNSET | REV, ONOCR, 0 }, | 255 | MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 ), |
256 | #endif | 256 | #endif |
257 | #ifdef ONLRET | 257 | #ifdef ONLRET |
258 | {"onlret", output, SANE_UNSET | REV, ONLRET, 0 }, | 258 | MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 ), |
259 | #endif | 259 | #endif |
260 | #ifdef OFILL | 260 | #ifdef OFILL |
261 | {"ofill", output, SANE_UNSET | REV, OFILL, 0 }, | 261 | MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 ), |
262 | #endif | 262 | #endif |
263 | #ifdef OFDEL | 263 | #ifdef OFDEL |
264 | {"ofdel", output, SANE_UNSET | REV, OFDEL, 0 }, | 264 | MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 ), |
265 | #endif | 265 | #endif |
266 | #ifdef NLDLY | 266 | #ifdef NLDLY |
267 | {"nl1", output, SANE_UNSET, NL1, NLDLY}, | 267 | MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY), |
268 | {"nl0", output, SANE_SET, NL0, NLDLY}, | 268 | MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY), |
269 | #endif | 269 | #endif |
270 | #ifdef CRDLY | 270 | #ifdef CRDLY |
271 | {"cr3", output, SANE_UNSET, CR3, CRDLY}, | 271 | MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY), |
272 | {"cr2", output, SANE_UNSET, CR2, CRDLY}, | 272 | MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY), |
273 | {"cr1", output, SANE_UNSET, CR1, CRDLY}, | 273 | MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY), |
274 | {"cr0", output, SANE_SET, CR0, CRDLY}, | 274 | MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY), |
275 | #endif | 275 | #endif |
276 | 276 | ||
277 | #ifdef TABDLY | 277 | #ifdef TABDLY |
278 | {"tab3", output, SANE_UNSET, TAB3, TABDLY}, | 278 | MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY), |
279 | {"tab2", output, SANE_UNSET, TAB2, TABDLY}, | 279 | MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY), |
280 | {"tab1", output, SANE_UNSET, TAB1, TABDLY}, | 280 | MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY), |
281 | {"tab0", output, SANE_SET, TAB0, TABDLY}, | 281 | MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY), |
282 | #else | 282 | #else |
283 | # ifdef OXTABS | 283 | # ifdef OXTABS |
284 | {"tab3", output, SANE_UNSET, OXTABS, 0 }, | 284 | MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 ), |
285 | # endif | 285 | # endif |
286 | #endif | 286 | #endif |
287 | 287 | ||
288 | #ifdef BSDLY | 288 | #ifdef BSDLY |
289 | {"bs1", output, SANE_UNSET, BS1, BSDLY}, | 289 | MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY), |
290 | {"bs0", output, SANE_SET, BS0, BSDLY}, | 290 | MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY), |
291 | #endif | 291 | #endif |
292 | #ifdef VTDLY | 292 | #ifdef VTDLY |
293 | {"vt1", output, SANE_UNSET, VT1, VTDLY}, | 293 | MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY), |
294 | {"vt0", output, SANE_SET, VT0, VTDLY}, | 294 | MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY), |
295 | #endif | 295 | #endif |
296 | #ifdef FFDLY | 296 | #ifdef FFDLY |
297 | {"ff1", output, SANE_UNSET, FF1, FFDLY}, | 297 | MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY), |
298 | {"ff0", output, SANE_SET, FF0, FFDLY}, | 298 | MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY), |
299 | #endif | 299 | #endif |
300 | {"isig", local, SANE_SET | REV, ISIG, 0 }, | 300 | MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 ), |
301 | {"icanon", local, SANE_SET | REV, ICANON, 0 }, | 301 | MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 ), |
302 | #ifdef IEXTEN | 302 | #ifdef IEXTEN |
303 | {"iexten", local, SANE_SET | REV, IEXTEN, 0 }, | 303 | MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ), |
304 | #endif | 304 | #endif |
305 | {"echo", local, SANE_SET | REV, ECHO, 0 }, | 305 | MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ), |
306 | {"echoe", local, SANE_SET | REV, ECHOE, 0 }, | 306 | MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 ), |
307 | {"crterase", local, REV | OMIT, ECHOE, 0 }, | 307 | MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 ), |
308 | {"echok", local, SANE_SET | REV, ECHOK, 0 }, | 308 | MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ), |
309 | {"echonl", local, SANE_UNSET | REV, ECHONL, 0 }, | 309 | MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 ), |
310 | {"noflsh", local, SANE_UNSET | REV, NOFLSH, 0 }, | 310 | MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 ), |
311 | #ifdef XCASE | 311 | #ifdef XCASE |
312 | {"xcase", local, SANE_UNSET | REV, XCASE, 0 }, | 312 | MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 ), |
313 | #endif | 313 | #endif |
314 | #ifdef TOSTOP | 314 | #ifdef TOSTOP |
315 | {"tostop", local, SANE_UNSET | REV, TOSTOP, 0 }, | 315 | MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 ), |
316 | #endif | 316 | #endif |
317 | #ifdef ECHOPRT | 317 | #ifdef ECHOPRT |
318 | {"echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 }, | 318 | MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 ), |
319 | {"prterase", local, REV | OMIT, ECHOPRT, 0 }, | 319 | MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 ), |
320 | #endif | 320 | #endif |
321 | #ifdef ECHOCTL | 321 | #ifdef ECHOCTL |
322 | {"echoctl", local, SANE_SET | REV, ECHOCTL, 0 }, | 322 | MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 ), |
323 | {"ctlecho", local, REV | OMIT, ECHOCTL, 0 }, | 323 | MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 ), |
324 | #endif | 324 | #endif |
325 | #ifdef ECHOKE | 325 | #ifdef ECHOKE |
326 | {"echoke", local, SANE_SET | REV, ECHOKE, 0 }, | 326 | MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 ), |
327 | {"crtkill", local, REV | OMIT, ECHOKE, 0 }, | 327 | MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 ), |
328 | #endif | 328 | #endif |
329 | {evenp, combination, REV | OMIT, 0, 0 }, | 329 | MI_ENTRY(evenp, combination, REV | OMIT, 0, 0 ), |
330 | {parity, combination, REV | OMIT, 0, 0 }, | 330 | MI_ENTRY(parity, combination, REV | OMIT, 0, 0 ), |
331 | {stty_oddp, combination, REV | OMIT, 0, 0 }, | 331 | MI_ENTRY(stty_oddp, combination, REV | OMIT, 0, 0 ), |
332 | {stty_nl, combination, REV | OMIT, 0, 0 }, | 332 | MI_ENTRY(stty_nl, combination, REV | OMIT, 0, 0 ), |
333 | {stty_ek, combination, OMIT, 0, 0 }, | 333 | MI_ENTRY(stty_ek, combination, OMIT, 0, 0 ), |
334 | {stty_sane, combination, OMIT, 0, 0 }, | 334 | MI_ENTRY(stty_sane, combination, OMIT, 0, 0 ), |
335 | {cooked, combination, REV | OMIT, 0, 0 }, | 335 | MI_ENTRY(cooked, combination, REV | OMIT, 0, 0 ), |
336 | {raw, combination, REV | OMIT, 0, 0 }, | 336 | MI_ENTRY(raw, combination, REV | OMIT, 0, 0 ), |
337 | {stty_pass8, combination, REV | OMIT, 0, 0 }, | 337 | MI_ENTRY(stty_pass8, combination, REV | OMIT, 0, 0 ), |
338 | {litout, combination, REV | OMIT, 0, 0 }, | 338 | MI_ENTRY(litout, combination, REV | OMIT, 0, 0 ), |
339 | {cbreak, combination, REV | OMIT, 0, 0 }, | 339 | MI_ENTRY(cbreak, combination, REV | OMIT, 0, 0 ), |
340 | #ifdef IXANY | 340 | #ifdef IXANY |
341 | {decctlq, combination, REV | OMIT, 0, 0 }, | 341 | MI_ENTRY(decctlq, combination, REV | OMIT, 0, 0 ), |
342 | #endif | 342 | #endif |
343 | #if defined (TABDLY) || defined (OXTABS) | 343 | #if defined (TABDLY) || defined (OXTABS) |
344 | {stty_tabs, combination, REV | OMIT, 0, 0 }, | 344 | MI_ENTRY(stty_tabs, combination, REV | OMIT, 0, 0 ), |
345 | #endif | 345 | #endif |
346 | #if defined(XCASE) && defined(IUCLC) && defined(OLCUC) | 346 | #if defined(XCASE) && defined(IUCLC) && defined(OLCUC) |
347 | {stty_lcase, combination, REV | OMIT, 0, 0 }, | 347 | MI_ENTRY(stty_lcase, combination, REV | OMIT, 0, 0 ), |
348 | {stty_LCASE, combination, REV | OMIT, 0, 0 }, | 348 | MI_ENTRY(stty_LCASE, combination, REV | OMIT, 0, 0 ), |
349 | #endif | 349 | #endif |
350 | {stty_crt, combination, OMIT, 0, 0 }, | 350 | MI_ENTRY(stty_crt, combination, OMIT, 0, 0 ), |
351 | {stty_dec, combination, OMIT, 0, 0 }, | 351 | MI_ENTRY(stty_dec, combination, OMIT, 0, 0 ), |
352 | }; | 352 | }; |
353 | 353 | ||
354 | static const int NUM_mode_info = | 354 | static const int NUM_mode_info = |
@@ -359,7 +359,7 @@ static const int NUM_mode_info = | |||
359 | struct control_info { | 359 | struct control_info { |
360 | const char *name; /* Name given on command line. */ | 360 | const char *name; /* Name given on command line. */ |
361 | unsigned char saneval; /* Value to set for `stty sane'. */ | 361 | unsigned char saneval; /* Value to set for `stty sane'. */ |
362 | int offset; /* Offset in c_cc. */ | 362 | unsigned char offset; /* Offset in c_cc. */ |
363 | }; | 363 | }; |
364 | 364 | ||
365 | /* Control characters. */ | 365 | /* Control characters. */ |
@@ -408,7 +408,6 @@ static const int NUM_control_info = | |||
408 | 408 | ||
409 | 409 | ||
410 | static const char * visible(unsigned int ch); | 410 | static const char * visible(unsigned int ch); |
411 | static unsigned long baud_to_value(speed_t speed); | ||
412 | static int recover_mode(char *arg, struct termios *mode); | 411 | static int recover_mode(char *arg, struct termios *mode); |
413 | static int screen_columns(void); | 412 | static int screen_columns(void); |
414 | static int set_mode(const struct mode_info *info, | 413 | static int set_mode(const struct mode_info *info, |
@@ -416,12 +415,11 @@ static int set_mode(const struct mode_info *info, | |||
416 | static speed_t string_to_baud(const char *arg); | 415 | static speed_t string_to_baud(const char *arg); |
417 | static tcflag_t* mode_type_flag(enum mode_type type, struct termios *mode); | 416 | static tcflag_t* mode_type_flag(enum mode_type type, struct termios *mode); |
418 | static void display_all(struct termios *mode, int fd, | 417 | static void display_all(struct termios *mode, int fd, |
419 | const char *device_name); | 418 | const char *device_name); |
420 | static void display_changed(struct termios *mode); | 419 | static void display_changed(struct termios *mode, int fd, |
421 | static void display_recoverable(struct termios *mode); | 420 | const char *device_name); |
422 | static void display_settings(enum output_type output_type, | 421 | static void display_recoverable(struct termios *mode, int fd, |
423 | struct termios *mode, int fd, | 422 | const char *device_name); |
424 | const char *device_name); | ||
425 | static void display_speed(struct termios *mode, int fancy); | 423 | static void display_speed(struct termios *mode, int fancy); |
426 | static void display_window_size(int fancy, int fd, | 424 | static void display_window_size(int fancy, int fd, |
427 | const char *device_name); | 425 | const char *device_name); |
@@ -479,7 +477,7 @@ extern int main(int argc, char **argv) | |||
479 | #endif | 477 | #endif |
480 | { | 478 | { |
481 | struct termios mode; | 479 | struct termios mode; |
482 | enum output_type output_type; | 480 | void (*output_func)(struct termios *, int, const char *); |
483 | int optc; | 481 | int optc; |
484 | int require_set_attr; | 482 | int require_set_attr; |
485 | int speed_was_set; | 483 | int speed_was_set; |
@@ -491,7 +489,7 @@ extern int main(int argc, char **argv) | |||
491 | int fd; | 489 | int fd; |
492 | const char *device_name; | 490 | const char *device_name; |
493 | 491 | ||
494 | output_type = changed; | 492 | output_func = display_changed; |
495 | verbose_output = 0; | 493 | verbose_output = 0; |
496 | recoverable_output = 0; | 494 | recoverable_output = 0; |
497 | 495 | ||
@@ -502,17 +500,17 @@ extern int main(int argc, char **argv) | |||
502 | switch (optc) { | 500 | switch (optc) { |
503 | case 'a': | 501 | case 'a': |
504 | verbose_output = 1; | 502 | verbose_output = 1; |
505 | output_type = all; | 503 | output_func = display_all; |
506 | break; | 504 | break; |
507 | 505 | ||
508 | case 'g': | 506 | case 'g': |
509 | recoverable_output = 1; | 507 | recoverable_output = 1; |
510 | output_type = recoverable; | 508 | output_func = display_recoverable; |
511 | break; | 509 | break; |
512 | 510 | ||
513 | case 'F': | 511 | case 'F': |
514 | if (file_name) | 512 | if (file_name) |
515 | error_msg_and_die("only one device may be specified"); | 513 | bb_error_msg_and_die("only one device may be specified"); |
516 | file_name = optarg; | 514 | file_name = optarg; |
517 | break; | 515 | break; |
518 | 516 | ||
@@ -529,12 +527,12 @@ extern int main(int argc, char **argv) | |||
529 | noargs = 0; | 527 | noargs = 0; |
530 | 528 | ||
531 | /* Specifying both -a and -g gets an error. */ | 529 | /* Specifying both -a and -g gets an error. */ |
532 | if (verbose_output && recoverable_output) | 530 | if (verbose_output & recoverable_output) |
533 | error_msg_and_die ("verbose and stty-readable output styles are mutually exclusive"); | 531 | bb_error_msg_and_die ("verbose and stty-readable output styles are mutually exclusive"); |
534 | 532 | ||
535 | /* Specifying any other arguments with -a or -g gets an error. */ | 533 | /* Specifying any other arguments with -a or -g gets an error. */ |
536 | if (!noargs && (verbose_output || recoverable_output)) | 534 | if (~noargs & (verbose_output | recoverable_output)) |
537 | error_msg_and_die ("modes may not be set when specifying an output style"); | 535 | bb_error_msg_and_die ("modes may not be set when specifying an output style"); |
538 | 536 | ||
539 | /* FIXME: it'd be better not to open the file until we've verified | 537 | /* FIXME: it'd be better not to open the file until we've verified |
540 | that all arguments are valid. Otherwise, we could end up doing | 538 | that all arguments are valid. Otherwise, we could end up doing |
@@ -547,26 +545,26 @@ extern int main(int argc, char **argv) | |||
547 | device_name = file_name; | 545 | device_name = file_name; |
548 | fd = open(device_name, O_RDONLY | O_NONBLOCK); | 546 | fd = open(device_name, O_RDONLY | O_NONBLOCK); |
549 | if (fd < 0) | 547 | if (fd < 0) |
550 | perror_msg_and_die("%s", device_name); | 548 | bb_perror_msg_and_die("%s", device_name); |
551 | if ((fdflags = fcntl(fd, F_GETFL)) == -1 | 549 | if ((fdflags = fcntl(fd, F_GETFL)) == -1 |
552 | || fcntl(fd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) | 550 | || fcntl(fd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) |
553 | perror_msg_and_die("%s: couldn't reset non-blocking mode", | 551 | bb_perror_msg_and_die("%s: couldn't reset non-blocking mode", |
554 | device_name); | 552 | device_name); |
555 | } else { | 553 | } else { |
556 | fd = 0; | 554 | fd = 0; |
557 | device_name = "standard input"; | 555 | device_name = bb_msg_standard_input; |
558 | } | 556 | } |
559 | 557 | ||
560 | /* Initialize to all zeroes so there is no risk memcmp will report a | 558 | /* Initialize to all zeroes so there is no risk memcmp will report a |
561 | spurious difference in an uninitialized portion of the structure. */ | 559 | spurious difference in an uninitialized portion of the structure. */ |
562 | memset(&mode, 0, sizeof(mode)); | 560 | memset(&mode, 0, sizeof(mode)); |
563 | if (tcgetattr(fd, &mode)) | 561 | if (tcgetattr(fd, &mode)) |
564 | perror_msg_and_die("%s", device_name); | 562 | bb_perror_msg_and_die("%s", device_name); |
565 | 563 | ||
566 | if (verbose_output || recoverable_output || noargs) { | 564 | if (verbose_output | recoverable_output | noargs) { |
567 | max_col = screen_columns(); | 565 | max_col = screen_columns(); |
568 | current_col = 0; | 566 | current_col = 0; |
569 | display_settings(output_type, &mode, fd, device_name); | 567 | output_func(&mode, fd, device_name); |
570 | return EXIT_SUCCESS; | 568 | return EXIT_SUCCESS; |
571 | } | 569 | } |
572 | 570 | ||
@@ -610,13 +608,13 @@ extern int main(int argc, char **argv) | |||
610 | } | 608 | } |
611 | 609 | ||
612 | if (match_found == 0 && reversed) | 610 | if (match_found == 0 && reversed) |
613 | error_msg_and_die("invalid argument `%s'", --argv[k]); | 611 | bb_error_msg_and_die("invalid argument `%s'", --argv[k]); |
614 | 612 | ||
615 | if (match_found == 0) | 613 | if (match_found == 0) |
616 | for (i = 0; i < NUM_control_info; ++i) | 614 | for (i = 0; i < NUM_control_info; ++i) |
617 | if (STREQ(argv[k], control_info[i].name)) { | 615 | if (STREQ(argv[k], control_info[i].name)) { |
618 | if (k == argc - 1) | 616 | if (k == argc - 1) |
619 | error_msg_and_die("missing argument to `%s'", argv[k]); | 617 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
620 | match_found = 1; | 618 | match_found = 1; |
621 | ++k; | 619 | ++k; |
622 | set_control_char(&control_info[i], argv[k], &mode); | 620 | set_control_char(&control_info[i], argv[k], &mode); |
@@ -627,14 +625,14 @@ extern int main(int argc, char **argv) | |||
627 | if (match_found == 0) { | 625 | if (match_found == 0) { |
628 | if (STREQ(argv[k], "ispeed")) { | 626 | if (STREQ(argv[k], "ispeed")) { |
629 | if (k == argc - 1) | 627 | if (k == argc - 1) |
630 | error_msg_and_die("missing argument to `%s'", argv[k]); | 628 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
631 | ++k; | 629 | ++k; |
632 | set_speed(input_speed, argv[k], &mode); | 630 | set_speed(input_speed, argv[k], &mode); |
633 | speed_was_set = 1; | 631 | speed_was_set = 1; |
634 | require_set_attr = 1; | 632 | require_set_attr = 1; |
635 | } else if (STREQ(argv[k], "ospeed")) { | 633 | } else if (STREQ(argv[k], "ospeed")) { |
636 | if (k == argc - 1) | 634 | if (k == argc - 1) |
637 | error_msg_and_die("missing argument to `%s'", argv[k]); | 635 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
638 | ++k; | 636 | ++k; |
639 | set_speed(output_speed, argv[k], &mode); | 637 | set_speed(output_speed, argv[k], &mode); |
640 | speed_was_set = 1; | 638 | speed_was_set = 1; |
@@ -643,16 +641,16 @@ extern int main(int argc, char **argv) | |||
643 | #ifdef TIOCGWINSZ | 641 | #ifdef TIOCGWINSZ |
644 | else if (STREQ(argv[k], "rows")) { | 642 | else if (STREQ(argv[k], "rows")) { |
645 | if (k == argc - 1) | 643 | if (k == argc - 1) |
646 | error_msg_and_die("missing argument to `%s'", argv[k]); | 644 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
647 | ++k; | 645 | ++k; |
648 | set_window_size((int) parse_number(argv[k], stty_suffixes), | 646 | set_window_size((int) bb_xparse_number(argv[k], stty_suffixes), |
649 | -1, fd, device_name); | 647 | -1, fd, device_name); |
650 | } else if (STREQ(argv[k], "cols") || STREQ(argv[k], "columns")) { | 648 | } else if (STREQ(argv[k], "cols") || STREQ(argv[k], "columns")) { |
651 | if (k == argc - 1) | 649 | if (k == argc - 1) |
652 | error_msg_and_die("missing argument to `%s'", argv[k]); | 650 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
653 | ++k; | 651 | ++k; |
654 | set_window_size(-1, | 652 | set_window_size(-1, |
655 | (int) parse_number(argv[k], stty_suffixes), | 653 | (int) bb_xparse_number(argv[k], stty_suffixes), |
656 | fd, device_name); | 654 | fd, device_name); |
657 | } else if (STREQ(argv[k], "size")) { | 655 | } else if (STREQ(argv[k], "size")) { |
658 | max_col = screen_columns(); | 656 | max_col = screen_columns(); |
@@ -663,9 +661,9 @@ extern int main(int argc, char **argv) | |||
663 | #ifdef HAVE_C_LINE | 661 | #ifdef HAVE_C_LINE |
664 | else if (STREQ(argv[k], "line")) { | 662 | else if (STREQ(argv[k], "line")) { |
665 | if (k == argc - 1) | 663 | if (k == argc - 1) |
666 | error_msg_and_die("missing argument to `%s'", argv[k]); | 664 | bb_error_msg_and_die("missing argument to `%s'", argv[k]); |
667 | ++k; | 665 | ++k; |
668 | mode.c_line = parse_number(argv[k], stty_suffixes); | 666 | mode.c_line = bb_xparse_number(argv[k], stty_suffixes); |
669 | require_set_attr = 1; | 667 | require_set_attr = 1; |
670 | } | 668 | } |
671 | #endif | 669 | #endif |
@@ -679,7 +677,7 @@ extern int main(int argc, char **argv) | |||
679 | speed_was_set = 1; | 677 | speed_was_set = 1; |
680 | require_set_attr = 1; | 678 | require_set_attr = 1; |
681 | } else | 679 | } else |
682 | error_msg_and_die("invalid argument `%s'", argv[k]); | 680 | bb_error_msg_and_die("invalid argument `%s'", argv[k]); |
683 | } | 681 | } |
684 | } | 682 | } |
685 | 683 | ||
@@ -687,7 +685,7 @@ extern int main(int argc, char **argv) | |||
687 | struct termios new_mode; | 685 | struct termios new_mode; |
688 | 686 | ||
689 | if (tcsetattr(fd, TCSADRAIN, &mode)) | 687 | if (tcsetattr(fd, TCSADRAIN, &mode)) |
690 | perror_msg_and_die("%s", device_name); | 688 | bb_perror_msg_and_die("%s", device_name); |
691 | 689 | ||
692 | /* POSIX (according to Zlotnick's book) tcsetattr returns zero if | 690 | /* POSIX (according to Zlotnick's book) tcsetattr returns zero if |
693 | it performs *any* of the requested operations. This means it | 691 | it performs *any* of the requested operations. This means it |
@@ -700,7 +698,7 @@ extern int main(int argc, char **argv) | |||
700 | spurious difference in an uninitialized portion of the structure. */ | 698 | spurious difference in an uninitialized portion of the structure. */ |
701 | memset(&new_mode, 0, sizeof(new_mode)); | 699 | memset(&new_mode, 0, sizeof(new_mode)); |
702 | if (tcgetattr(fd, &new_mode)) | 700 | if (tcgetattr(fd, &new_mode)) |
703 | perror_msg_and_die("%s", device_name); | 701 | bb_perror_msg_and_die("%s", device_name); |
704 | 702 | ||
705 | /* Normally, one shouldn't use memcmp to compare structures that | 703 | /* Normally, one shouldn't use memcmp to compare structures that |
706 | may have `holes' containing uninitialized data, but we have been | 704 | may have `holes' containing uninitialized data, but we have been |
@@ -723,7 +721,7 @@ extern int main(int argc, char **argv) | |||
723 | new_mode.c_cflag &= (~CIBAUD); | 721 | new_mode.c_cflag &= (~CIBAUD); |
724 | if (speed_was_set || memcmp(&mode, &new_mode, sizeof(mode)) != 0) | 722 | if (speed_was_set || memcmp(&mode, &new_mode, sizeof(mode)) != 0) |
725 | #endif | 723 | #endif |
726 | error_msg_and_die ("%s: unable to perform all requested operations", | 724 | bb_error_msg_and_die ("%s: unable to perform all requested operations", |
727 | device_name); | 725 | device_name); |
728 | } | 726 | } |
729 | } | 727 | } |
@@ -896,9 +894,9 @@ set_mode(const struct mode_info *info, int reversed, struct termios *mode) | |||
896 | #endif | 894 | #endif |
897 | } | 895 | } |
898 | } else if (reversed) | 896 | } else if (reversed) |
899 | *bitsp = *bitsp & ~info->mask & ~info->bits; | 897 | *bitsp = *bitsp & ~((unsigned long)info->mask) & ~info->bits; |
900 | else | 898 | else |
901 | *bitsp = (*bitsp & ~info->mask) | info->bits; | 899 | *bitsp = (*bitsp & ~((unsigned long)info->mask)) | info->bits; |
902 | 900 | ||
903 | return 1; | 901 | return 1; |
904 | } | 902 | } |
@@ -910,7 +908,7 @@ set_control_char(const struct control_info *info, const char *arg, | |||
910 | unsigned char value; | 908 | unsigned char value; |
911 | 909 | ||
912 | if (info->name == stty_min || info->name == stty_time) | 910 | if (info->name == stty_min || info->name == stty_time) |
913 | value = parse_number(arg, stty_suffixes); | 911 | value = bb_xparse_number(arg, stty_suffixes); |
914 | else if (arg[0] == '\0' || arg[1] == '\0') | 912 | else if (arg[0] == '\0' || arg[1] == '\0') |
915 | value = arg[0]; | 913 | value = arg[0]; |
916 | else if (STREQ(arg, "^-") || STREQ(arg, "undef")) | 914 | else if (STREQ(arg, "^-") || STREQ(arg, "undef")) |
@@ -921,7 +919,7 @@ set_control_char(const struct control_info *info, const char *arg, | |||
921 | else | 919 | else |
922 | value = arg[1] & ~0140; /* Non-letters get weird results. */ | 920 | value = arg[1] & ~0140; /* Non-letters get weird results. */ |
923 | } else | 921 | } else |
924 | value = parse_number(arg, stty_suffixes); | 922 | value = bb_xparse_number(arg, stty_suffixes); |
925 | mode->c_cc[info->offset] = value; | 923 | mode->c_cc[info->offset] = value; |
926 | } | 924 | } |
927 | 925 | ||
@@ -931,10 +929,13 @@ set_speed(enum speed_setting type, const char *arg, struct termios *mode) | |||
931 | speed_t baud; | 929 | speed_t baud; |
932 | 930 | ||
933 | baud = string_to_baud(arg); | 931 | baud = string_to_baud(arg); |
934 | if (type == input_speed || type == both_speeds) | 932 | |
933 | if (type != output_speed) { /* either input or both */ | ||
935 | cfsetispeed(mode, baud); | 934 | cfsetispeed(mode, baud); |
936 | if (type == output_speed || type == both_speeds) | 935 | } |
936 | if (type != input_speed) { /* either output or both */ | ||
937 | cfsetospeed(mode, baud); | 937 | cfsetospeed(mode, baud); |
938 | } | ||
938 | } | 939 | } |
939 | 940 | ||
940 | #ifdef TIOCGWINSZ | 941 | #ifdef TIOCGWINSZ |
@@ -953,7 +954,7 @@ set_window_size(int rows, int cols, int fd, const char *device_name) | |||
953 | 954 | ||
954 | if (get_win_size(fd, &win)) { | 955 | if (get_win_size(fd, &win)) { |
955 | if (errno != EINVAL) | 956 | if (errno != EINVAL) |
956 | perror_msg_and_die("%s", device_name); | 957 | bb_perror_msg_and_die("%s", device_name); |
957 | memset(&win, 0, sizeof(win)); | 958 | memset(&win, 0, sizeof(win)); |
958 | } | 959 | } |
959 | 960 | ||
@@ -975,32 +976,28 @@ set_window_size(int rows, int cols, int fd, const char *device_name) | |||
975 | ttysz.ts_lines = win.ws_row; | 976 | ttysz.ts_lines = win.ws_row; |
976 | ttysz.ts_cols = win.ws_col; | 977 | ttysz.ts_cols = win.ws_col; |
977 | 978 | ||
978 | win.ws_row = 1; | 979 | win.ws_row = win.ws_col = 1; |
979 | win.ws_col = 1; | ||
980 | |||
981 | if (ioctl(fd, TIOCSWINSZ, (char *) &win)) | ||
982 | perror_msg_and_die("%s", device_name); | ||
983 | 980 | ||
984 | if (ioctl(fd, TIOCSSIZE, (char *) &ttysz)) | 981 | if ((ioctl(fd, TIOCSWINSZ, (char *) &win) != 0) |
985 | perror_msg_and_die("%s", device_name); | 982 | || (ioctl(fd, TIOCSSIZE, (char *) &ttysz) != 0)) { |
983 | bb_perror_msg_and_die("%s", device_name); | ||
986 | return; | 984 | return; |
987 | } | 985 | } |
988 | # endif | 986 | # endif |
989 | 987 | ||
990 | if (ioctl(fd, TIOCSWINSZ, (char *) &win)) | 988 | if (ioctl(fd, TIOCSWINSZ, (char *) &win)) |
991 | perror_msg_and_die("%s", device_name); | 989 | bb_perror_msg_and_die("%s", device_name); |
992 | } | 990 | } |
993 | 991 | ||
994 | static void display_window_size(int fancy, int fd, const char *device_name) | 992 | static void display_window_size(int fancy, int fd, const char *device_name) |
995 | { | 993 | { |
994 | const char *fmt_str = "%s" "\0" "%s: no size information for this device"; | ||
996 | struct winsize win; | 995 | struct winsize win; |
997 | 996 | ||
998 | if (get_win_size(fd, &win)) { | 997 | if (get_win_size(fd, &win)) { |
999 | if (errno != EINVAL) | 998 | if ((errno != EINVAL) || ((fmt_str += 2), !fancy)) { |
1000 | perror_msg_and_die("%s", device_name); | 999 | bb_perror_msg_and_die(fmt_str, device_name); |
1001 | if (!fancy) | 1000 | } |
1002 | perror_msg_and_die("%s: no size information for this device", | ||
1003 | device_name); | ||
1004 | } else { | 1001 | } else { |
1005 | wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n", | 1002 | wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n", |
1006 | win.ws_row, win.ws_col); | 1003 | win.ws_row, win.ws_col); |
@@ -1012,6 +1009,9 @@ static void display_window_size(int fancy, int fd, const char *device_name) | |||
1012 | 1009 | ||
1013 | static int screen_columns(void) | 1010 | static int screen_columns(void) |
1014 | { | 1011 | { |
1012 | int columns; | ||
1013 | const char *s; | ||
1014 | |||
1015 | #ifdef TIOCGWINSZ | 1015 | #ifdef TIOCGWINSZ |
1016 | struct winsize win; | 1016 | struct winsize win; |
1017 | 1017 | ||
@@ -1025,51 +1025,29 @@ static int screen_columns(void) | |||
1025 | return win.ws_col; | 1025 | return win.ws_col; |
1026 | #endif | 1026 | #endif |
1027 | 1027 | ||
1028 | if (getenv("COLUMNS")) | 1028 | columns = 80; |
1029 | return atoi(getenv("COLUMNS")); | 1029 | if ((s = getenv("COLUMNS"))) { |
1030 | return 80; | 1030 | columns = atoi(s); |
1031 | } | ||
1032 | |||
1033 | static tcflag_t *mode_type_flag(enum mode_type type, struct termios *mode) | ||
1034 | { | ||
1035 | switch (type) { | ||
1036 | case control: | ||
1037 | return &mode->c_cflag; | ||
1038 | |||
1039 | case input: | ||
1040 | return &mode->c_iflag; | ||
1041 | |||
1042 | case output: | ||
1043 | return &mode->c_oflag; | ||
1044 | |||
1045 | case local: | ||
1046 | return &mode->c_lflag; | ||
1047 | |||
1048 | default: /* combination: */ | ||
1049 | return NULL; | ||
1050 | } | 1031 | } |
1032 | return columns; | ||
1051 | } | 1033 | } |
1052 | 1034 | ||
1053 | static void | 1035 | static tcflag_t *mode_type_flag(enum mode_type type, struct termios *mode) |
1054 | display_settings(enum output_type output_type, struct termios *mode, | ||
1055 | int fd, const char *device_name) | ||
1056 | { | 1036 | { |
1057 | switch (output_type) { | 1037 | static const unsigned char tcflag_offsets[] = { |
1058 | case changed: | 1038 | offsetof(struct termios, c_cflag), /* control */ |
1059 | display_changed(mode); | 1039 | offsetof(struct termios, c_iflag), /* input */ |
1060 | break; | 1040 | offsetof(struct termios, c_oflag), /* output */ |
1061 | 1041 | offsetof(struct termios, c_lflag) /* local */ | |
1062 | case all: | 1042 | }; |
1063 | display_all(mode, fd, device_name); | 1043 | |
1064 | break; | 1044 | if (((unsigned int) type) <= local) { |
1065 | 1045 | return (tcflag_t *)(((char *) mode) + tcflag_offsets[(int)type]); | |
1066 | case recoverable: | ||
1067 | display_recoverable(mode); | ||
1068 | break; | ||
1069 | } | 1046 | } |
1047 | return NULL; | ||
1070 | } | 1048 | } |
1071 | 1049 | ||
1072 | static void display_changed(struct termios *mode) | 1050 | static void display_changed(struct termios *mode, int fd, const char *device_name) |
1073 | { | 1051 | { |
1074 | int i; | 1052 | int i; |
1075 | int empty_line; | 1053 | int empty_line; |
@@ -1206,18 +1184,25 @@ display_all(struct termios *mode, int fd, const char *device_name) | |||
1206 | 1184 | ||
1207 | static void display_speed(struct termios *mode, int fancy) | 1185 | static void display_speed(struct termios *mode, int fancy) |
1208 | { | 1186 | { |
1209 | if (cfgetispeed(mode) == 0 || cfgetispeed(mode) == cfgetospeed(mode)) | 1187 | unsigned long ispeed, ospeed; |
1210 | wrapf(fancy ? "speed %lu baud;" : "%lu\n", | 1188 | const char *fmt_str = |
1211 | baud_to_value(cfgetospeed(mode))); | 1189 | "%lu %lu\n\0" "ispeed %lu baud; ospeed %lu baud;\0" |
1212 | else | 1190 | "%lu\n\0" "\0\0\0\0" "speed %lu baud;"; |
1213 | wrapf(fancy ? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n", | 1191 | |
1214 | baud_to_value(cfgetispeed(mode)), | 1192 | ospeed = ispeed = cfgetispeed(mode); |
1215 | baud_to_value(cfgetospeed(mode))); | 1193 | if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) { |
1194 | ispeed = ospeed; /* in case ispeed was 0 */ | ||
1195 | fmt_str += 43; | ||
1196 | } | ||
1197 | if (fancy) { | ||
1198 | fmt_str += 9; | ||
1199 | } | ||
1200 | wrapf(fmt_str, bb_baud_to_value(ispeed), bb_baud_to_value(ospeed)); | ||
1216 | if (!fancy) | 1201 | if (!fancy) |
1217 | current_col = 0; | 1202 | current_col = 0; |
1218 | } | 1203 | } |
1219 | 1204 | ||
1220 | static void display_recoverable(struct termios *mode) | 1205 | static void display_recoverable(struct termios *mode, int fd, const char *device_name) |
1221 | { | 1206 | { |
1222 | int i; | 1207 | int i; |
1223 | 1208 | ||
@@ -1259,62 +1244,9 @@ static int recover_mode(char *arg, struct termios *mode) | |||
1259 | return 1; | 1244 | return 1; |
1260 | } | 1245 | } |
1261 | 1246 | ||
1262 | struct speed_map { | ||
1263 | speed_t speed; /* Internal form. */ | ||
1264 | unsigned long value; /* Numeric value. */ | ||
1265 | }; | ||
1266 | |||
1267 | static const struct speed_map speeds[] = { | ||
1268 | {B0, 0}, | ||
1269 | {B50, 50}, | ||
1270 | {B75, 75}, | ||
1271 | {B110, 110}, | ||
1272 | {B134, 134}, | ||
1273 | {B150, 150}, | ||
1274 | {B200, 200}, | ||
1275 | {B300, 300}, | ||
1276 | {B600, 600}, | ||
1277 | {B1200, 1200}, | ||
1278 | {B1800, 1800}, | ||
1279 | {B2400, 2400}, | ||
1280 | {B4800, 4800}, | ||
1281 | {B9600, 9600}, | ||
1282 | {B19200, 19200}, | ||
1283 | {B38400, 38400}, | ||
1284 | #ifdef B57600 | ||
1285 | {B57600, 57600}, | ||
1286 | #endif | ||
1287 | #ifdef B115200 | ||
1288 | {B115200, 115200}, | ||
1289 | #endif | ||
1290 | #ifdef B230400 | ||
1291 | {B230400, 230400}, | ||
1292 | #endif | ||
1293 | #ifdef B460800 | ||
1294 | {B460800, 460800}, | ||
1295 | #endif | ||
1296 | }; | ||
1297 | |||
1298 | static const int NUM_SPEEDS = (sizeof(speeds) / sizeof(struct speed_map)); | ||
1299 | |||
1300 | static speed_t string_to_baud(const char *arg) | 1247 | static speed_t string_to_baud(const char *arg) |
1301 | { | 1248 | { |
1302 | int i; | 1249 | return bb_value_to_baud(bb_xparse_number(arg, 0)); |
1303 | |||
1304 | for (i = 0; i < NUM_SPEEDS; ++i) | ||
1305 | if (parse_number(arg, 0) == speeds[i].value) | ||
1306 | return speeds[i].speed; | ||
1307 | return (speed_t) - 1; | ||
1308 | } | ||
1309 | |||
1310 | static unsigned long baud_to_value(speed_t speed) | ||
1311 | { | ||
1312 | int i; | ||
1313 | |||
1314 | for (i = 0; i < NUM_SPEEDS; ++i) | ||
1315 | if (speed == speeds[i].speed) | ||
1316 | return speeds[i].value; | ||
1317 | return 0; | ||
1318 | } | 1250 | } |
1319 | 1251 | ||
1320 | static void sane_mode(struct termios *mode) | 1252 | static void sane_mode(struct termios *mode) |
@@ -1333,10 +1265,12 @@ static void sane_mode(struct termios *mode) | |||
1333 | for (i = 0; i < NUM_mode_info; ++i) { | 1265 | for (i = 0; i < NUM_mode_info; ++i) { |
1334 | if (mode_info[i].flags & SANE_SET) { | 1266 | if (mode_info[i].flags & SANE_SET) { |
1335 | bitsp = mode_type_flag(mode_info[i].type, mode); | 1267 | bitsp = mode_type_flag(mode_info[i].type, mode); |
1336 | *bitsp = (*bitsp & ~mode_info[i].mask) | mode_info[i].bits; | 1268 | *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask)) |
1269 | | mode_info[i].bits; | ||
1337 | } else if (mode_info[i].flags & SANE_UNSET) { | 1270 | } else if (mode_info[i].flags & SANE_UNSET) { |
1338 | bitsp = mode_type_flag(mode_info[i].type, mode); | 1271 | bitsp = mode_type_flag(mode_info[i].type, mode); |
1339 | *bitsp = *bitsp & ~mode_info[i].mask & ~mode_info[i].bits; | 1272 | *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask) |
1273 | & ~mode_info[i].bits; | ||
1340 | } | 1274 | } |
1341 | } | 1275 | } |
1342 | } | 1276 | } |
@@ -1349,47 +1283,32 @@ static const char *visible(unsigned int ch) | |||
1349 | static char buf[10]; | 1283 | static char buf[10]; |
1350 | char *bpout = buf; | 1284 | char *bpout = buf; |
1351 | 1285 | ||
1352 | if (ch == _POSIX_VDISABLE) | 1286 | if (ch == _POSIX_VDISABLE) { |
1353 | return "<undef>"; | 1287 | return "<undef>"; |
1288 | } | ||
1354 | 1289 | ||
1355 | if (ch >= 32) { | 1290 | if (ch >= 128) { |
1356 | if (ch < 127) | 1291 | ch -= 128; |
1357 | *bpout++ = ch; | 1292 | *bpout++ = 'M'; |
1358 | else if (ch == 127) { | 1293 | *bpout++ = '-'; |
1359 | *bpout++ = '^'; | 1294 | } |
1360 | *bpout++ = '?'; | 1295 | |
1361 | } else { | 1296 | if (ch < 32) { |
1362 | *bpout++ = 'M', *bpout++ = '-'; | ||
1363 | if (ch >= 128 + 32) { | ||
1364 | if (ch < 128 + 127) | ||
1365 | *bpout++ = ch - 128; | ||
1366 | else { | ||
1367 | *bpout++ = '^'; | ||
1368 | *bpout++ = '?'; | ||
1369 | } | ||
1370 | } else { | ||
1371 | *bpout++ = '^'; | ||
1372 | *bpout++ = ch - 128 + 64; | ||
1373 | } | ||
1374 | } | ||
1375 | } else { | ||
1376 | *bpout++ = '^'; | 1297 | *bpout++ = '^'; |
1377 | *bpout++ = ch + 64; | 1298 | *bpout++ = ch + 64; |
1299 | } else if (ch < 127) { | ||
1300 | *bpout++ = ch; | ||
1301 | } else { | ||
1302 | *bpout++ = '^'; | ||
1303 | *bpout++ = '?'; | ||
1378 | } | 1304 | } |
1305 | |||
1379 | *bpout = '\0'; | 1306 | *bpout = '\0'; |
1380 | return (const char *) buf; | 1307 | return (const char *) buf; |
1381 | } | 1308 | } |
1382 | 1309 | ||
1383 | #ifdef TEST | 1310 | #ifdef TEST |
1384 | 1311 | ||
1385 | const char *applet_name = "stty"; | 1312 | const char *bb_applet_name = "stty"; |
1386 | 1313 | ||
1387 | #endif | 1314 | #endif |
1388 | |||
1389 | /* | ||
1390 | Local Variables: | ||
1391 | c-file-style: "linux" | ||
1392 | c-basic-offset: 4 | ||
1393 | tab-width: 4 | ||
1394 | End: | ||
1395 | */ | ||