diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/9src/stty.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/9src/stty.c')
-rwxr-xr-x | sys/src/ape/9src/stty.c | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/sys/src/ape/9src/stty.c b/sys/src/ape/9src/stty.c new file mode 100755 index 000000000..54d92ee81 --- /dev/null +++ b/sys/src/ape/9src/stty.c @@ -0,0 +1,266 @@ +#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; +} |