Re: [PATCH RFC] ldattach: add --iflag command line option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Feb 22, 2010 at 01:00:10PM +0100, Tilman Schmidt wrote:
> Add a command line option '-i' / '--iflag' for setting or clearing
> input flags on the serial device before attaching the line discipline.
> 
> Impact: added functionality
> Signed-off-by: Tilman Schmidt <tilman@xxxxxxx>
> ---
> I would still like to be convinced that this is The Right Thing To Do,
> but meanwhile, here's a first draft at implementing the ability to set
> ICRNL and IGNBRK flags as requested by the PPS people, by saying
> something like:
> 
> 	ldattach --iflag=ICRNL,IGNBRK PPS /dev/ttyS0

 Good idea. Applied with some changes (see below). Thanks.
 
 Note that I did a small refactoring in the ldattach to remove
 duplicate code.
    
    Karel

>From b091b880f963b5181ac09a202bff4e41a38dfbe0 Mon Sep 17 00:00:00 2001
From: Tilman Schmidt <tilman@xxxxxxx>
Date: Mon, 1 Mar 2010 10:45:47 +0100
Subject: [PATCH] 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@xxxxxxxxxx: - 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@xxxxxxx>
Signed-off-by: Karel Zak <kzak@xxxxxxxxxx>
---
 sys-utils/ldattach.8 |   11 ++++++++-
 sys-utils/ldattach.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/sys-utils/ldattach.8 b/sys-utils/ldattach.8
index 3856999..f78ab34 100644
--- a/sys-utils/ldattach.8
+++ b/sys-utils/ldattach.8
@@ -1,6 +1,6 @@
 .\" Copyright 2008 Tilman Schmidt (tilman@xxxxxxx)
 .\" 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)
diff --git a/sys-utils/ldattach.c b/sys-utils/ldattach.c
index e85677c..26cf10a 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);
 
-- 
1.6.6

--
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux