summaryrefslogtreecommitdiff
path: root/sys/src/ape/9src/stty.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/ape/9src/stty.c266
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;
+}