summaryrefslogtreecommitdiff
path: root/sys-utils
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2010-03-01 10:45:47 +0100
committerKarel Zak <kzak@redhat.com>2010-03-01 10:45:47 +0100
commitb091b880f963b5181ac09a202bff4e41a38dfbe0 (patch)
tree1416642206f667c004eb2be4893a460b2c846ca7 /sys-utils
parent7b549aff71c0e3f9591f743df4f680a16bb537d7 (diff)
downloadutil-linux-old-b091b880f963b5181ac09a202bff4e41a38dfbe0.tar.gz
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')
-rw-r--r--sys-utils/ldattach.811
-rw-r--r--sys-utils/ldattach.c61
2 files changed, 68 insertions, 4 deletions
diff --git a/sys-utils/ldattach.8 b/sys-utils/ldattach.8
index 3856999f..f78ab34c 100644
--- a/sys-utils/ldattach.8
+++ b/sys-utils/ldattach.8
@@ -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)
diff --git a/sys-utils/ldattach.c b/sys-utils/ldattach.c
index e85677c8..26cf10a7 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);