diff options
| author | Michael Forney <mforney@mforney.org> | 2016-12-11 16:04:20 -0800 |
|---|---|---|
| committer | Michael Forney <mforney@mforney.org> | 2016-12-13 23:10:30 -0800 |
| commit | 293f5a93b77d92fd65db7f3d0df654f102e46cfb (patch) | |
| tree | 6ecd1170e3dd793862dd852814dc1b4cd5e44260 /pkg/ubase/patch/0003-Add-stty-1.patch | |
| parent | 9a506a6834df01a26795cea222b410f206efa9fa (diff) | |
Move to flat package hierarchy
Note to self: never try to move submodules again
To migrate your existing submodules (more or less):
set -x
set -e
mkdir .git/modules/pkg
for old in */*/src ; do
new="pkg/${old#*/}"
if ! [ -f "$old/.git" ] || [ "${old%%/*}" = pkg ] ; then
continue
fi
git -C ".git/modules/$old" config core.worktree "../../../../../$new"
rmdir "$new"
mv "$old" "$new"
sed -e "s,$old,$new," "$new/.git" > "$new/.git.tmp"
mv "$new/.git.tmp" "$new/.git"
mkdir ".git/modules/${new%/src}"
mv ".git/modules/$old" ".git/modules/$new"
rm "${old%/src}"/*.ninja
mv "${old%/src}"/*.tar.{gz,xz,bz2} "${new%/src}/"
rmdir "${old%/src}" || true
done
sed -e 's,^\[submodule "[^/]*/,[submodule "pkg/,' .git/config > .git/config.tmp
mv .git/config.tmp .git/config
Diffstat (limited to 'pkg/ubase/patch/0003-Add-stty-1.patch')
| -rw-r--r-- | pkg/ubase/patch/0003-Add-stty-1.patch | 811 |
1 files changed, 811 insertions, 0 deletions
diff --git a/pkg/ubase/patch/0003-Add-stty-1.patch b/pkg/ubase/patch/0003-Add-stty-1.patch new file mode 100644 index 00000000..7f9876a6 --- /dev/null +++ b/pkg/ubase/patch/0003-Add-stty-1.patch @@ -0,0 +1,811 @@ +From a5fa7dc291bf970a05e113434cd847e03d61e826 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= <maandree@kth.se> +Date: Mon, 28 Mar 2016 18:52:07 +0200 +Subject: [PATCH] Add stty(1) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Mattias Andrée <maandree@kth.se> +--- + Makefile | 1 + + TODO | 1 + + stty.c | 762 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 764 insertions(+) + create mode 100644 stty.c + +diff --git a/Makefile b/Makefile +index 453607c..4b872ae 100644 +--- a/Makefile ++++ b/Makefile +@@ -75,6 +75,7 @@ BIN = \ + respawn \ + rmmod \ + stat \ ++ stty \ + su \ + swaplabel \ + swapoff \ +diff --git a/TODO b/TODO +index 21f5c20..5cdc351 100644 +--- a/TODO ++++ b/TODO +@@ -23,6 +23,7 @@ rfkill + rmgroup + rmuser + setcap ++stty manpage + tabs + taskset + top +diff --git a/stty.c b/stty.c +new file mode 100644 +index 0000000..c65748a +--- /dev/null ++++ b/stty.c +@@ -0,0 +1,762 @@ ++/* See LICENSE file for copyright and license details. */ ++#include <ctype.h> ++#include <errno.h> ++#include <limits.h> ++#include <stdarg.h> ++#include <stdint.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <sys/ioctl.h> ++#include <termios.h> ++#include <unistd.h> ++ ++#include "util.h" ++ ++/* ++ * Petty POSIX violations: ++ * ++ * - XBD 12.2 is not honoured precisely. This is for ++ * convenience and compatibility with other implementations. ++ */ ++ ++#define CC_MAX 255 ++ ++static int output_size_requested = 0; ++static int output_speed_requested = 0; ++static int drain_requested = 1; ++ ++static void sane(int, struct termios *); ++static void setwinsize(long, long); ++static void ispeed(char *, struct termios *); ++static void ospeed(char *, struct termios *); ++ ++static void ++raw(int unset, struct termios *m) ++{ ++ if (!unset) { ++ m->c_iflag = 0; ++ m->c_lflag &= ~XCASE; ++ m->c_cc[VMIN] = 1; ++ m->c_cc[VTIME] = 0; ++ } else { ++ m->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON; ++ } ++} ++ ++static void ++evenp(int unset, struct termios *m) ++{ ++ m->c_oflag &= ~CSIZE; ++ m->c_oflag &= ~(unset ? PARENB : PARODD); ++ m->c_oflag |= unset ? CS8 : (CS7 | PARENB); ++} ++ ++ ++static void ++dec(int unset, struct termios *m) ++{ ++ m->c_cc[VINTR] = CINTR; ++ m->c_cc[VKILL] = CKILL; ++ m->c_cc[VERASE] = CERASE; ++ (void) unset; ++} ++ ++static void ++ek(int unset, struct termios *m) ++{ ++ m->c_cc[VKILL] = CKILL; ++ m->c_cc[VERASE] = CERASE; ++ (void) unset; ++} ++ ++static void ++nl(int unset, struct termios *m) ++{ ++ if (unset) { ++ m->c_iflag &= ~(INLCR | IGNCR); ++ m->c_oflag &= ~(OCRNL | ONLRET); ++ } ++} ++ ++static void ++oddp(int unset, struct termios *m) ++{ ++ m->c_oflag &= ~CSIZE; ++ m->c_oflag &= ~(unset ? PARENB : 0); ++ m->c_oflag |= unset ? CS8 : (CS7 | PARODD | PARENB); ++} ++ ++static void drain(int unset, struct termios *m) { drain_requested = !unset; (void) m; } ++static void cooked(int unset, struct termios *m) { raw(!unset, m); } ++static void pass8(int unset, struct termios *m) { m->c_cflag &= ~CSIZE, m->c_cflag |= unset ? CS7 : CS8; } ++static void size(int unset, struct termios *m) { output_size_requested = 1; (void) m; (void) unset; } ++static void speed(int unset, struct termios *m) { output_speed_requested = 1; (void) m; (void) unset; } ++static void tabs(int unset, struct termios *m) { m->c_oflag &= ~TABDLY, m->c_oflag |= unset ? TAB3 : TAB0; } ++static void cols(char *arg, struct termios *m) { setwinsize(-1, estrtonum(arg, 0, USHRT_MAX)); (void) m; } ++static void line(char *arg, struct termios *m) { m->c_line = estrtonum(arg, 0, 255); } ++static void min(char *arg, struct termios *m) { m->c_cc[VMIN] = estrtonum(arg, 0, CC_MAX); } ++static void rows(char *arg, struct termios *m) { setwinsize(estrtonum(arg, 0, USHRT_MAX), -1); (void) m; } ++static void stime(char *arg, struct termios *m) { m->c_cc[VTIME] = estrtonum(arg, 0, CC_MAX); } ++ ++enum type { CTRL, IN, OUT, LOCAL, COMB, SPEC }; ++enum { ++ BOOL = 1, ++ DUP = 2, ++ SANE = 4, ++ INSANE = 8, ++ CBREAK = 16, ++ DECCTLQ = 32, ++ LCASE = 64, ++ PASS8 = 128, ++ LITOUT = 256, ++ CRT = 1024, ++ DEC = 2048, ++ NL = 4096, ++ COOKED = 8192 ++}; ++ ++struct mode { ++ const char *op; ++ enum type type; ++ tcflag_t set; ++ tcflag_t clear; ++ void (*fun)(int, struct termios *); ++ int flags; ++}; ++ ++struct key { ++ const char *op; ++ size_t index; ++ cc_t sanevalue; ++}; ++ ++struct intvalued { ++ const char *op; ++ void (*fun)(char *, struct termios *); ++}; ++ ++struct speed { ++ const char *str; ++ speed_t speed; ++}; ++ ++static const struct mode modes[] = { ++ {"clocal", CTRL, CLOCAL, 0, 0, BOOL}, ++ {"cmspar", CTRL, CMSPAR, 0, 0, BOOL}, ++ {"cread", CTRL, CREAD, 0, 0, BOOL | SANE}, ++ {"crtscts", CTRL, CRTSCTS, 0, 0, BOOL}, ++ {"cs5", CTRL, CS5, CSIZE, 0, 0}, ++ {"cs6", CTRL, CS6, CSIZE, 0, 0}, ++ {"cs7", CTRL, CS7, CSIZE, 0, 0}, ++ {"cs8", CTRL, CS8, CSIZE, 0, 0}, ++ {"cstopb", CTRL, CSTOPB, 0, 0, BOOL}, ++ {"hup", CTRL, HUPCL, 0, 0, BOOL | DUP}, ++ {"hupcl", CTRL, HUPCL, 0, 0, BOOL}, ++ {"parenb", CTRL, PARENB, 0, 0, BOOL | PASS8 | LITOUT}, ++ {"parodd", CTRL, PARODD, 0, 0, BOOL}, ++ ++ {"brkint", IN, BRKINT, 0, 0, BOOL | SANE}, ++ {"icrnl", IN, ICRNL, 0, 0, BOOL | SANE | NL}, ++ {"ignbrk", IN, IGNBRK, 0, 0, BOOL | INSANE}, ++ {"igncr", IN, IGNCR, 0, 0, BOOL | INSANE}, ++ {"ignpar", IN, IGNPAR, 0, 0, BOOL}, ++ {"imaxbel", IN, IMAXBEL, 0, 0, BOOL | SANE}, ++ {"inlcr", IN, INLCR, 0, 0, BOOL | INSANE}, ++ {"inpck", IN, INPCK, 0, 0, BOOL}, ++ {"istrip", IN, ISTRIP, 0, 0, BOOL | PASS8 | LITOUT}, ++ {"iuclc", IN, IUCLC, 0, 0, BOOL | INSANE | LCASE}, ++ {"iutf8", IN, IUTF8, 0, 0, BOOL | SANE}, ++ {"ixany", IN, IXANY, 0, 0, BOOL | INSANE | DECCTLQ}, ++ {"ixoff", IN, IXOFF, 0, 0, BOOL | INSANE}, ++ {"ixon", IN, IXON, 0, 0, BOOL}, ++ {"parmrk", IN, PARMRK, 0, 0, BOOL}, ++ {"tandem", IN, IXOFF, 0, 0, BOOL | DUP}, ++ ++ {"bs0", OUT, BS0, BSDLY, 0, SANE}, ++ {"bs1", OUT, BS1, BSDLY, 0, INSANE}, ++ {"cr0", OUT, CR0, CRDLY, 0, SANE}, ++ {"cr1", OUT, CR1, CRDLY, 0, INSANE}, ++ {"cr2", OUT, CR2, CRDLY, 0, INSANE}, ++ {"cr3", OUT, CR3, CRDLY, 0, INSANE}, ++ {"ff0", OUT, FF0, FFDLY, 0, SANE}, ++ {"ff1", OUT, FF1, FFDLY, 0, INSANE}, ++ {"nl0", OUT, NL0, NLDLY, 0, SANE}, ++ {"nl1", OUT, NL1, NLDLY, 0, INSANE}, ++ {"ocrnl", OUT, OCRNL, 0, 0, BOOL | INSANE}, ++ {"ofdel", OUT, OFDEL, 0, 0, BOOL | INSANE}, ++ {"ofill", OUT, OFILL, 0, 0, BOOL | INSANE}, ++ {"olcuc", OUT, OLCUC, 0, 0, BOOL | INSANE | LCASE}, ++ {"onlcr", OUT, ONLCR, 0, 0, BOOL | SANE | NL}, ++ {"onlret", OUT, ONLRET, 0, 0, BOOL | INSANE}, ++ {"onocr", OUT, ONOCR, 0, 0, BOOL | INSANE}, ++ {"opost", OUT, OPOST, 0, 0, BOOL | SANE | LITOUT | COOKED}, ++ {"tab0", OUT, TAB0, TABDLY, 0, SANE}, ++ {"tab1", OUT, TAB1, TABDLY, 0, INSANE}, ++ {"tab2", OUT, TAB2, TABDLY, 0, INSANE}, ++ {"tab3", OUT, TAB3, TABDLY, 0, INSANE}, ++ {"vt0", OUT, VT0, VTDLY, 0, SANE}, ++ {"vt1", OUT, VT1, VTDLY, 0, INSANE}, ++ ++ {"crterase", LOCAL, ECHOE, 0, 0, BOOL | DUP}, ++ {"crtkill", LOCAL, ECHOKE, 0, 0, BOOL | DUP}, ++ {"ctlecho", LOCAL, ECHOCTL, 0, 0, BOOL | DUP}, ++ {"echo", LOCAL, ECHO, 0, 0, BOOL | SANE}, ++ {"echoctl", LOCAL, ECHOCTL, 0, 0, BOOL | SANE | CRT | DEC}, ++ {"echoe", LOCAL, ECHOE, 0, 0, BOOL | SANE | CRT | DEC}, ++ {"echok", LOCAL, ECHOK, 0, 0, BOOL | SANE}, ++ {"echoke", LOCAL, ECHOKE, 0, 0, BOOL | SANE | CRT | DEC}, ++ {"echonl", LOCAL, ECHONL, 0, 0, BOOL | INSANE}, ++ {"echoprt", LOCAL, ECHOPRT, 0, 0, BOOL | INSANE}, ++ {"extproc", LOCAL, EXTPROC, 0, 0, BOOL | INSANE}, ++ {"flusho", LOCAL, FLUSHO, 0, 0, BOOL | INSANE}, ++ {"icanon", LOCAL, ICANON, 0, 0, BOOL | SANE | CBREAK | COOKED}, ++ {"iexten", LOCAL, IEXTEN, 0, 0, BOOL | SANE}, ++ {"isig", LOCAL, ISIG, 0, 0, BOOL | SANE | COOKED}, ++ {"noflsh", LOCAL, NOFLSH, 0, 0, BOOL | INSANE}, ++ {"prterase", LOCAL, ECHOPRT, 0, 0, BOOL | DUP}, ++ {"tostop", LOCAL, TOSTOP, 0, 0, BOOL | INSANE}, ++ {"xcase", LOCAL, XCASE, 0, 0, BOOL | INSANE | LCASE}, ++ ++ {"cbreak", COMB, 0, CBREAK, 0, BOOL | DUP}, ++ {"cooked", COMB, COOKED, 0, cooked, BOOL | DUP}, ++ {"crt", COMB, CRT, 0, 0, DUP}, ++ {"dec", COMB, DEC, DECCTLQ, dec, DUP}, ++ {"decctlq", COMB, 0, DECCTLQ, 0, BOOL | DUP}, ++ {"ek", COMB, 0, 0, ek, DUP}, ++ {"evenp", COMB, 0, 0, evenp, BOOL | DUP}, ++ {"LCASE", COMB, LCASE, 0, 0, BOOL | DUP}, ++ {"lcase", COMB, LCASE, 0, 0, BOOL | DUP}, ++ {"litout", COMB, 0, LITOUT, pass8, BOOL | DUP}, ++ {"nl", COMB, 0, NL, nl, BOOL | DUP}, ++ {"oddp", COMB, 0, 0, oddp, BOOL | DUP}, ++ {"parity", COMB, 0, 0, evenp, BOOL | DUP}, ++ {"pass8", COMB, 0, PASS8, pass8, BOOL | DUP}, ++ {"raw", COMB, 0, COOKED, raw, BOOL | DUP}, ++ {"sane", COMB, SANE, INSANE, sane, DUP}, ++ {"tabs", COMB, 0, 0, tabs, BOOL | DUP}, ++ ++ {"size", SPEC, 0, 0, size, DUP}, ++ {"speed", SPEC, 0, 0, speed, DUP}, ++ {"drain", SPEC, 0, 0, drain, BOOL | DUP}, ++ ++ {0, 0, 0, 0, 0, 0} ++}; ++ ++static const struct key keys[] = { ++ {"discard", VDISCARD, CDISCARD}, ++ {"eof", VEOF, CEOF}, ++ {"eol", VEOL, CEOL}, ++ {"eol2", VEOL2, _POSIX_VDISABLE}, ++ {"erase", VERASE, CERASE}, ++ {"intr", VINTR, CINTR}, ++ {"kill", VKILL, CKILL}, ++ {"lnext", VLNEXT, CLNEXT}, ++ {"quit", VQUIT, CQUIT}, ++ {"rprnt", VREPRINT, CRPRNT}, ++ {"start", VSTART, CSTART}, ++ {"stop", VSTOP, CSTOP}, ++ {"susp", VSUSP, CSUSP}, ++ {"swtch", VSWTC, _POSIX_VDISABLE}, ++ {"werase", VWERASE, CWERASE}, ++ {0, 0, 0} ++}; ++ ++static const struct intvalued ints[] = { ++ {"cols", cols}, ++ {"columns", cols}, ++ {"line", line}, ++ {"min", min}, ++ {"rows", rows}, ++ {"time", stime}, ++ {"ispeed", ispeed}, ++ {"ospeed", ospeed}, ++ {0, 0} ++}; ++ ++#define B(baud) {#baud, B##baud} ++static const struct speed speeds[] = { ++ B(0), B(50), B(75), B(110), B(134), B(150), B(200), B(300), ++ B(600), B(1200), B(1800), B(2400), B(4800), B(9600), B(19200), B(38400), ++ B(57600), B(115200), B(230400), B(460800), B(500000), B(576000), B(921600), B(1000000), ++ B(1152000), B(1500000), B(2000000), B(2500000), B(3000000), B(3500000), B(4000000), ++ {"134.5", B134}, ++ {"exta", B19200}, ++ {"extb", B38400}, ++ {0, 0} ++}; ++#undef B ++ ++static void ++sane(int unset, struct termios *m) ++{ ++ const struct key *op = keys; ++ for (; op->op; op++) ++ m->c_cc[op->index] = op->sanevalue; ++ m->c_cc[VMIN] = 1; ++ m->c_cc[VTIME] = 0; ++ (void) unset; ++} ++ ++static int ++isxnumber(char* str) ++{ ++ if (!*str) ++ return 0; ++ for (; *str; str++) ++ if (!isxdigit(*str)) ++ return 0; ++ return 1; ++} ++ ++static void ++decodehex(char *dest, char* src) ++{ ++ while (*src) { ++ char hi = *src++; ++ char lo = *src++; ++ hi = (hi & 15) + 9 * !isdigit(hi); ++ lo = (lo & 15) + 9 * !isdigit(lo); ++ *dest++ = (hi << 4) | lo; ++ } ++} ++ ++static void ++setwinsize(long y, long x) ++{ ++ struct winsize winsize; ++ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &winsize)) ++ eprintf("TIOCGWINSZ <stdin>:"); ++ if (y >= 0) ++ winsize.ws_row = y; ++ if (x >= 0) ++ winsize.ws_col = x; ++ if (ioctl(STDIN_FILENO, TIOCSWINSZ, &winsize)) ++ eprintf("TIOCSWINSZ <stdin>:"); ++} ++ ++static void ++setoperand_mode(int unset, const struct mode *op, struct termios *mode) ++{ ++ tcflag_t *bitsp = 0; ++ ++ switch (op->type) { ++ case CTRL: bitsp = &mode->c_cflag; break; ++ case IN: bitsp = &mode->c_iflag; break; ++ case OUT: bitsp = &mode->c_oflag; break; ++ case LOCAL: bitsp = &mode->c_lflag; break; ++ case SPEC: break; ++ default: abort(); ++ } ++ ++ if (bitsp) { ++ *bitsp &= ~op->clear; ++ if (!unset) ++ *bitsp |= op->set; ++ else ++ *bitsp &= ~op->set; ++ } ++ ++ if (op->fun) ++ op->fun(unset, mode); ++} ++ ++static int ++parseoperand_mode(char *arg, struct termios *mode) ++{ ++ const struct mode *op = modes; ++ const struct mode *op_proper; ++ int unset = *arg == '-'; ++ int flags_set, flags_unset; ++ ++ arg += unset; ++ while (op->op && strcmp(arg, op->op)) ++ op++; ++ if (!op->op) ++ return -1; ++ if (unset && !(op->flags & BOOL)) ++ return -1; ++ ++ switch (op->type) { ++ case CTRL: ++ case IN: ++ case OUT: ++ case LOCAL: ++ case SPEC: ++ setoperand_mode(unset, op, mode); ++ return 0; ++ case COMB: ++ break; ++ default: ++ abort(); ++ } ++ ++ flags_set = (int)(op->set); ++ flags_unset = (int)(op->clear); ++ op_proper = op; ++ ++ if (flags_unset || flags_set) { ++ for (op = modes; op->op; op++) { ++ if (op->type == COMB) ++ continue; ++ if (flags_unset && (op->flags & flags_unset)) ++ setoperand_mode(!unset, op, mode); ++ if (flags_set && (op->flags & flags_set)) ++ setoperand_mode(unset, op, mode); ++ } ++ } ++ ++ if (op_proper->fun) ++ op_proper->fun(unset, mode); ++ ++ return 0; ++} ++ ++static long long ++estrtonum_radix(const char *numstr, long long minval, long long maxval, int radix) ++{ ++ long long ll = 0; ++ char *ep; ++ errno = 0; ++ ll = strtoll(numstr, &ep, radix); ++ if (numstr == ep || *ep != '\0') ++ eprintf("strtoll %s: invalid\n", numstr); ++ else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) ++ eprintf("strtoll %s: too small\n", numstr); ++ else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) ++ eprintf("strtoll %s: too large\n", numstr); ++ return ll; ++} ++ ++static int ++parseoperand_key(char *arg0, char *arg1, struct termios *mode) ++{ ++ const struct key *op = keys; ++ cc_t value; ++ ++ while (op->op && strcmp(arg0, op->op)) ++ op++; ++ if (!op->op) ++ return -1; ++ ++ if (!arg1) ++ eprintf("missing argument for operand: %s\n", arg0); ++ ++ if (!strcmp(arg1, "^-") || !strcmp(arg1, "undef")) ++ value = _POSIX_VDISABLE; ++ else if (!strcmp(arg1, "^?")) ++ value = 127; ++ else if (!arg1[0] || !arg1[1]) ++ value = arg1[0]; ++ else if (arg1[0] == '^') ++ value = (cc_t)(arg1[1]) & ~0x60; ++ else if (strstr(arg1, "0x") == arg1) ++ value = estrtonum_radix(arg1 + 2, 0, CC_MAX, 16); ++ else if (arg1[0] == '0' && arg1[1]) ++ value = estrtonum_radix(arg1 + 1, 0, CC_MAX, 8); ++ else ++ value = estrtonum_radix(arg1 + 0, 0, CC_MAX, 10); ++ ++ mode->c_cc[op->index] = value; ++ return 0; ++} ++ ++static int ++parseoperand_int(char *arg0, char *arg1, struct termios *mode) ++{ ++ const struct intvalued *op = ints; ++ ++ while (op->op && strcmp(arg0, op->op)) ++ op++; ++ if (!op->op) ++ return -1; ++ ++ if (!arg1) ++ eprintf("missing argument for operand: %s\n", arg0); ++ ++ op->fun(arg1, mode); ++ return 0; ++} ++ ++static const char * ++baudtostr(speed_t baud) ++{ ++ const struct speed *speed = speeds; ++ while (speed->str && speed->speed != baud) ++ speed++; ++ return speed->str ? speed->str : "0"; ++} ++ ++static int ++parsespeed(char *arg, struct speed *ret) ++{ ++ const struct speed *speed = speeds; ++ while (speed->str && strcmp(arg, speed->str)) ++ speed++; ++ if (!speed->str) ++ return -1; ++ *ret = *speed; ++ return 0; ++} ++ ++static void ++eparsespeed(char *arg, struct speed *ret) ++{ ++ if (parsespeed(arg, ret)) ++ eprintf("invalid speed parameter: %s\n", arg); ++} ++ ++static void ++ispeed(char *arg, struct termios *m) ++{ ++ struct speed speed; ++ eparsespeed(arg, &speed); ++ if (cfsetispeed(m, speed.speed)) ++ eprintf("cfsetispeed %s:", speed.str); ++} ++ ++static void ++ospeed(char *arg, struct termios *m) ++{ ++ struct speed speed; ++ eparsespeed(arg, &speed); ++ if (cfsetospeed(m, speed.speed)) ++ eprintf("cfsetospeed %s:", speed.str); ++} ++ ++static void ++printtoken(const char *fmt, ...) ++{ ++ static size_t width = 0; ++ static size_t pos = 0; ++ static char buf[BUFSIZ]; ++ va_list ap; ++ int len; ++ ++ if (!width) { ++ struct winsize winsize; ++ if (!ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize)) ++ if (winsize.ws_col > 40) ++ width = winsize.ws_col; ++ if (!width) ++ width = SIZE_MAX; ++ } ++ ++ if (!strcmp(fmt, "\n")) { ++ if (pos) ++ printf("\n"); ++ pos = 0; ++ return; ++ } ++ ++ va_start(ap, fmt); ++ len = vsnprintf(buf, sizeof(buf), fmt, ap); ++ va_end(ap); ++ if (len < 0 || (size_t)len >= sizeof(buf)) ++ eprintf("vsnprintf:"); ++ ++ if (pos + !!pos + len > width) { ++ printf("\n"); ++ pos = 0; ++ } else if (pos) { ++ printf(" "); ++ pos++; ++ } ++ ++ printf("%s", buf); ++ pos += len; ++} ++ ++static const char* ++keytostr(cc_t key) ++{ ++ static char buf[5]; ++ int r; ++ if (key == _POSIX_VDISABLE) ++ return "undef"; ++ else if (key < (cc_t)' ') ++ r = snprintf(buf, sizeof(buf), "^%c", key + '@'); ++ else if (key < 127) ++ r = snprintf(buf, sizeof(buf), "%c", key); ++ else if (key == 127) ++ r = snprintf(buf, sizeof(buf), "^?"); ++ else if (key < 128 + ' ') ++ r = snprintf(buf, sizeof(buf), "M-^%c", key - 128 + '@'); ++ else if (key == 128 + 127) ++ r = snprintf(buf, sizeof(buf), "M-^?"); ++ else ++ r = snprintf(buf, sizeof(buf), "M-%c", key - 128); ++ if (r < 0 || (size_t)r >= sizeof(buf)) ++ eprintf("snprintf:"); ++ return buf; ++} ++ ++static void ++displaysettings(struct termios *m, int all) ++{ ++ const struct key *kbd = keys; ++ const struct mode *mod = modes; ++ struct winsize winsize; ++ speed_t in, out; ++ tcflag_t *bitsp, mask; ++ ++ in = cfgetispeed(m); ++ out = cfgetospeed(m); ++ if (!in || in == out) { ++ if (all || out != B38400) ++ printtoken("speed %s baud;", baudtostr(out)); ++ } else { ++ printtoken("ispeed %s baud;", baudtostr(in)); ++ printtoken("ospeed %s baud;", baudtostr(out)); ++ } ++ ++ if (all) { ++ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &winsize)) ++ eprintf("TIOCGWINSZ <stdin>:"); ++ printtoken("rows %u;", winsize.ws_row); ++ printtoken("columns %u;", winsize.ws_col); ++ } ++ printtoken("\n"); ++ ++ if (all || m->c_line != 0) ++ printtoken("line = %u;", (unsigned long)(m->c_line)); ++ if (all || (m->c_cc[VMIN] != 1 && !(m->c_lflag & ICANON))) ++ printtoken("min = %u;", (unsigned long)(m->c_cc[VMIN])); ++ if (all || (m->c_cc[VTIME] != 0 && !(m->c_lflag & ICANON))) ++ printtoken("time = %u;", (unsigned long)(m->c_cc[VTIME])); ++ printtoken("\n"); ++ ++ for (; kbd->op; kbd++) ++ if (all || m->c_cc[kbd->index] != kbd->sanevalue) ++ printtoken("%s = %s;", kbd->op, keytostr(m->c_cc[kbd->index])); ++ printtoken("\n"); ++ ++ for (; mod->op; mod++) { ++ switch (mod->type) { ++ case CTRL: bitsp = &m->c_cflag; break; ++ case IN: bitsp = &m->c_iflag; break; ++ case OUT: bitsp = &m->c_oflag; break; ++ case LOCAL: bitsp = &m->c_lflag; break; ++ default: bitsp = 0; break; ++ } ++ if (!bitsp || (mod->flags & DUP)) ++ continue; ++ mask = mod->clear ? mod->clear : mod->set; ++ if ((*bitsp & mask) == mod->set) { ++ if (all || (mod->flags & INSANE) || !(mod->flags & SANE)) ++ printtoken("%s", mod->op); ++ } ++ else if (mod->flags & BOOL) { ++ if (all || (mod->flags & SANE) || !(mod->flags & INSANE)) ++ printtoken("-%s", mod->op); ++ } ++ } ++ printtoken("\n"); ++} ++ ++static void ++usage(void) ++{ ++ eprintf("usage: %s [-a | -g] [operand ...]\n", argv0); ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++ struct termios mode; ++ struct termios mode2; ++ struct winsize winsize; ++ struct speed speed; ++ int aflag = 0; ++ int gflag = 0; ++ size_t n; ++ unsigned char *buf; ++ char *p; ++ speed_t in, out; ++ ++ for (argv0 = *argv++, argc--; argc; argv++, argc--) { ++ if (!strcmp(*argv, "-ag") || !strcmp(*argv, "-ga")) { ++ aflag = gflag = 1; ++ } else if (!strcmp(*argv, "-g")) { ++ gflag = 1; ++ } else if (!strcmp(*argv, "-a")) { ++ aflag = 1; ++ } else if (!strcmp(*argv, "--")) { ++ argv++, argc--; ++ break; ++ } else { ++ break; ++ } ++ } ++ ++ if (aflag && gflag) ++ usage(); ++ ++ memset(&mode, 0, sizeof(mode)); ++ if (tcgetattr(STDIN_FILENO, &mode)) ++ eprintf("tcgetattr <stdin>:"); ++ memcpy(&mode2, &mode, sizeof(mode)); ++ ++ for (; *argv; argv++) { ++ if (**argv == '=') { ++ p = *argv + 1; ++ if (strlen(p) != sizeof(mode) * 2 || !isxnumber(p)) ++ goto invalid; ++ decodehex((char *)&mode, p); ++ } else if (!parseoperand_mode(*argv, &mode)) { ++ /* do nothing. */ ++ } else if (!parseoperand_key(argv[0], argv[1], &mode)) { ++ argv++; ++ } else if (!parseoperand_int(argv[0], argv[1], &mode)) { ++ argv++; ++ } else if (!parsespeed(*argv, &speed)) { ++ if (cfsetispeed(&mode, speed.speed)) ++ eprintf("cfsetispeed %s:", speed.str); ++ if (cfsetospeed(&mode, speed.speed)) ++ eprintf("cfsetospeed %s:", speed.str); ++ } else { ++ goto invalid; ++ } ++ } ++ ++ if (memcmp(&mode, &mode2, sizeof(mode))) { ++ memset(&mode2, 0, sizeof(mode2)); ++ if (tcsetattr(STDIN_FILENO, drain_requested ? TCSADRAIN : TCSANOW, &mode)) ++ eprintf("tcsetattr <stdin>:"); ++ if (tcgetattr(STDIN_FILENO, &mode2)) ++ eprintf("tcgetattr <stdin>:"); ++ if (memcmp(&mode, &mode2, sizeof(mode))) ++ eprintf("tcsetattr <stdin>: unable to apply all operands\n"); ++ } ++ ++ if (gflag) { ++ buf = (unsigned char *)&mode; ++ printf("="); ++ for (n = sizeof(mode); n--; buf++) ++ printf("%02x", *buf); ++ printf("\n"); ++ } ++ ++ if (output_size_requested) { ++ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &winsize)) ++ eprintf("TIOCGWINSZ <stdin>:"); ++ printf("%u %u\n", winsize.ws_row, winsize.ws_col); ++ } ++ ++ if (output_speed_requested) { ++ in = cfgetispeed(&mode); ++ out = cfgetospeed(&mode); ++ if (!in || in == out) ++ printf("%s\n", baudtostr(out)); ++ else ++ printf("%s %s\n", baudtostr(in), baudtostr(out)); ++ } ++ ++ if ((aflag || !argc) && !gflag) ++ displaysettings(&mode, aflag); ++ ++ return 0; ++ ++invalid: ++ eprintf("invalid operand: %s\n", *argv); ++} +-- +2.8.1 + |
