source: trunk/minix/commands/simple/stty.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 24.1 KB
Line 
1/* stty - set terminal mode Author: Andy Tanenbaum */
2
3/*
4 Adapted to POSIX 1003.2 by Philip Homburg.
5 */
6
7#ifdef __minix_vmd
8#define _MINIX_SOURCE
9#endif
10
11#include <assert.h>
12#include <ctype.h>
13#include <errno.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <termios.h>
18#ifdef __minix
19#include <sys/types.h>
20#include <sys/ioctl.h>
21#endif
22
23/* Default settings, the Minix ones are defined in <termios.h> */
24
25#ifndef TCTRL_DEF
26#define TCTRL_DEF (PARENB | CREAD | CS7)
27#endif
28
29#ifndef TSPEED_DEF
30#define TSPEED_DEF B1200
31#endif
32
33#ifndef TINPUT_DEF
34#define TINPUT_DEF (BRKINT | IGNPAR | ISTRIP | ICRNL)
35#endif
36
37#ifndef TOUTPUT_DEF
38#define TOUTPUT_DEF OPOST
39#endif
40
41#ifndef TLOCAL_DEF
42#define TLOCAL_DEF (ISIG | IEXTEN | ICANON | ECHO | ECHOE)
43#endif
44
45#ifndef TEOF_DEF
46#define TEOF_DEF '\4' /* ^D */
47#endif
48#ifndef TEOL_DEF
49#ifdef _POSIX_VDISABLE
50#define TEOL_DEF _POSIX_VDISABLE
51#else
52#define TEOL_DEF '\n'
53#endif
54#endif
55#ifndef TERASE_DEF
56#define TERASE_DEF '\10' /* ^H */
57#endif
58#ifndef TINTR_DEF
59#define TINTR_DEF '\177' /* ^? */
60#endif
61#ifndef TKILL_DEF
62#define TKILL_DEF '\25' /* ^U */
63#endif
64#ifndef TQUIT_DEF
65#define TQUIT_DEF '\34' /* ^\ */
66#endif
67#ifndef TSUSP_DEF
68#define TSUSP_DEF '\32' /* ^Z */
69#endif
70#ifndef TSTART_DEF
71#define TSTART_DEF '\21' /* ^Q */
72#endif
73#ifndef TSTOP_DEF
74#define TSTOP_DEF '\23' /* ^S */
75#endif
76#ifndef TMIN_DEF
77#define TMIN_DEF 1
78#endif
79#ifndef TTIME_DEF
80#define TTIME_DEF 0
81#endif
82
83
84
85char *prog_name;
86struct termios termios;
87int column= 0, max_column=80; /* Assume 80 character terminals. */
88#ifdef __minix
89struct winsize winsize;
90#endif
91
92#if __minix
93#define PROTO(a) _ARGS(a)
94#else
95#define PROTO(a) ()
96#endif
97
98void main PROTO(( int argc, char **argv ));
99void report PROTO(( int flags ));
100int option PROTO(( char *opt, char *next ));
101int match PROTO(( char *s1, char *s2 ));
102void prctl PROTO(( int c ));
103speed_t long2speed PROTO(( long num ));
104long speed2long PROTO(( unsigned long speed ));
105void print_flags PROTO(( unsigned long flags, unsigned long flag,
106 unsigned long def, char *string, int all ));
107void output PROTO(( char *s ));
108void do_print_char PROTO(( unsigned chr, unsigned def, char *name, int all ));
109void do_print_num PROTO(( unsigned num, unsigned def, char *name, int all ));
110void set_saved_settings PROTO(( char *opt ));
111void set_control PROTO(( int option, char *value ));
112void set_min_tim PROTO(( int option, char *value ));
113
114#define print_char(c,d,n,a) (do_print_char((unsigned)(c),(unsigned)(d),(n),(a)))
115#define print_num(m,d,n,a) (do_print_num((unsigned)(m),(unsigned)(d),(n),(a)))
116
117void main(argc, argv)
118int argc;
119char *argv[];
120{
121 int flags, k;
122
123 prog_name= argv[0];
124 flags= 0;
125
126 /* Stty with no arguments just reports on current status. */
127 if (tcgetattr(0, &termios) == -1)
128 {
129 fprintf(stderr, "%s: can't read ioctl parameters from stdin: %s\n",
130 prog_name, strerror(errno));
131 exit(1);
132 }
133#ifdef __minix
134 if (ioctl(0, TIOCGWINSZ, &winsize) == -1)
135 {
136 fprintf(stderr, "%s: can't get screen size from stdin: %s\n",
137 prog_name, strerror(errno));
138 exit(1);
139 }
140 if (winsize.ws_col != 0)
141 max_column= winsize.ws_col;
142#endif
143
144 if (argc == 2)
145 {
146 if (!strcmp(argv[1], "-a"))
147 flags |= 1;
148 else if (!strcmp(argv[1], "-g"))
149 flags |= 2;
150 }
151 if (argc == 1 || flags) {
152 report(flags);
153 exit(0);
154 }
155
156 /* Process the options specified. */
157 for (k= 1; k < argc; k++)
158 k += option(argv[k], k+1 < argc ? argv[k+1] : "");
159
160#ifdef __minix
161 if (ioctl(0, TIOCSWINSZ, &winsize) == -1)
162 {
163 fprintf(stderr, "%s: can't set screen size to stdin: %s\n",
164 prog_name, strerror(errno));
165 exit(1);
166 }
167#endif
168 if (tcsetattr(0, TCSANOW, &termios) == -1)
169 {
170 fprintf(stderr, "%s: can't set terminal parameters to stdin: %s\n",
171 prog_name, strerror(errno));
172 exit(1);
173 }
174 exit(0);
175}
176
177
178
179void report(flags)
180int flags;
181{
182 int i, all;
183 tcflag_t c_cflag, c_iflag, c_oflag, c_lflag;
184 char line[80];
185 speed_t ispeed, ospeed;
186
187 if (flags & 2)
188 { /* We have to write the termios structure in a encoded form
189 * to stdout.
190 */
191 printf(":%x:%x:%x:%x:%x:%x", termios.c_iflag, termios.c_oflag,
192 termios.c_cflag, termios.c_lflag, cfgetispeed(&termios),
193 cfgetospeed(&termios));
194 for (i= 0; i<NCCS; i++)
195 printf(":%x", termios.c_cc[i]);
196 printf(":\n");
197 return;
198 }
199
200 all= !!flags;
201
202 /* Start with the baud rate. */
203 ispeed= cfgetispeed(&termios);
204 ospeed= cfgetospeed(&termios);
205 if (ispeed != ospeed)
206 {
207 sprintf(line, "ispeed %lu baud; ospeed %lu baud;",
208 speed2long(ispeed), speed2long(ospeed));
209 output(line);
210 }
211 else if (all || ospeed != TSPEED_DEF)
212 {
213 sprintf(line, "speed %lu baud;", speed2long(ospeed));
214 output(line);
215 }
216
217 /* The control modes. */
218
219 c_cflag= termios.c_cflag;
220 if (all || (c_cflag & CSIZE) != (TCTRL_DEF & CSIZE))
221 {
222 switch (c_cflag & CSIZE)
223 {
224 case CS5: output("cs5"); break;
225 case CS6: output("cs6"); break;
226 case CS7: output("cs7"); break;
227 case CS8: output("cs8"); break;
228 default: output("cs??"); break;
229 }
230 }
231 print_flags(c_cflag, PARENB, TCTRL_DEF, "-parenb", all);
232 print_flags(c_cflag, PARODD, TCTRL_DEF, "-parodd", all);
233 print_flags(c_cflag, HUPCL, TCTRL_DEF, "-hupcl", all);
234 print_flags(c_cflag, CSTOPB, TCTRL_DEF, "-cstopb", all);
235 print_flags(c_cflag, CREAD, TCTRL_DEF, "-cread", all);
236 print_flags(c_cflag, CLOCAL, TCTRL_DEF, "-clocal", all);
237
238 if (all)
239 {
240 printf("\n");
241 column= 0;
242 }
243
244 /* The input flags. */
245
246 c_iflag= termios.c_iflag;
247
248 print_flags(c_iflag, IGNBRK, TINPUT_DEF, "-ignbrk", all);
249 print_flags(c_iflag, BRKINT, TINPUT_DEF, "-brkint", all);
250 print_flags(c_iflag, IGNPAR, TINPUT_DEF, "-ignpar", all);
251 print_flags(c_iflag, PARMRK, TINPUT_DEF, "-parmrk", all);
252 print_flags(c_iflag, INPCK, TINPUT_DEF, "-inpck", all);
253 print_flags(c_iflag, ISTRIP, TINPUT_DEF, "-istrip", all);
254 print_flags(c_iflag, INLCR, TINPUT_DEF, "-inlcr", all);
255 print_flags(c_iflag, IGNCR, TINPUT_DEF, "-igncr", all);
256 print_flags(c_iflag, ICRNL, TINPUT_DEF, "-icrnl", all);
257 print_flags(c_iflag, IXON, TINPUT_DEF, "-ixon", all);
258 print_flags(c_iflag, IXOFF, TINPUT_DEF, "-ixoff", all);
259 print_flags(c_iflag, IXANY, TINPUT_DEF, "-ixany", all);
260
261 if (all)
262 {
263 printf("\n");
264 column= 0;
265 }
266
267 /* The output flags. */
268
269 c_oflag= termios.c_oflag;
270
271 print_flags(c_oflag, OPOST, TOUTPUT_DEF, "-opost", all);
272#ifdef __minix
273 print_flags(c_oflag, ONLCR, TOUTPUT_DEF, "-onlcr", all);
274 print_flags(c_oflag, XTABS, TOUTPUT_DEF, "-xtabs", all);
275 print_flags(c_oflag, ONOEOT, TOUTPUT_DEF, "-onoeot", all);
276#endif
277 if (all)
278 {
279 printf("\n");
280 column= 0;
281 }
282
283 /* The local flags. */
284
285 c_lflag= termios.c_lflag;
286
287 print_flags(c_lflag, ISIG, TLOCAL_DEF, "-isig", all);
288 print_flags(c_lflag, ICANON, TLOCAL_DEF, "-icanon", all);
289 print_flags(c_lflag, IEXTEN, TLOCAL_DEF, "-iexten", all);
290 print_flags(c_lflag, ECHO, TLOCAL_DEF, "-echo", all);
291 print_flags(c_lflag, ECHOE, TLOCAL_DEF, "-echoe", all);
292 print_flags(c_lflag, ECHOK, TLOCAL_DEF, "-echok", all);
293 print_flags(c_lflag, ECHONL, TLOCAL_DEF, "-echonl", all);
294 print_flags(c_lflag, NOFLSH, TLOCAL_DEF, "-noflsh", all);
295#ifdef TOSTOP
296 print_flags(c_lflag, TOSTOP, TLOCAL_DEF, "-tostop", all);
297#endif
298#ifdef __minix
299 print_flags(c_lflag, LFLUSHO, TLOCAL_DEF, "-lflusho", all);
300#endif
301
302 if (all)
303 {
304 printf("\n");
305 column= 0;
306 }
307
308 /* The special control characters. */
309
310 print_char(termios.c_cc[VEOF], TEOF_DEF, "eof", all);
311 print_char(termios.c_cc[VEOL], TEOL_DEF, "eol", all);
312 print_char(termios.c_cc[VERASE], TERASE_DEF, "erase", all);
313 print_char(termios.c_cc[VINTR], TINTR_DEF, "intr", all);
314 print_char(termios.c_cc[VKILL], TKILL_DEF, "kill", all);
315 print_char(termios.c_cc[VQUIT], TQUIT_DEF, "quit", all);
316 print_char(termios.c_cc[VSUSP], TSUSP_DEF, "susp", all);
317 print_char(termios.c_cc[VSTART], TSTART_DEF, "start", all);
318 print_char(termios.c_cc[VSTOP], TSTOP_DEF, "stop", all);
319#ifdef __minix
320 print_char(termios.c_cc[VREPRINT], TREPRINT_DEF, "rprnt", all);
321 print_char(termios.c_cc[VLNEXT], TLNEXT_DEF, "lnext", all);
322 print_char(termios.c_cc[VDISCARD], TDISCARD_DEF, "flush", all);
323#endif
324 print_num(termios.c_cc[VMIN], TMIN_DEF, "min", all);
325 print_num(termios.c_cc[VTIME], TTIME_DEF, "time", all);
326 if (all)
327 {
328 printf("\n");
329 column= 0;
330 }
331
332#ifdef __minix
333 /* Screen size */
334 if (all || winsize.ws_row != 0 || winsize.ws_col != 0)
335 {
336 sprintf(line, "%d rows %d columns", winsize.ws_row,
337 winsize.ws_col);
338 output(line);
339 }
340
341 if (all || winsize.ws_ypixel != 0 || winsize.ws_xpixel != 0)
342 {
343 sprintf(line, "%d ypixels %d xpixels", winsize.ws_ypixel,
344 winsize.ws_xpixel);
345 output(line);
346 }
347
348 if (all)
349 {
350 printf("\n");
351 column= 0;
352 }
353#endif
354
355 if (column != 0)
356 {
357 printf("\n");
358 column= 0;
359 }
360}
361
362int option(opt, next)
363char *opt, *next;
364{
365 char *check;
366 speed_t speed;
367 long num;
368
369 /* The control options. */
370
371 if (match(opt, "clocal")) {
372 termios.c_cflag |= CLOCAL;
373 return 0;
374 }
375 if (match(opt, "-clocal")) {
376 termios.c_cflag &= ~CLOCAL;
377 return 0;
378 }
379
380 if (match(opt, "cread")) {
381 termios.c_cflag |= CREAD;
382 return 0;
383 }
384 if (match(opt, "-cread")) {
385 termios.c_cflag &= ~CREAD;
386 return 0;
387 }
388
389 if (match(opt, "cs5")) {
390 termios.c_cflag &= ~CSIZE;
391 termios.c_cflag |= CS5;
392 return 0;
393 }
394 if (match(opt, "cs6")) {
395 termios.c_cflag &= ~CSIZE;
396 termios.c_cflag |= CS6;
397 return 0;
398 }
399 if (match(opt, "cs7")) {
400 termios.c_cflag &= ~CSIZE;
401 termios.c_cflag |= CS7;
402 return 0;
403 }
404 if (match(opt, "cs8")) {
405 termios.c_cflag &= ~CSIZE;
406 termios.c_cflag |= CS8;
407 return 0;
408 }
409
410 if (match(opt, "cstopb")) {
411 termios.c_cflag |= CSTOPB;
412 return 0;
413 }
414 if (match(opt, "-cstopb")) {
415 termios.c_cflag &= ~CSTOPB;
416 return 0;
417 }
418
419 if (match(opt, "hupcl") || match(opt, "hup")) {
420 termios.c_cflag |= HUPCL;
421 return 0;
422 }
423 if (match(opt, "-hupcl") || match(opt, "-hup")) {
424 termios.c_cflag &= ~HUPCL;
425 return 0;
426 }
427
428 if (match(opt, "parenb")) {
429 termios.c_cflag |= PARENB;
430 return 0;
431 }
432 if (match(opt, "-parenb")) {
433 termios.c_cflag &= ~PARENB;
434 return 0;
435 }
436
437 if (match(opt, "parodd")) {
438 termios.c_cflag |= PARODD;
439 return 0;
440 }
441 if (match(opt, "-parodd")) {
442 termios.c_cflag &= ~PARODD;
443 return 0;
444 }
445
446 num= strtol(opt, &check, 10);
447 if (check[0] == '\0')
448 {
449 speed= long2speed(num);
450 if (speed == (speed_t)-1)
451 {
452 fprintf(stderr, "%s: illegal speed: '%s'\n", prog_name, opt);
453 return 0;
454 }
455 /* Speed OK */
456 cfsetispeed(&termios, speed);
457 cfsetospeed(&termios, speed);
458 return 0;
459 }
460
461 if (match(opt, "ispeed")) {
462 num= strtol(next, &check, 10);
463 if (check != '\0')
464 {
465 speed= long2speed(num);
466 if (speed == (speed_t)-1)
467 {
468 fprintf(stderr, "%s: illegal speed: '%s'\n", prog_name,
469 opt);
470 return 1;
471 }
472 cfsetispeed(&termios, speed);
473 return 1;
474 }
475 else
476 {
477 fprintf(stderr, "%s: invalid argument to ispeed: '%s'\n",
478 prog_name, next);
479 return 1;
480 }
481 }
482
483 if (match(opt, "ospeed")) {
484 num= strtol(next, &check, 10);
485 if (check != '\0')
486 {
487 speed= long2speed(num);
488 if (speed == (speed_t)-1)
489 {
490 fprintf(stderr, "%s: illegal speed: '%s'\n", prog_name,
491 opt);
492 return 1;
493 }
494 cfsetospeed(&termios, speed);
495 return 1;
496 }
497 else
498 {
499 fprintf(stderr, "%s: invalid argument to ospeed: %s\n",
500 prog_name, next);
501 return 1;
502 }
503 }
504
505 /* Input modes. */
506
507 if (match(opt, "brkint")) {
508 termios.c_iflag |= BRKINT;
509 return 0;
510 }
511 if (match(opt, "-brkint")) {
512 termios.c_iflag &= ~BRKINT;
513 return 0;
514 }
515
516 if (match(opt, "icrnl")) {
517 termios.c_iflag |= ICRNL;
518 return 0;
519 }
520 if (match(opt, "-icrnl")) {
521 termios.c_iflag &= ~ICRNL;
522 return 0;
523 }
524
525 if (match(opt, "ignbrk")) {
526 termios.c_iflag |= IGNBRK;
527 return 0;
528 }
529 if (match(opt, "-ignbrk")) {
530 termios.c_iflag &= ~IGNBRK;
531 return 0;
532 }
533
534 if (match(opt, "igncr")) {
535 termios.c_iflag |= IGNCR;
536 return 0;
537 }
538 if (match(opt, "-igncr")) {
539 termios.c_iflag &= ~IGNCR;
540 return 0;
541 }
542
543 if (match(opt, "ignpar")) {
544 termios.c_iflag |= IGNPAR;
545 return 0;
546 }
547 if (match(opt, "-ignpar")) {
548 termios.c_iflag &= ~IGNPAR;
549 return 0;
550 }
551
552 if (match(opt, "inlcr")) {
553 termios.c_iflag |= INLCR;
554 return 0;
555 }
556 if (match(opt, "-inlcr")) {
557 termios.c_iflag &= ~INLCR;
558 return 0;
559 }
560
561 if (match(opt, "inpck")) {
562 termios.c_iflag |= INPCK;
563 return 0;
564 }
565 if (match(opt, "-inpck")) {
566 termios.c_iflag &= ~INPCK;
567 return 0;
568 }
569
570 if (match(opt, "istrip")) {
571 termios.c_iflag |= ISTRIP;
572 return 0;
573 }
574 if (match(opt, "-istrip")) {
575 termios.c_iflag &= ~ISTRIP;
576 return 0;
577 }
578
579 if (match(opt, "ixoff")) {
580 termios.c_iflag |= IXOFF;
581 return 0;
582 }
583 if (match(opt, "-ixoff")) {
584 termios.c_iflag &= ~IXOFF;
585 return 0;
586 }
587
588 if (match(opt, "ixon")) {
589 termios.c_iflag |= IXON;
590 return 0;
591 }
592 if (match(opt, "-ixon")) {
593 termios.c_iflag &= ~IXON;
594 return 0;
595 }
596
597 if (match(opt, "parmrk")) {
598 termios.c_iflag |= PARMRK;
599 return 0;
600 }
601 if (match(opt, "-parmrk")) {
602 termios.c_iflag &= ~PARMRK;
603 return 0;
604 }
605
606 if (match(opt, "ixany")) {
607 termios.c_iflag |= IXANY;
608 return 0;
609 }
610 if (match(opt, "-ixany")) {
611 termios.c_iflag &= ~IXANY;
612 return 0;
613 }
614
615 /* Output modes. */
616
617 if (match(opt, "opost")) {
618 termios.c_oflag |= OPOST;
619 return 0;
620 }
621 if (match(opt, "-opost")) {
622 termios.c_oflag &= ~OPOST;
623 return 0;
624 }
625#ifdef __minix
626 if (match(opt, "onlcr")) {
627 termios.c_oflag |= ONLCR;
628 return 0;
629 }
630 if (match(opt, "-onlcr")) {
631 termios.c_oflag &= ~ONLCR;
632 return 0;
633 }
634
635 if (match(opt, "xtabs")) {
636 termios.c_oflag |= XTABS;
637 return 0;
638 }
639 if (match(opt, "-xtabs")) {
640 termios.c_oflag &= ~XTABS;
641 return 0;
642 }
643
644 if (match(opt, "onoeot")) {
645 termios.c_oflag |= ONOEOT;
646 return 0;
647 }
648 if (match(opt, "-onoeot")) {
649 termios.c_oflag &= ~ONOEOT;
650 return 0;
651 }
652#endif
653
654 /* Local modes. */
655
656 if (match(opt, "echo")) {
657 termios.c_lflag |= ECHO;
658 return 0;
659 }
660 if (match(opt, "-echo")) {
661 termios.c_lflag &= ~ECHO;
662 return 0;
663 }
664
665 if (match(opt, "echoe")) {
666 termios.c_lflag |= ECHOE;
667 return 0;
668 }
669 if (match(opt, "-echoe")) {
670 termios.c_lflag &= ~ECHOE;
671 return 0;
672 }
673
674 if (match(opt, "echok")) {
675 termios.c_lflag |= ECHOK;
676 return 0;
677 }
678 if (match(opt, "-echok")) {
679 termios.c_lflag &= ~ECHOK;
680 return 0;
681 }
682
683 if (match(opt, "echonl")) {
684 termios.c_lflag |= ECHONL;
685 return 0;
686 }
687 if (match(opt, "-echonl")) {
688 termios.c_lflag &= ~ECHONL;
689 return 0;
690 }
691
692 if (match(opt, "icanon")) {
693 termios.c_lflag |= ICANON;
694 return 0;
695 }
696 if (match(opt, "-icanon")) {
697 termios.c_lflag &= ~ICANON;
698 return 0;
699 }
700
701 if (match(opt, "iexten")) {
702 termios.c_lflag |= IEXTEN;
703 return 0;
704 }
705 if (match(opt, "-iexten")) {
706 termios.c_lflag &= ~IEXTEN;
707 return 0;
708 }
709
710 if (match(opt, "isig")) {
711 termios.c_lflag |= ISIG;
712 return 0;
713 }
714 if (match(opt, "-isig")) {
715 termios.c_lflag &= ~ISIG;
716 return 0;
717 }
718
719 if (match(opt, "noflsh")) {
720 termios.c_lflag |= NOFLSH;
721 return 0;
722 }
723 if (match(opt, "-noflsh")) {
724 termios.c_lflag &= ~NOFLSH;
725 return 0;
726 }
727
728 if (match(opt, "tostop")) {
729 termios.c_lflag |= TOSTOP;
730 return 0;
731 }
732 if (match(opt, "-tostop")) {
733 termios.c_lflag &= ~TOSTOP;
734 return 0;
735 }
736
737#ifdef __minix
738 if (match(opt, "lflusho")) {
739 termios.c_lflag |= LFLUSHO;
740 return 0;
741 }
742 if (match(opt, "-lflusho")) {
743 termios.c_lflag &= ~LFLUSHO;
744 return 0;
745 }
746#endif
747
748 /* The special control characters. */
749 if (match(opt, "eof")) {
750 set_control(VEOF, next);
751 return 1;
752 }
753
754 if (match(opt, "eol")) {
755 set_control(VEOL, next);
756 return 1;
757 }
758
759 if (match(opt, "erase")) {
760 set_control(VERASE, next);
761 return 1;
762 }
763
764 if (match(opt, "intr")) {
765 set_control(VINTR, next);
766 return 1;
767 }
768
769 if (match(opt, "kill")) {
770 set_control(VKILL, next);
771 return 1;
772 }
773
774 if (match(opt, "quit")) {
775 set_control(VQUIT, next);
776 return 1;
777 }
778
779 if (match(opt, "susp")) {
780 set_control(VSUSP, next);
781 return 1;
782 }
783
784 if (match(opt, "start")) {
785 set_control(VSTART, next);
786 return 1;
787 }
788
789 if (match(opt, "stop")) {
790 set_control(VSTOP, next);
791 return 1;
792 }
793#ifdef __minix
794 if (match(opt, "rprnt")) {
795 set_control(VREPRINT, next);
796 return 1;
797 }
798
799 if (match(opt, "lnext")) {
800 set_control(VLNEXT, next);
801 return 1;
802 }
803
804 if (match(opt, "flush")) {
805 set_control(VDISCARD, next);
806 return 1;
807 }
808#endif
809
810 if (match(opt, "min")) {
811 set_min_tim(VMIN, next);
812 return 1;
813 }
814
815 if (match(opt, "time")) {
816 set_min_tim(VTIME, next);
817 return 1;
818 }
819
820 /* Special modes. */
821 if (opt[0] == ':')
822 {
823 set_saved_settings(opt);
824 return 0;
825 }
826
827 if (match(opt, "cooked") || match(opt, "raw")) {
828 int x = opt[0] == 'c' ? 1 : 0;
829
830 option(x + "-icrnl", ""); /* off in raw mode, on in cooked mode */
831 option(x + "-ixon", "");
832 option(x + "-opost", "");
833 option(x + "-onlcr", "");
834 option(x + "-isig", "");
835 option(x + "-icanon", "");
836 option(x + "-iexten", "");
837 option(x + "-echo", "");
838 return 0;
839 }
840
841 if (match(opt, "evenp") || match(opt, "parity")) {
842 option("parenb", "");
843 option("cs7", "");
844 option("-parodd", "");
845 return 0;
846 }
847
848 if (match(opt, "oddp")) {
849 option("parenb", "");
850 option("cs7", "");
851 option("parodd", "");
852 return 0;
853 }
854
855 if (match(opt, "-parity") || match(opt, "-evenp") || match(opt, "-oddp")) {
856 option("-parenb", "");
857 option("cs8", "");
858 return 0;
859 }
860
861 if (match(opt, "nl")) {
862 option("icrnl", "");
863 return 0;
864 }
865
866 if (match(opt, "-nl")) {
867 option("-icrnl", "");
868 option("-inlcr", "");
869 option("-igncr", "");
870 return 0;
871 }
872
873 if (match(opt, "ek")) {
874 termios.c_cc[VERASE]= TERASE_DEF;;
875 termios.c_cc[VKILL]= TKILL_DEF;;
876 return 0;
877 }
878
879 if (match(opt, "sane"))
880 {
881 /* Reset all terminal attributes to a sane state, except things like
882 * line speed and parity, because it can't be known what their sane
883 * values are.
884 */
885 termios.c_iflag= (TINPUT_DEF & ~(IGNPAR|ISTRIP|INPCK))
886 | (termios.c_iflag & (IGNPAR|ISTRIP|INPCK));
887 termios.c_oflag= (TOUTPUT_DEF & ~(XTABS))
888 | (termios.c_oflag & (XTABS));
889 termios.c_cflag= (TCTRL_DEF & ~(CLOCAL|CSIZE|CSTOPB|PARENB|PARODD))
890 | (termios.c_cflag & (CLOCAL|CSIZE|CSTOPB|PARENB|PARODD));
891 termios.c_lflag= (TLOCAL_DEF & ~(ECHOE|ECHOK))
892 | (termios.c_lflag & (ECHOE|ECHOK));
893 if (termios.c_lflag & ICANON) {
894 termios.c_cc[VMIN]= TMIN_DEF;
895 termios.c_cc[VTIME]= TTIME_DEF;
896 }
897 termios.c_cc[VEOF]= TEOF_DEF;
898 termios.c_cc[VEOL]= TEOL_DEF;
899 termios.c_cc[VERASE]= TERASE_DEF;
900 termios.c_cc[VINTR]= TINTR_DEF;
901 termios.c_cc[VKILL]= TKILL_DEF;
902 termios.c_cc[VQUIT]= TQUIT_DEF;
903 termios.c_cc[VSUSP]= TSUSP_DEF;
904#ifdef __minix
905 termios.c_cc[VREPRINT]= TREPRINT_DEF;
906 termios.c_cc[VLNEXT]= TLNEXT_DEF;
907 termios.c_cc[VDISCARD]= TDISCARD_DEF;
908#endif
909 termios.c_cc[VSTART]= TSTART_DEF;
910 termios.c_cc[VSTOP]= TSTOP_DEF;
911 if (!(termios.c_lflag & ICANON)) {
912 termios.c_cc[VMIN]= TMIN_DEF;
913 termios.c_cc[VTIME]= TTIME_DEF;
914 }
915 return 0;
916 }
917
918#ifdef __minix
919 if (match(opt, "cols"))
920 {
921 num= strtol(next, &check, 0);
922 if (check[0] != '\0')
923 {
924 fprintf(stderr, "%s: illegal parameter to cols: '%s'\n",
925 prog_name, next);
926 return 1;
927 }
928 winsize.ws_col= num;
929 return 1;
930 }
931
932 if (match(opt, "rows"))
933 {
934 num= strtol(next, &check, 0);
935 if (check[0] != '\0')
936 {
937 fprintf(stderr, "%s: illegal parameter to rows: '%s'\n",
938 prog_name, next);
939 return 1;
940 }
941 winsize.ws_row= num;
942 return 1;
943 }
944
945 if (match(opt, "xpixels"))
946 {
947 num= strtol(next, &check, 0);
948 if (check[0] != '\0')
949 {
950 fprintf(stderr, "%s: illegal parameter to xpixels: '%s'\n",
951 prog_name, next);
952 return 1;
953 }
954 winsize.ws_xpixel= num;
955 return 1;
956 }
957
958 if (match(opt, "ypixels"))
959 {
960 num= strtol(next, &check, 0);
961 if (check[0] != '\0')
962 {
963 fprintf(stderr, "%s: illegal parameter to ypixels: '%s'\n",
964 prog_name, next);
965 return 1;
966 }
967 winsize.ws_ypixel= num;
968 return 1;
969 }
970#endif /* __minix */
971
972 fprintf(stderr, "%s: unknown mode: %s\n", prog_name, opt);
973 return 0;
974}
975
976int match(s1, s2)
977char *s1, *s2;
978{
979
980 while (1) {
981 if (*s1 == 0 && *s2 == 0) return(1);
982 if (*s1 == 0 || *s2 == 0) return (0);
983 if (*s1 != *s2) return (0);
984 s1++;
985 s2++;
986 }
987}
988
989void prctl(c)
990char c;
991{
992 if (c < ' ')
993 printf("^%c", 'A' + c - 1);
994 else if (c == 0177)
995 printf("^?");
996 else
997 printf("%c", c);
998}
999
1000struct s2s {
1001 speed_t ts;
1002 long ns;
1003} s2s[] = {
1004 { B0, 0 },
1005 { B50, 50 },
1006 { B75, 75 },
1007 { B110, 110 },
1008 { B134, 134 },
1009 { B150, 150 },
1010 { B200, 200 },
1011 { B300, 300 },
1012 { B600, 600 },
1013 { B1200, 1200 },
1014 { B1800, 1800 },
1015 { B2400, 2400 },
1016 { B4800, 4800 },
1017 { B9600, 9600 },
1018 { B19200, 19200 },
1019 { B38400, 38400 },
1020#ifdef __minix
1021 { B57600, 57600 },
1022 { B115200, 115200 },
1023#ifdef B230400
1024 { B230400, 230400 },
1025#endif
1026#ifdef B460800
1027 { B460800, 460800 },
1028#endif
1029#ifdef B921600
1030 { B921600, 921600 },
1031#endif
1032#endif
1033};
1034
1035speed_t long2speed(num)
1036long num;
1037{
1038 struct s2s *sp;
1039
1040 for (sp = s2s; sp < s2s + (sizeof(s2s) / sizeof(s2s[0])); sp++) {
1041 if (sp->ns == num) return sp->ts;
1042 }
1043 return -1;
1044}
1045
1046long speed2long(speed)
1047unsigned long speed;
1048{
1049 struct s2s *sp;
1050
1051 for (sp = s2s; sp < s2s + (sizeof(s2s) / sizeof(s2s[0])); sp++) {
1052 if (sp->ts == speed) return sp->ns;
1053 }
1054 return -1;
1055}
1056
1057void print_flags(flags, flag, def, string, all)
1058unsigned long flags;
1059unsigned long flag;
1060unsigned long def;
1061char *string;
1062int all;
1063{
1064 if (!(flags & flag))
1065 {
1066 if (all || (def & flag))
1067 output(string);
1068 return;
1069 }
1070 string++;
1071 if (all || !(def & flag))
1072 output(string);
1073}
1074
1075void output(s)
1076char *s;
1077{
1078 int len;
1079
1080 len= strlen(s);
1081 if (column + len + 3 >= max_column)
1082 {
1083 printf("\n");
1084 column= 0;
1085 }
1086 if (column)
1087 {
1088 putchar(' ');
1089 column++;
1090 }
1091 fputs(s, stdout);
1092 column += len;
1093}
1094
1095void do_print_char(chr, def, name, all)
1096unsigned chr;
1097unsigned def;
1098char *name;
1099int all;
1100{
1101 char line[20];
1102
1103 if (!all && chr == def)
1104 return;
1105
1106#ifdef _POSIX_VDISABLE
1107 if (chr == _POSIX_VDISABLE)
1108 sprintf(line, "%s = <undef>", name);
1109 else
1110#endif
1111 if (chr < ' ')
1112 sprintf(line, "%s = ^%c", name, chr + '@');
1113 else if (chr == 127)
1114 sprintf(line, "%s = ^?", name);
1115 else
1116 sprintf(line, "%s = %c", name, chr);
1117 output(line);
1118}
1119
1120void do_print_num(num, def, name, all)
1121unsigned num;
1122unsigned def;
1123char *name;
1124int all;
1125{
1126 char line[20];
1127
1128 if (!all && num == def)
1129 return;
1130 sprintf(line, "%s = %u", name, num);
1131 output(line);
1132}
1133
1134void set_saved_settings(opt)
1135char *opt;
1136{
1137 long num;
1138 char *check;
1139 tcflag_t c_oflag, c_cflag, c_lflag, c_iflag;
1140 cc_t c_cc[NCCS];
1141 speed_t ispeed, ospeed;
1142 int i;
1143
1144 check= opt;
1145 num= strtol(check+1, &check, 16);
1146 if (check[0] != ':')
1147 {
1148 fprintf(stderr, "error in saved settings '%s'\n", opt);
1149 return;
1150 }
1151 c_iflag= num;
1152
1153 num= strtol(check+1, &check, 16);
1154 if (check[0] != ':')
1155 {
1156 fprintf(stderr, "error in saved settings '%s'\n", opt);
1157 return;
1158 }
1159 c_oflag= num;
1160
1161 num= strtol(check+1, &check, 16);
1162 if (check[0] != ':')
1163 {
1164 fprintf(stderr, "error in saved settings '%s'\n", opt);
1165 return;
1166 }
1167 c_cflag= num;
1168
1169 num= strtol(check+1, &check, 16);
1170 if (check[0] != ':')
1171 {
1172 fprintf(stderr, "error in saved settings '%s'\n", opt);
1173 return;
1174 }
1175 c_lflag= num;
1176
1177 num= strtol(check+1, &check, 16);
1178 if (check[0] != ':')
1179 {
1180 fprintf(stderr, "error in saved settings '%s'\n", opt);
1181 return;
1182 }
1183 ispeed= num;
1184
1185 num= strtol(check+1, &check, 16);
1186 if (check[0] != ':')
1187 {
1188 fprintf(stderr, "error in saved settings '%s'\n", opt);
1189 return;
1190 }
1191 ospeed= num;
1192
1193 for(i=0; i<NCCS; i++)
1194 {
1195 num= strtol(check+1, &check, 16);
1196 if (check[0] != ':')
1197 {
1198 fprintf(stderr, "error in saved settings '%s'\n", opt);
1199 return;
1200 }
1201 c_cc[i]= num;
1202 }
1203 if (check[1] != '\0')
1204 {
1205 fprintf(stderr, "error in saved settings '%s'\n", opt);
1206 return;
1207 }
1208 termios.c_iflag= c_iflag;
1209 termios.c_oflag= c_oflag;
1210 termios.c_cflag= c_cflag;
1211 termios.c_lflag= c_lflag;
1212
1213 cfsetispeed(&termios, ispeed);
1214 cfsetospeed(&termios, ospeed);
1215
1216 for(i=0; i<NCCS; i++)
1217 termios.c_cc[i]= c_cc[i];
1218}
1219
1220void set_control(option, value)
1221int option;
1222char *value;
1223{
1224 int chr;
1225
1226 if (match(value, "undef") || match(value, "^-")) {
1227#ifdef _POSIX_VDISABLE
1228 chr= _POSIX_VDISABLE;
1229#else
1230 fprintf(stderr,
1231 "stty: unable to set option to _POSIX_VDISABLE\n");
1232 return;
1233#endif
1234 } else if (match(value, "^?"))
1235 chr= '\177';
1236 else if (strlen(value) == 2 && value[0] == '^') {
1237 chr= toupper(value[1]) - '@';
1238 if (chr < 0 || chr >= 32) {
1239 fprintf(stderr, "stty: illegal option value: '%s'\n",
1240 value);
1241 return;
1242 }
1243 } else if (strlen(value) == 1)
1244 chr= value[0];
1245 else {
1246 fprintf(stderr, "stty: illegal option value: '%s'\n", value);
1247 return;
1248 }
1249
1250 assert(option >= 0 && option < NCCS);
1251 termios.c_cc[option]= chr;
1252}
1253
1254void set_min_tim(option, value)
1255int option;
1256char *value;
1257{
1258 long num;
1259 char *check;
1260
1261 num= strtol(value, &check, 0);
1262 if (check[0] != '\0') {
1263 fprintf(stderr, "stty: illegal option value: '%s'\n", value);
1264 return;
1265 }
1266
1267 if ((cc_t)num != num) {
1268 fprintf(stderr, "stty: illegal option value: '%s'\n", value);
1269 return;
1270 }
1271 assert(option >= 0 && option < NCCS);
1272 termios.c_cc[option]= num;
1273}
1274
1275/*
1276 * $PchId: stty.c,v 1.7 2001/05/02 15:04:42 philip Exp $
1277 */
Note: See TracBrowser for help on using the repository browser.