.\" 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
.RB [ \-dhV78neo12 ]
.RB [ \-s
.IR speed ]
+.RB [ \-i
+.IR iflag ]
.I ldisc device
.SH DESCRIPTION
The
.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)
{ 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;
}
}
+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);
}
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;
{"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'},
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++;
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;
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);