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 CCing everybody involved in that discussion so far. Please comment. Thanks, Tilman sys-utils/ldattach.8 | 11 ++++++++- sys-utils/ldattach.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 3 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 8064c7b..810b322 100644 --- a/sys-utils/ldattach.c +++ b/sys-utils/ldattach.c @@ -85,12 +85,43 @@ static int lookup_ld(const char *s) return -1; } +/* known c_iflag names */ +static const struct iflag_entry { const char *s; int v; } +iflag_table[] = { + { "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 }, +}; + +/* look up iflag name */ +static int lookup_iflag(const char *s) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(iflag_table); i++) + if (!strcasecmp(iflag_table[i].s, s)) + return iflag_table[i].v; + return -1; +} + static void __attribute__((__noreturn__)) usage(int exitcode) { size_t i; 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); for (i = 0; i < ARRAY_SIZE(ld_table); i++) @@ -127,6 +158,8 @@ 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 iflag; int ldisc; int optc; char *end; @@ -140,6 +173,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'}, @@ -156,7 +190,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++; @@ -179,6 +213,25 @@ int main(int argc, char **argv) if (*end || speed <= 0) errx(EXIT_FAILURE, _("invalid speed: %s"), optarg); break; + case 'i': + for (char *s = strtok(optarg, ","); s != NULL; s = strtok(NULL, ",")) { + if (s[0] == '-') { + if ((iflag = lookup_iflag(s+1)) < 0) { + iflag = strtol(s+1, &end, 0); + if (*end || iflag < 0) + errx(EXIT_FAILURE, _("invalid iflag: %s"), s+1); + } + clr_iflag |= iflag; + } else { + if ((iflag = lookup_iflag(s)) < 0) { + iflag = strtol(s, &end, 0); + if (*end || iflag < 0) + errx(EXIT_FAILURE, _("invalid iflag: %s"), s); + } + set_iflag |= iflag; + } + } + break; case 'V': printf(_("ldattach from %s\n"), PACKAGE_STRING); break; @@ -244,6 +297,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.5.3.298.g39add -- 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