diff options
author | Tilman Schmidt | 2010-03-01 10:45:47 +0100 |
---|---|---|
committer | Karel Zak | 2010-03-01 10:45:47 +0100 |
commit | b091b880f963b5181ac09a202bff4e41a38dfbe0 (patch) | |
tree | 1416642206f667c004eb2be4893a460b2c846ca7 /sys-utils/ldattach.c | |
parent | ldattach: create a generic functions for name=value tables (diff) | |
download | kernel-qcow2-util-linux-b091b880f963b5181ac09a202bff4e41a38dfbe0.tar.gz kernel-qcow2-util-linux-b091b880f963b5181ac09a202bff4e41a38dfbe0.tar.xz kernel-qcow2-util-linux-b091b880f963b5181ac09a202bff4e41a38dfbe0.zip |
ldattach: add --iflag command line option
Add a command line option '-i' / '--iflag' for setting or clearing
input flags on the serial device before attaching the line discipline.
[kzak@redhat.com: - use generic functions for work with iflags table
- add list of iflags to usage/help output
- move iflags parsing to separate function]
Impact: added functionality
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/ldattach.c')
-rw-r--r-- | sys-utils/ldattach.c | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/sys-utils/ldattach.c b/sys-utils/ldattach.c index e85677c89..26cf10a70 100644 --- a/sys-utils/ldattach.c +++ b/sys-utils/ldattach.c @@ -76,6 +76,27 @@ static const struct ld_table ld_discs[] = { NULL, 0 } }; +/* known c_iflag names */ +static const struct ld_table ld_iflags[] = +{ + { "IGNBRK", IGNBRK }, + { "BRKINT", BRKINT }, + { "IGNPAR", IGNPAR }, + { "PARMRK", PARMRK }, + { "INPCK", INPCK }, + { "ISTRIP", ISTRIP }, + { "INLCR", INLCR }, + { "IGNCR", IGNCR }, + { "ICRNL", ICRNL }, + { "IUCLC", IUCLC }, + { "IXON", IXON }, + { "IXANY", IXANY }, + { "IXOFF", IXOFF }, + { "IMAXBEL", IMAXBEL }, + { "IUTF8", IUTF8 }, + { NULL, 0 } +}; + static int lookup_table(const struct ld_table *tab, const char *str) { const struct ld_table *t; @@ -98,14 +119,39 @@ static void print_table(FILE *out, const struct ld_table *tab) } } +static int parse_iflag(char *str, int *set_iflag, int *clr_iflag) +{ + int iflag; + char *s, *end; + + for (s = strtok(str, ","); s != NULL; s = strtok(NULL, ",")) { + if (*s == '-') + s++; + if ((iflag = lookup_table(ld_iflags, s)) < 0) { + iflag = strtol(s, &end, 0); + if (*end || iflag < 0) + errx(EXIT_FAILURE, _("invalid iflag: %s"), s); + } + if (s > str && *(s - 1) == '-') + *clr_iflag |= iflag; + else + *set_iflag |= iflag; + } + + dbg("iflag (set/clear): %d/%d", *set_iflag, *clr_iflag); + return 0; +} + + static void __attribute__((__noreturn__)) usage(int exitcode) { fprintf(stderr, - _("\nUsage: %s [ -dhV78neo12 ] [ -s <speed> ] <ldisc> <device>\n"), + _("\nUsage: %s [ -dhV78neo12 ] [ -s <speed> ] [ -i [-]<iflag> ] <ldisc> <device>\n"), progname); fputs(_("\nKnown <ldisc> names:\n"), stderr); print_table(stderr, ld_discs); - + fputs(_("\nKnown <iflag> names:\n"), stderr); + print_table(stderr, ld_iflags); exit(exitcode); } @@ -138,6 +184,7 @@ int main(int argc, char **argv) int tty_fd; struct termios ts; int speed = 0, bits = '-', parity = '-', stop = '-'; + int set_iflag = 0, clr_iflag = 0; int ldisc; int optc; char *end; @@ -151,6 +198,7 @@ int main(int argc, char **argv) {"oddparity", 0, 0, 'o'}, {"onestopbit", 0, 0, '1'}, {"twostopbits", 0, 0, '2'}, + {"iflag", 1, 0, 'i'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"debug", 0, 0, 'd'}, @@ -166,7 +214,7 @@ int main(int argc, char **argv) if (argc == 0) usage(EXIT_SUCCESS); - while ((optc = getopt_long(argc, argv, "dhV78neo12s:", opttbl, NULL)) >= 0) { + while ((optc = getopt_long(argc, argv, "dhV78neo12s:i:", opttbl, NULL)) >= 0) { switch (optc) { case 'd': debug++; @@ -189,6 +237,9 @@ int main(int argc, char **argv) if (*end || speed <= 0) errx(EXIT_FAILURE, _("invalid speed: %s"), optarg); break; + case 'i': + parse_iflag(optarg, &set_iflag, &clr_iflag); + break; case 'V': printf(_("ldattach from %s\n"), PACKAGE_STRING); break; @@ -255,6 +306,10 @@ int main(int argc, char **argv) break; } ts.c_cflag |= CREAD; /* just to be on the safe side */ + + ts.c_iflag |= set_iflag; + ts.c_iflag &= ~clr_iflag; + if (tcsetattr(tty_fd, TCSAFLUSH, &ts) < 0) err(EXIT_FAILURE, _("cannot set terminal attributes for %s"), dev); |