]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
ldattach: add --iflag command line option
authorTilman Schmidt <tilman@imap.cc>
Mon, 1 Mar 2010 09:45:47 +0000 (10:45 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 1 Mar 2010 09:45:47 +0000 (10:45 +0100)
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>
sys-utils/ldattach.8
sys-utils/ldattach.c

index 3856999f0e35e47c6ec5ace7fb5d4579f37239c5..f78ab34cb42d5d43690a218419562edddd01abb4 100644 (file)
@@ -1,6 +1,6 @@
 .\" Copyright 2008 Tilman Schmidt (tilman@imap.cc)
 .\" May be distributed under the GNU General Public License version 2 or later
-.TH LDATTACH 8 "14 January 2008" "Linux 2.6" "Linux Programmer's Manual"
+.TH LDATTACH 8 "14 February 2010" "Linux 2.6" "Linux Programmer's Manual"
 .SH NAME
 ldattach \- attach a line discipline to a serial line
 .SH SYNOPSIS
@@ -8,6 +8,8 @@ ldattach \- attach a line discipline to a serial line
 .RB [ \-dhV78neo12 ]
 .RB [ \-s
 .IR speed ]
+.RB [ \-i
+.IR iflag ]
 .I ldisc device
 .SH DESCRIPTION
 The
@@ -122,6 +124,13 @@ Sets the number of stop bits of the serial line to one.
 .TP
 \fB-2\fP | \fB--twostopbits\fP
 Sets the number of stop bits of the serial line to two.
+.TP
+\fB-i\fP \fIvalue\fP | \fB--iflag\fP [\fB-\fP]\fIvalue\fP{,...}
+Sets the specified bits in the c_iflag word of the serial line.
+\fIValue\fP may be a number or a symbolic name.
+If \fIvalue\fP is prefixed by a minus sign, clear the specified bits instead.
+Several comma separated \fIvalue\fPs may be given in order to
+set and clear multiple bits.
 .SH "SEE ALSO"
 .BR inputattach (1),
 .BR ttys (4)
index e85677c899f32d1fae6cbf3e15ceb0c4620948ce..26cf10a70215cb7ebb7128b91b0b4bc0942aa7a5 100644 (file)
@@ -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);