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>
This commit is contained in:
parent
7b549aff71
commit
b091b880f9
|
@ -1,6 +1,6 @@
|
||||||
.\" Copyright 2008 Tilman Schmidt (tilman@imap.cc)
|
.\" Copyright 2008 Tilman Schmidt (tilman@imap.cc)
|
||||||
.\" May be distributed under the GNU General Public License version 2 or later
|
.\" 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
|
.SH NAME
|
||||||
ldattach \- attach a line discipline to a serial line
|
ldattach \- attach a line discipline to a serial line
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -8,6 +8,8 @@ ldattach \- attach a line discipline to a serial line
|
||||||
.RB [ \-dhV78neo12 ]
|
.RB [ \-dhV78neo12 ]
|
||||||
.RB [ \-s
|
.RB [ \-s
|
||||||
.IR speed ]
|
.IR speed ]
|
||||||
|
.RB [ \-i
|
||||||
|
.IR iflag ]
|
||||||
.I ldisc device
|
.I ldisc device
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
@ -122,6 +124,13 @@ Sets the number of stop bits of the serial line to one.
|
||||||
.TP
|
.TP
|
||||||
\fB-2\fP | \fB--twostopbits\fP
|
\fB-2\fP | \fB--twostopbits\fP
|
||||||
Sets the number of stop bits of the serial line to two.
|
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"
|
.SH "SEE ALSO"
|
||||||
.BR inputattach (1),
|
.BR inputattach (1),
|
||||||
.BR ttys (4)
|
.BR ttys (4)
|
||||||
|
|
|
@ -76,6 +76,27 @@ static const struct ld_table ld_discs[] =
|
||||||
{ NULL, 0 }
|
{ 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)
|
static int lookup_table(const struct ld_table *tab, const char *str)
|
||||||
{
|
{
|
||||||
const struct ld_table *t;
|
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)
|
static void __attribute__((__noreturn__)) usage(int exitcode)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("\nUsage: %s [ -dhV78neo12 ] [ -s <speed> ] <ldisc> <device>\n"),
|
_("\nUsage: %s [ -dhV78neo12 ] [ -s <speed> ] [ -i [-]<iflag> ] <ldisc> <device>\n"),
|
||||||
progname);
|
progname);
|
||||||
fputs(_("\nKnown <ldisc> names:\n"), stderr);
|
fputs(_("\nKnown <ldisc> names:\n"), stderr);
|
||||||
print_table(stderr, ld_discs);
|
print_table(stderr, ld_discs);
|
||||||
|
fputs(_("\nKnown <iflag> names:\n"), stderr);
|
||||||
|
print_table(stderr, ld_iflags);
|
||||||
exit(exitcode);
|
exit(exitcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +184,7 @@ int main(int argc, char **argv)
|
||||||
int tty_fd;
|
int tty_fd;
|
||||||
struct termios ts;
|
struct termios ts;
|
||||||
int speed = 0, bits = '-', parity = '-', stop = '-';
|
int speed = 0, bits = '-', parity = '-', stop = '-';
|
||||||
|
int set_iflag = 0, clr_iflag = 0;
|
||||||
int ldisc;
|
int ldisc;
|
||||||
int optc;
|
int optc;
|
||||||
char *end;
|
char *end;
|
||||||
|
@ -151,6 +198,7 @@ int main(int argc, char **argv)
|
||||||
{"oddparity", 0, 0, 'o'},
|
{"oddparity", 0, 0, 'o'},
|
||||||
{"onestopbit", 0, 0, '1'},
|
{"onestopbit", 0, 0, '1'},
|
||||||
{"twostopbits", 0, 0, '2'},
|
{"twostopbits", 0, 0, '2'},
|
||||||
|
{"iflag", 1, 0, 'i'},
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
{"version", 0, 0, 'V'},
|
{"version", 0, 0, 'V'},
|
||||||
{"debug", 0, 0, 'd'},
|
{"debug", 0, 0, 'd'},
|
||||||
|
@ -166,7 +214,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
usage(EXIT_SUCCESS);
|
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) {
|
switch (optc) {
|
||||||
case 'd':
|
case 'd':
|
||||||
debug++;
|
debug++;
|
||||||
|
@ -189,6 +237,9 @@ int main(int argc, char **argv)
|
||||||
if (*end || speed <= 0)
|
if (*end || speed <= 0)
|
||||||
errx(EXIT_FAILURE, _("invalid speed: %s"), optarg);
|
errx(EXIT_FAILURE, _("invalid speed: %s"), optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
parse_iflag(optarg, &set_iflag, &clr_iflag);
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
printf(_("ldattach from %s\n"), PACKAGE_STRING);
|
printf(_("ldattach from %s\n"), PACKAGE_STRING);
|
||||||
break;
|
break;
|
||||||
|
@ -255,6 +306,10 @@ int main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ts.c_cflag |= CREAD; /* just to be on the safe side */
|
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)
|
if (tcsetattr(tty_fd, TCSAFLUSH, &ts) < 0)
|
||||||
err(EXIT_FAILURE, _("cannot set terminal attributes for %s"), dev);
|
err(EXIT_FAILURE, _("cannot set terminal attributes for %s"), dev);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue