123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- #include <u.h>
- #include <libc.h>
- #include <tty.h>
- typedef struct Mode Mode;
- struct Mode
- {
- char* name;
- int bit;
- };
- Mode ou[] =
- {
- "opost", OPOST,
- "olcuc", OLCUC,
- "onlcr", ONLCR,
- "ocrnl", OCRNL,
- "onocr", ONOCR,
- "onlret", ONLRET,
- "ofill", OFILL,
- "ofdel", OFDEL,
- 0
- };
- Mode in[] =
- {
- "brkint", BRKINT,
- "icrnl", ICRNL,
- "ignbrk", IGNBRK,
- "igncr", IGNCR,
- "ignpar", IGNPAR,
- "inlcr", INLCR,
- "inpck", INPCK,
- "istrip", ISTRIP,
- "ixoff", IXOFF,
- "ixon", IXON,
- "parmrk", PARMRK,
- 0
- };
- Mode lo[] =
- {
- "echo", ECHO,
- "echoe", ECHOE,
- "echok", ECHOK,
- "echonl", ECHONL,
- "icanon", ICANON,
- "iexten", IEXTEN,
- "isig", ISIG,
- "noflsh", NOFLSH,
- "tostop", TOSTOP,
- 0
- };
- Mode cc[] =
- {
- "eof", VEOF,
- "eol", VEOL,
- "erase", VERASE,
- "intr", VINTR,
- "kill", VKILL,
- "min", VMIN,
- "quit", VQUIT,
- "susp", VSUSP,
- "time", VTIME,
- "start", VSTART,
- "stop", VSTOP,
- 0,
- };
- int getmode(int, Termios*);
- int setmode(int, Termios*);
- char*
- ctlchar(char c)
- {
- static char buf[10];
- if(c == 0x7f)
- return "DEL";
- if(c == 0)
- return "NUL";
- if(c < 32) {
- buf[0] = '^';
- buf[1] = '@'+c;
- buf[2] = '\0';
- return buf;
- }
- buf[0] = c;
- buf[1] = '\0';
- return buf;
- }
- void
- showmode(Termios *t)
- {
- int i;
- for(i = 0; cc[i].name; i++) {
- switch(cc[i].bit) {
- case VMIN:
- case VTIME:
- if(t->cc[i] != 0)
- print("%s %d ", cc[i].name, t->cc[i]);
- break;
- default:
- print("%s %s ", cc[i].name, ctlchar(t->cc[i]));
- break;
- }
- }
- print("\n");
- for(i = 0; ou[i].name; i++)
- if(ou[i].bit & t->oflag)
- print("%s ", ou[i].name);
- for(i = 0; in[i].name; i++)
- if(in[i].bit & t->iflag)
- print("%s ", in[i].name);
- print("\n");
- for(i = 0; lo[i].name; i++)
- if(lo[i].bit & t->lflag)
- print("%s ", lo[i].name);
- print("\n");
- }
- int
- setreset(char *mode, int *bits, Mode *t)
- {
- int i, clr;
- clr = 0;
- if(mode[0] == '-') {
- mode++;
- clr = 1;
- }
- for(i = 0; t[i].name; i++) {
- if(strcmp(mode, t[i].name) == 0) {
- if(clr)
- *bits &= ~t[i].bit;
- else
- *bits |= t[i].bit;
- return 1;
- }
- }
- return 0;
- }
- int
- ccname(char *name)
- {
- int i;
- for(i = 0; cc[i].name; i++)
- if(strcmp(cc[i].name, name) == 0)
- return i;
- return -1;
- }
- void
- main(int argc, char **argv)
- {
- Termios t;
- int i, stdin, wmo, cc;
- /* Try and get a seek pointer */
- stdin = open("/fd/0", ORDWR);
- if(stdin < 0)
- stdin = 0;
- if(getmode(stdin, &t) < 0) {
- fprint(2, "stty: tiocget %r\n");
- exits("1");
- }
- if(argc < 2) {
- fprint(2, "usage: stty [-a|-g] modes...\n");
- exits("1");
- }
- wmo = 0;
- for(i = 1; i < argc; i++) {
- if(strcmp(argv[i], "-a") == 0) {
- showmode(&t);
- continue;
- }
- if(setreset(argv[i], &t.iflag, in)) {
- wmo++;
- continue;
- }
- if(setreset(argv[i], &t.lflag, lo)) {
- wmo++;
- continue;
- }
- if(setreset(argv[i], &t.oflag, ou)) {
- wmo++;
- continue;
- }
- cc = ccname(argv[i]);
- if(cc != -1 && i+1 < argc) {
- wmo++;
- t.cc[cc] = argv[++i][0];
- continue;
- }
- fprint(2, "stty: bad option/mode %s\n", argv[i]);
- exits("1");
- }
- if(wmo) {
- if(setmode(stdin, &t) < 0) {
- fprint(2, "stty: cant set mode %r\n");
- exits("1");
- }
- }
- exits(0);
- }
- int
- setmode(int fd, Termios *t)
- {
- int n, i;
- char buf[256];
- n = sprint(buf, "IOW %4.4ux %4.4ux %4.4ux %4.4ux ",
- t->iflag, t->oflag, t->cflag, t->lflag);
- for(i = 0; i < NCCS; i++)
- n += sprint(buf+n, "%2.2ux ", t->cc[i]);
- if(seek(fd, -2, 0) != -2)
- return -1;
- n = write(fd, buf, n);
- if(n < 0)
- return -1;
- return 0;
- }
- /*
- * Format is: IOR iiii oooo cccc llll xx xx xx xx ...
- */
- int
- getmode(int fd, Termios *t)
- {
- int n;
- char buf[256];
- if(seek(fd, -2, 0) != -2)
- return -1;
- n = read(fd, buf, 57);
- if(n < 0)
- return -1;
- t->iflag = strtoul(buf+4, 0, 16);
- t->oflag = strtoul(buf+9, 0, 16);
- t->cflag = strtoul(buf+14, 0, 16);
- t->lflag = strtoul(buf+19, 0, 16);
- for(n = 0; n < NCCS; n++)
- t->cc[n] = strtoul(buf+24+(n*3), 0, 16);
- return 0;
- }
|