mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
Apply termios settings in a single system call (for ispeed,ospeed)
This commit is contained in:
parent
b5be579187
commit
ebbe704423
5 changed files with 255 additions and 249 deletions
6
CHANGES
6
CHANGES
|
@ -31,6 +31,12 @@ corrections:
|
||||||
Test: UDP6MULTICAST_UNIDIR
|
Test: UDP6MULTICAST_UNIDIR
|
||||||
Thanks to Angus Gratton for sending a patch.
|
Thanks to Angus Gratton for sending a patch.
|
||||||
|
|
||||||
|
Setting ispeed and ospeed failed for some serial devices because the
|
||||||
|
two settings were applied with two different get/set cycles, Thanks to
|
||||||
|
Alexandre Fenyo for providing an initial patch.
|
||||||
|
However, the actual fix is part of a conceptual change of the termios
|
||||||
|
module that aims for applying all changes in a single tcsetaddr call.
|
||||||
|
|
||||||
testing:
|
testing:
|
||||||
test.sh: Show a warning when phase-1 (insecure phase) of a security
|
test.sh: Show a warning when phase-1 (insecure phase) of a security
|
||||||
test fails
|
test fails
|
||||||
|
|
|
@ -123,8 +123,8 @@ static int xioopen_readline(int argc, const char *argv[], struct opt *opts,
|
||||||
Read_history(xfd->stream.para.readline.history_file);
|
Read_history(xfd->stream.para.readline.history_file);
|
||||||
}
|
}
|
||||||
#if _WITH_TERMIOS
|
#if _WITH_TERMIOS
|
||||||
xiotermios_clrflag(xfd->stream.fd, 3, ICANON);
|
xiotermios_clrflag(xfd->stream.fd, 3, ICANON|ECHO);
|
||||||
xiotermios_clrflag(xfd->stream.fd, 3, ECHO);
|
xiotermios_flush(xfd->stream.fd);
|
||||||
#endif /* _WITH_TERMIOS */
|
#endif /* _WITH_TERMIOS */
|
||||||
return _xio_openlate(&xfd->stream, opts);
|
return _xio_openlate(&xfd->stream, opts);
|
||||||
}
|
}
|
||||||
|
@ -174,6 +174,7 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) {
|
||||||
|
|
||||||
#if _WITH_TERMIOS
|
#if _WITH_TERMIOS
|
||||||
xiotermios_setflag(pipe->fd, 3, ECHO);
|
xiotermios_setflag(pipe->fd, 3, ECHO);
|
||||||
|
xiotermios_flush(pipe->fd);
|
||||||
#endif /* _WITH_TERMIOS */
|
#endif /* _WITH_TERMIOS */
|
||||||
if (pipe->para.readline.prompt || pipe->para.readline.dynprompt) {
|
if (pipe->para.readline.prompt || pipe->para.readline.dynprompt) {
|
||||||
/* we must carriage return, because readline will first print the
|
/* we must carriage return, because readline will first print the
|
||||||
|
@ -201,6 +202,7 @@ ssize_t xioread_readline(struct single *pipe, void *buff, size_t bufsiz) {
|
||||||
}
|
}
|
||||||
#if _WITH_TERMIOS
|
#if _WITH_TERMIOS
|
||||||
xiotermios_clrflag(pipe->fd, 3, ECHO);
|
xiotermios_clrflag(pipe->fd, 3, ECHO);
|
||||||
|
xiotermios_flush(pipe->fd);
|
||||||
#endif /* _WITH_TERMIOS */
|
#endif /* _WITH_TERMIOS */
|
||||||
Add_history(line);
|
Add_history(line);
|
||||||
bytes = strlen(line);
|
bytes = strlen(line);
|
||||||
|
|
242
xio-termios.c
242
xio-termios.c
|
@ -14,6 +14,7 @@
|
||||||
#if WITH_TERMIOS
|
#if WITH_TERMIOS
|
||||||
const struct optdesc opt_tiocsctty={ "tiocsctty", "ctty",OPT_TIOCSCTTY, GROUP_TERMIOS, PH_LATE2, TYPE_BOOL, OFUNC_SPEC };
|
const struct optdesc opt_tiocsctty={ "tiocsctty", "ctty",OPT_TIOCSCTTY, GROUP_TERMIOS, PH_LATE2, TYPE_BOOL, OFUNC_SPEC };
|
||||||
|
|
||||||
|
/* it is important for handling of these options that they have PH_FD */
|
||||||
const struct optdesc opt_brkint = { "brkint", NULL, OPT_BRKINT, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, BRKINT };
|
const struct optdesc opt_brkint = { "brkint", NULL, OPT_BRKINT, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, BRKINT };
|
||||||
const struct optdesc opt_icrnl = { "icrnl", NULL, OPT_ICRNL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, ICRNL };
|
const struct optdesc opt_icrnl = { "icrnl", NULL, OPT_ICRNL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, ICRNL };
|
||||||
const struct optdesc opt_ignbrk = { "ignbrk", NULL, OPT_IGNBRK, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IGNBRK };
|
const struct optdesc opt_ignbrk = { "ignbrk", NULL, OPT_IGNBRK, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IGNBRK };
|
||||||
|
@ -297,42 +298,237 @@ int xiotermiosflag_applyopt(int fd, struct opt *opt) {
|
||||||
|
|
||||||
#endif /* WITH_TERMIOS */
|
#endif /* WITH_TERMIOS */
|
||||||
|
|
||||||
int xiotermios_setflag(int fd, int word, tcflag_t mask) {
|
bool _xiotermios_doit = false; /* _data has been retrieved and manipulated, set it later */
|
||||||
union {
|
union {
|
||||||
struct termios termarg;
|
struct termios termarg;
|
||||||
tcflag_t flags[4];
|
tcflag_t flags[4];
|
||||||
} tdata;
|
#ifdef HAVE_TERMIOS_ISPEED
|
||||||
|
speed_t speeds[sizeof(struct termios)/sizeof(speed_t)];
|
||||||
|
#endif
|
||||||
|
} _xiotermios_data;
|
||||||
|
|
||||||
if (Tcgetattr(fd, &tdata.termarg) < 0) {
|
int xiotermios_setflag(int fd, int word, tcflag_t mask) {
|
||||||
|
if (!_xiotermios_doit) {
|
||||||
|
if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
|
||||||
Error3("tcgetattr(%d, %p): %s",
|
Error3("tcgetattr(%d, %p): %s",
|
||||||
fd, &tdata.termarg, strerror(errno));
|
fd, &_xiotermios_data.termarg, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tdata.flags[word] |= mask;
|
_xiotermios_doit = true;
|
||||||
if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) {
|
}
|
||||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
_xiotermios_data.flags[word] |= mask;
|
||||||
fd, &tdata.termarg, strerror(errno));
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xiotermios_clrflag(int fd, int word, tcflag_t mask) {
|
||||||
|
if (!_xiotermios_doit) {
|
||||||
|
if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
|
||||||
|
Error3("tcgetattr(%d, %p): %s",
|
||||||
|
fd, &_xiotermios_data.termarg, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
_xiotermios_doit = true;
|
||||||
|
}
|
||||||
|
_xiotermios_data.flags[word] &= ~mask;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xiotermios_value(int fd, int word, tcflag_t mask, tcflag_t value) {
|
||||||
|
if (!_xiotermios_doit) {
|
||||||
|
if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
|
||||||
|
Error3("tcgetattr(%d, %p): %s",
|
||||||
|
fd, &_xiotermios_data.termarg, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
_xiotermios_doit = true;
|
||||||
|
}
|
||||||
|
_xiotermios_data.flags[word] &= ~mask;
|
||||||
|
_xiotermios_data.flags[word] |= value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xiotermios_char(int fd, int n, unsigned char c) {
|
||||||
|
if (!_xiotermios_doit) {
|
||||||
|
if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
|
||||||
|
Error3("tcgetattr(%d, %p): %s",
|
||||||
|
fd, &_xiotermios_data.termarg, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
_xiotermios_doit = true;
|
||||||
|
}
|
||||||
|
_xiotermios_data.termarg.c_cc[n] = c;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_TERMIOS_ISPEED
|
||||||
|
int xiotermios_speed(int fd, int n, unsigned int speed) {
|
||||||
|
if (!_xiotermios_doit) {
|
||||||
|
if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
|
||||||
|
Error3("tcgetattr(%d, %p): %s",
|
||||||
|
fd, &_xiotermios_data.termarg, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
_xiotermios_doit = true;
|
||||||
|
}
|
||||||
|
_xiotermios_data.speeds[n] = speed;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_TERMIOS_ISPEED */
|
||||||
|
|
||||||
|
int xiotermios_spec(int fd, int optcode) {
|
||||||
|
if (!_xiotermios_doit) {
|
||||||
|
if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
|
||||||
|
Error3("tcgetattr(%d, %p): %s",
|
||||||
|
fd, &_xiotermios_data.termarg, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
_xiotermios_doit = true;
|
||||||
|
}
|
||||||
|
switch (optcode) {
|
||||||
|
case OPT_RAW:
|
||||||
|
_xiotermios_data.termarg.c_iflag &=
|
||||||
|
~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF
|
||||||
|
#ifdef IUCLC
|
||||||
|
|IUCLC
|
||||||
|
#endif
|
||||||
|
|IXANY|IMAXBEL);
|
||||||
|
_xiotermios_data.termarg.c_iflag |= (0);
|
||||||
|
_xiotermios_data.termarg.c_oflag &= ~(OPOST);
|
||||||
|
_xiotermios_data.termarg.c_oflag |= (0);
|
||||||
|
_xiotermios_data.termarg.c_cflag &= ~(0);
|
||||||
|
_xiotermios_data.termarg.c_cflag |= (0);
|
||||||
|
_xiotermios_data.termarg.c_lflag &= ~(ISIG|ICANON
|
||||||
|
#ifdef XCASE
|
||||||
|
|XCASE
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
_xiotermios_data.termarg.c_lflag |= (0);
|
||||||
|
_xiotermios_data.termarg.c_cc[VMIN] = 1;
|
||||||
|
_xiotermios_data.termarg.c_cc[VTIME] = 0;
|
||||||
|
break;
|
||||||
|
case OPT_TERMIOS_RAWER:
|
||||||
|
_xiotermios_data.termarg.c_iflag = 0;
|
||||||
|
_xiotermios_data.termarg.c_oflag = 0;
|
||||||
|
_xiotermios_data.termarg.c_lflag = 0;
|
||||||
|
_xiotermios_data.termarg.c_cflag = (CS8);
|
||||||
|
_xiotermios_data.termarg.c_cc[VMIN] = 1;
|
||||||
|
_xiotermios_data.termarg.c_cc[VTIME] = 0;
|
||||||
|
break;
|
||||||
|
case OPT_SANE:
|
||||||
|
/* cread -ignbrk brkint -inlcr -igncr icrnl
|
||||||
|
-ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl
|
||||||
|
onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0
|
||||||
|
vt0 ff0 isig icanon iexten echo echoe echok -echonl
|
||||||
|
-noflsh -xcase -tostop -echoprt echoctl echoke, and
|
||||||
|
also sets all special characters to their default
|
||||||
|
values.
|
||||||
|
*/
|
||||||
|
_xiotermios_data.termarg.c_iflag &= ~(IGNBRK|INLCR|IGNCR|IXOFF
|
||||||
|
#ifdef IUCLC
|
||||||
|
|IUCLC
|
||||||
|
#endif
|
||||||
|
|IXANY);
|
||||||
|
_xiotermios_data.termarg.c_iflag |= (BRKINT|ICRNL|IMAXBEL);
|
||||||
|
_xiotermios_data.termarg.c_oflag &= ~(0 /* for canonical reasons */
|
||||||
|
#ifdef OLCUC
|
||||||
|
|OLCUC
|
||||||
|
#endif
|
||||||
|
#ifdef OCRNL
|
||||||
|
|OCRNL
|
||||||
|
#endif
|
||||||
|
#ifdef ONOCR
|
||||||
|
|ONOCR
|
||||||
|
#endif
|
||||||
|
#ifdef ONLRET
|
||||||
|
|ONLRET
|
||||||
|
#endif
|
||||||
|
#ifdef OFILL
|
||||||
|
|OFILL
|
||||||
|
#endif
|
||||||
|
#ifdef OFDEL
|
||||||
|
|OFDEL
|
||||||
|
#endif
|
||||||
|
#ifdef NLDLY
|
||||||
|
|NLDLY
|
||||||
|
#endif
|
||||||
|
#ifdef CRDLY
|
||||||
|
|CRDLY
|
||||||
|
#endif
|
||||||
|
#ifdef TABDLY
|
||||||
|
|TABDLY
|
||||||
|
#endif
|
||||||
|
#ifdef BSDLY
|
||||||
|
|BSDLY
|
||||||
|
#endif
|
||||||
|
#ifdef VTDLY
|
||||||
|
|VTDLY
|
||||||
|
#endif
|
||||||
|
#ifdef FFDLY
|
||||||
|
|FFDLY
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
_xiotermios_data.termarg.c_oflag |= (OPOST|ONLCR
|
||||||
|
#ifdef NL0
|
||||||
|
|NL0
|
||||||
|
#endif
|
||||||
|
#ifdef CR0
|
||||||
|
|CR0
|
||||||
|
#endif
|
||||||
|
#ifdef TAB0
|
||||||
|
|TAB0
|
||||||
|
#endif
|
||||||
|
#ifdef BS0
|
||||||
|
|BS0
|
||||||
|
#endif
|
||||||
|
#ifdef VT0
|
||||||
|
|VT0
|
||||||
|
#endif
|
||||||
|
#ifdef FF0
|
||||||
|
|FF0
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
_xiotermios_data.termarg.c_cflag &= ~(0);
|
||||||
|
_xiotermios_data.termarg.c_cflag |= (CREAD);
|
||||||
|
_xiotermios_data.termarg.c_lflag &= ~(ECHONL|NOFLSH
|
||||||
|
#ifdef XCASE
|
||||||
|
|XCASE
|
||||||
|
#endif
|
||||||
|
|TOSTOP
|
||||||
|
#ifdef ECHOPRT
|
||||||
|
|ECHOPRT
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
_xiotermios_data.termarg.c_lflag |= (ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE);
|
||||||
|
/*! "sets characters to their default values... - which? */
|
||||||
|
break;
|
||||||
|
case OPT_TERMIOS_CFMAKERAW:
|
||||||
|
#if HAVE_CFMAKERAW
|
||||||
|
cfmakeraw(&_xiotermios_data.termarg);
|
||||||
|
#else
|
||||||
|
/* these setting follow the Linux documenation of cfmakeraw */
|
||||||
|
_xiotermios_data.termarg.c_iflag &=
|
||||||
|
~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
||||||
|
_xiotermios_data.termarg.c_oflag &= ~(OPOST);
|
||||||
|
_xiotermios_data.termarg.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
||||||
|
_xiotermios_data.termarg.c_cflag &= ~(CSIZE|PARENB);
|
||||||
|
_xiotermios_data.termarg.c_cflag |= (CS8);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Error("TERMIOS option not handled - internal error?");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xiotermios_clrflag(int fd, int word, tcflag_t mask) {
|
int xiotermios_flush(int fd) {
|
||||||
union {
|
if (_xiotermios_doit) {
|
||||||
struct termios termarg;
|
if (Tcsetattr(fd, TCSADRAIN, &_xiotermios_data.termarg) < 0) {
|
||||||
tcflag_t flags[4];
|
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
||||||
} tdata;
|
fd, &_xiotermios_data.termarg, strerror(errno));
|
||||||
|
|
||||||
if (Tcgetattr(fd, &tdata.termarg) < 0) {
|
|
||||||
Error3("tcgetattr(%d, %p): %s",
|
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tdata.flags[word] &= ~mask;
|
_xiotermios_doit = false;
|
||||||
if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) {
|
|
||||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,13 @@ extern const struct optdesc opt_termios_cfmakeraw;
|
||||||
extern int xiotermios_setflag(int fd, int word, tcflag_t mask);
|
extern int xiotermios_setflag(int fd, int word, tcflag_t mask);
|
||||||
extern int xiotermios_clrflag(int fd, int word, tcflag_t mask);
|
extern int xiotermios_clrflag(int fd, int word, tcflag_t mask);
|
||||||
extern int xiotermiosflag_applyopt(int fd, struct opt *opt);
|
extern int xiotermiosflag_applyopt(int fd, struct opt *opt);
|
||||||
|
extern int xiotermios_value(int fd, int word, tcflag_t mask, tcflag_t value);
|
||||||
|
extern int xiotermios_char(int fd, int n, unsigned char c);
|
||||||
|
#ifdef HAVE_TERMIOS_ISPEED
|
||||||
|
extern int xiotermios_speed(int fd, int n, unsigned int speed);
|
||||||
|
#endif
|
||||||
|
extern int xiotermios_spec(int fd, int optcode);
|
||||||
|
extern int xiotermios_flush(int fd);
|
||||||
#endif /* _WITH_TERMIOS */
|
#endif /* _WITH_TERMIOS */
|
||||||
|
|
||||||
#endif /* !defined(__xio_termios_h_included) */
|
#endif /* !defined(__xio_termios_h_included) */
|
||||||
|
|
229
xioopts.c
229
xioopts.c
|
@ -3509,252 +3509,41 @@ int applyopts(int fd, struct opt *opts, enum e_phase phase) {
|
||||||
|
|
||||||
#if WITH_TERMIOS
|
#if WITH_TERMIOS
|
||||||
} else if (opt->desc->func == OFUNC_TERMIOS_FLAG) {
|
} else if (opt->desc->func == OFUNC_TERMIOS_FLAG) {
|
||||||
#if 0
|
|
||||||
union {
|
|
||||||
struct termios termarg;
|
|
||||||
tcflag_t flags[4];
|
|
||||||
} tdata;
|
|
||||||
if (Tcgetattr(fd, &tdata.termarg) < 0) {
|
|
||||||
Error3("tcgetattr(%d, %p): %s",
|
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
|
||||||
}
|
|
||||||
if (opt->value.u_bool) {
|
|
||||||
tdata.flags[opt->desc->major] |= opt->desc->minor;
|
|
||||||
} else {
|
|
||||||
tdata.flags[opt->desc->major] &= ~opt->desc->minor;
|
|
||||||
}
|
|
||||||
if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) {
|
|
||||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (xiotermiosflag_applyopt(fd, opt) < 0) {
|
if (xiotermiosflag_applyopt(fd, opt) < 0) {
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
} else if (opt->desc->func == OFUNC_TERMIOS_VALUE) {
|
} else if (opt->desc->func == OFUNC_TERMIOS_VALUE) {
|
||||||
union {
|
|
||||||
struct termios termarg;
|
|
||||||
tcflag_t flags[4];
|
|
||||||
} tdata;
|
|
||||||
if (((opt->value.u_uint << opt->desc->arg3) & opt->desc->minor) !=
|
if (((opt->value.u_uint << opt->desc->arg3) & opt->desc->minor) !=
|
||||||
(opt->value.u_uint << opt->desc->arg3)) {
|
(opt->value.u_uint << opt->desc->arg3)) {
|
||||||
Error2("option %s: invalid value %u",
|
Error2("option %s: invalid value %u",
|
||||||
opt->desc->defname, opt->value.u_uint);
|
opt->desc->defname, opt->value.u_uint);
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||||
}
|
}
|
||||||
if (Tcgetattr(fd, &tdata.termarg) < 0) {
|
if (xiotermios_value(fd, opt->desc->major, opt->desc->minor,
|
||||||
Error3("tcgetattr(%d, %p): %s",
|
(opt->value.u_uint << opt->desc->arg3) & opt->desc->minor) < 0) {
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
tdata.flags[opt->desc->major] &= ~opt->desc->minor;
|
|
||||||
tdata.flags[opt->desc->major] |=
|
|
||||||
((opt->value.u_uint << opt->desc->arg3) & opt->desc->minor);
|
|
||||||
if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) {
|
|
||||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (opt->desc->func == OFUNC_TERMIOS_PATTERN) {
|
} else if (opt->desc->func == OFUNC_TERMIOS_PATTERN) {
|
||||||
union {
|
if (xiotermios_value(fd, opt->desc->major, opt->desc->arg3, opt->desc->minor) < 0) {
|
||||||
struct termios termarg;
|
|
||||||
tcflag_t flags[4];
|
|
||||||
} tdata;
|
|
||||||
if (Tcgetattr(fd, &tdata.termarg) < 0) {
|
|
||||||
Error3("tcgetattr(%d, %p): %s",
|
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||||
}
|
}
|
||||||
tdata.flags[opt->desc->major] &= ~opt->desc->arg3;
|
|
||||||
tdata.flags[opt->desc->major] |= opt->desc->minor;
|
|
||||||
if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) {
|
|
||||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR;++opt; continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (opt->desc->func == OFUNC_TERMIOS_CHAR) {
|
} else if (opt->desc->func == OFUNC_TERMIOS_CHAR) {
|
||||||
struct termios termarg;
|
if (xiotermios_char(fd, opt->desc->major, opt->value.u_byte) < 0) {
|
||||||
if (Tcgetattr(fd, &termarg) < 0) {
|
|
||||||
Error3("tcgetattr(%d, %p): %s",
|
|
||||||
fd, &termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
|
||||||
}
|
|
||||||
termarg.c_cc[opt->desc->major] = opt->value.u_byte;
|
|
||||||
if (Tcsetattr(fd, TCSADRAIN, &termarg) < 0) {
|
|
||||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
|
||||||
fd, &termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_ISPEED
|
#ifdef HAVE_TERMIOS_ISPEED
|
||||||
} else if (opt->desc->func == OFUNC_TERMIOS_SPEED) {
|
} else if (opt->desc->func == OFUNC_TERMIOS_SPEED) {
|
||||||
union {
|
if (xiotermios_speed(fd, opt->desc->major, opt->value.u_uint) < 0) {
|
||||||
struct termios termarg;
|
|
||||||
speed_t speeds[sizeof(struct termios)/sizeof(speed_t)];
|
|
||||||
} tdata;
|
|
||||||
if (Tcgetattr(fd, &tdata.termarg) < 0) {
|
|
||||||
Error3("tcgetattr(%d, %p): %s",
|
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
|
||||||
}
|
|
||||||
tdata.speeds[opt->desc->major] = opt->value.u_uint;
|
|
||||||
if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) {
|
|
||||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
|
||||||
fd, &tdata.termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_TERMIOS_ISPEED */
|
#endif /* HAVE_TERMIOS_ISPEED */
|
||||||
|
|
||||||
} else if (opt->desc->func == OFUNC_TERMIOS_SPEC) {
|
} else if (opt->desc->func == OFUNC_TERMIOS_SPEC) {
|
||||||
struct termios termarg;
|
if (xiotermios_spec(fd, opt->desc->optcode) < 0) {
|
||||||
if (Tcgetattr(fd, &termarg) < 0) {
|
|
||||||
Error3("tcgetattr(%d, %p): %s",
|
|
||||||
fd, &termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
|
||||||
}
|
|
||||||
switch (opt->desc->optcode) {
|
|
||||||
case OPT_RAW:
|
|
||||||
termarg.c_iflag &=
|
|
||||||
~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF
|
|
||||||
#ifdef IUCLC
|
|
||||||
|IUCLC
|
|
||||||
#endif
|
|
||||||
|IXANY|IMAXBEL);
|
|
||||||
termarg.c_iflag |= (0);
|
|
||||||
termarg.c_oflag &= ~(OPOST);
|
|
||||||
termarg.c_oflag |= (0);
|
|
||||||
termarg.c_cflag &= ~(0);
|
|
||||||
termarg.c_cflag |= (0);
|
|
||||||
termarg.c_lflag &= ~(ISIG|ICANON
|
|
||||||
#ifdef XCASE
|
|
||||||
|XCASE
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
termarg.c_lflag |= (0);
|
|
||||||
termarg.c_cc[VMIN] = 1;
|
|
||||||
termarg.c_cc[VTIME] = 0;
|
|
||||||
break;
|
|
||||||
case OPT_TERMIOS_RAWER:
|
|
||||||
termarg.c_iflag = 0;
|
|
||||||
termarg.c_oflag = 0;
|
|
||||||
termarg.c_lflag = 0;
|
|
||||||
termarg.c_cflag = (CS8);
|
|
||||||
termarg.c_cc[VMIN] = 1;
|
|
||||||
termarg.c_cc[VTIME] = 0;
|
|
||||||
break;
|
|
||||||
case OPT_SANE:
|
|
||||||
/* cread -ignbrk brkint -inlcr -igncr icrnl
|
|
||||||
-ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl
|
|
||||||
onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0
|
|
||||||
vt0 ff0 isig icanon iexten echo echoe echok -echonl
|
|
||||||
-noflsh -xcase -tostop -echoprt echoctl echoke, and
|
|
||||||
also sets all special characters to their default
|
|
||||||
values.
|
|
||||||
*/
|
|
||||||
termarg.c_iflag &= ~(IGNBRK|INLCR|IGNCR|IXOFF
|
|
||||||
#ifdef IUCLC
|
|
||||||
|IUCLC
|
|
||||||
#endif
|
|
||||||
|IXANY);
|
|
||||||
termarg.c_iflag |= (BRKINT|ICRNL|IMAXBEL);
|
|
||||||
termarg.c_oflag &= ~(0 /* for canonical reasons */
|
|
||||||
#ifdef OLCUC
|
|
||||||
|OLCUC
|
|
||||||
#endif
|
|
||||||
#ifdef OCRNL
|
|
||||||
|OCRNL
|
|
||||||
#endif
|
|
||||||
#ifdef ONOCR
|
|
||||||
|ONOCR
|
|
||||||
#endif
|
|
||||||
#ifdef ONLRET
|
|
||||||
|ONLRET
|
|
||||||
#endif
|
|
||||||
#ifdef OFILL
|
|
||||||
|OFILL
|
|
||||||
#endif
|
|
||||||
#ifdef OFDEL
|
|
||||||
|OFDEL
|
|
||||||
#endif
|
|
||||||
#ifdef NLDLY
|
|
||||||
|NLDLY
|
|
||||||
#endif
|
|
||||||
#ifdef CRDLY
|
|
||||||
|CRDLY
|
|
||||||
#endif
|
|
||||||
#ifdef TABDLY
|
|
||||||
|TABDLY
|
|
||||||
#endif
|
|
||||||
#ifdef BSDLY
|
|
||||||
|BSDLY
|
|
||||||
#endif
|
|
||||||
#ifdef VTDLY
|
|
||||||
|VTDLY
|
|
||||||
#endif
|
|
||||||
#ifdef FFDLY
|
|
||||||
|FFDLY
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
termarg.c_oflag |= (OPOST|ONLCR
|
|
||||||
#ifdef NL0
|
|
||||||
|NL0
|
|
||||||
#endif
|
|
||||||
#ifdef CR0
|
|
||||||
|CR0
|
|
||||||
#endif
|
|
||||||
#ifdef TAB0
|
|
||||||
|TAB0
|
|
||||||
#endif
|
|
||||||
#ifdef BS0
|
|
||||||
|BS0
|
|
||||||
#endif
|
|
||||||
#ifdef VT0
|
|
||||||
|VT0
|
|
||||||
#endif
|
|
||||||
#ifdef FF0
|
|
||||||
|FF0
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
termarg.c_cflag &= ~(0);
|
|
||||||
termarg.c_cflag |= (CREAD);
|
|
||||||
termarg.c_lflag &= ~(ECHONL|NOFLSH
|
|
||||||
#ifdef XCASE
|
|
||||||
|XCASE
|
|
||||||
#endif
|
|
||||||
|TOSTOP
|
|
||||||
#ifdef ECHOPRT
|
|
||||||
|ECHOPRT
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
termarg.c_lflag |= (ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE);
|
|
||||||
/*! "sets characters to their default values... - which? */
|
|
||||||
break;
|
|
||||||
case OPT_TERMIOS_CFMAKERAW:
|
|
||||||
#if HAVE_CFMAKERAW
|
|
||||||
cfmakeraw(&termarg);
|
|
||||||
#else
|
|
||||||
/* these setting follow the Linux documenation of cfmakeraw */
|
|
||||||
termarg.c_iflag &=
|
|
||||||
~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
|
||||||
termarg.c_oflag &= ~(OPOST);
|
|
||||||
termarg.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
|
||||||
termarg.c_cflag &= ~(CSIZE|PARENB);
|
|
||||||
termarg.c_cflag |= (CS8);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Error("TERMIOS option not handled - internal error?");
|
|
||||||
}
|
|
||||||
if (Tcsetattr(fd, TCSADRAIN, &termarg) < 0) {
|
|
||||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
|
||||||
fd, &termarg, strerror(errno));
|
|
||||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3782,6 +3571,12 @@ int applyopts(int fd, struct opt *opts, enum e_phase phase) {
|
||||||
opt->desc = ODESC_DONE;
|
opt->desc = ODESC_DONE;
|
||||||
++opt;
|
++opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WITH_TERMIOS
|
||||||
|
if (phase == PH_FD) {
|
||||||
|
xiotermios_flush(fd);
|
||||||
|
}
|
||||||
|
#endif /* WITH_TERMIOS */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue