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
|
||||
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:
|
||||
test.sh: Show a warning when phase-1 (insecure phase) of a security
|
||||
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);
|
||||
}
|
||||
#if _WITH_TERMIOS
|
||||
xiotermios_clrflag(xfd->stream.fd, 3, ICANON);
|
||||
xiotermios_clrflag(xfd->stream.fd, 3, ECHO);
|
||||
xiotermios_clrflag(xfd->stream.fd, 3, ICANON|ECHO);
|
||||
xiotermios_flush(xfd->stream.fd);
|
||||
#endif /* _WITH_TERMIOS */
|
||||
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
|
||||
xiotermios_setflag(pipe->fd, 3, ECHO);
|
||||
xiotermios_flush(pipe->fd);
|
||||
#endif /* _WITH_TERMIOS */
|
||||
if (pipe->para.readline.prompt || pipe->para.readline.dynprompt) {
|
||||
/* 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
|
||||
xiotermios_clrflag(pipe->fd, 3, ECHO);
|
||||
xiotermios_flush(pipe->fd);
|
||||
#endif /* _WITH_TERMIOS */
|
||||
Add_history(line);
|
||||
bytes = strlen(line);
|
||||
|
|
254
xio-termios.c
254
xio-termios.c
|
@ -14,6 +14,7 @@
|
|||
#if WITH_TERMIOS
|
||||
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_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 };
|
||||
|
@ -297,42 +298,237 @@ int xiotermiosflag_applyopt(int fd, struct opt *opt) {
|
|||
|
||||
#endif /* WITH_TERMIOS */
|
||||
|
||||
int xiotermios_setflag(int fd, int word, tcflag_t mask) {
|
||||
union {
|
||||
struct termios termarg;
|
||||
tcflag_t flags[4];
|
||||
} tdata;
|
||||
bool _xiotermios_doit = false; /* _data has been retrieved and manipulated, set it later */
|
||||
union {
|
||||
struct termios termarg;
|
||||
tcflag_t flags[4];
|
||||
#ifdef HAVE_TERMIOS_ISPEED
|
||||
speed_t speeds[sizeof(struct termios)/sizeof(speed_t)];
|
||||
#endif
|
||||
} _xiotermios_data;
|
||||
|
||||
if (Tcgetattr(fd, &tdata.termarg) < 0) {
|
||||
Error3("tcgetattr(%d, %p): %s",
|
||||
fd, &tdata.termarg, strerror(errno));
|
||||
return -1;
|
||||
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",
|
||||
fd, &_xiotermios_data.termarg, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
_xiotermios_doit = true;
|
||||
}
|
||||
tdata.flags[word] |= mask;
|
||||
if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) {
|
||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
||||
fd, &tdata.termarg, strerror(errno));
|
||||
_xiotermios_data.flags[word] |= mask;
|
||||
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 0;
|
||||
}
|
||||
|
||||
int xiotermios_clrflag(int fd, int word, tcflag_t mask) {
|
||||
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));
|
||||
return -1;
|
||||
}
|
||||
tdata.flags[word] &= ~mask;
|
||||
if (Tcsetattr(fd, TCSADRAIN, &tdata.termarg) < 0) {
|
||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
||||
fd, &tdata.termarg, strerror(errno));
|
||||
return -1;
|
||||
int xiotermios_flush(int fd) {
|
||||
if (_xiotermios_doit) {
|
||||
if (Tcsetattr(fd, TCSADRAIN, &_xiotermios_data.termarg) < 0) {
|
||||
Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
|
||||
fd, &_xiotermios_data.termarg, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
_xiotermios_doit = false;
|
||||
}
|
||||
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_clrflag(int fd, int word, tcflag_t mask);
|
||||
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 /* !defined(__xio_termios_h_included) */
|
||||
|
|
231
xioopts.c
231
xioopts.c
|
@ -3509,252 +3509,41 @@ int applyopts(int fd, struct opt *opts, enum e_phase phase) {
|
|||
|
||||
#if WITH_TERMIOS
|
||||
} 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) {
|
||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
} 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) !=
|
||||
(opt->value.u_uint << opt->desc->arg3)) {
|
||||
Error2("option %s: invalid value %u",
|
||||
opt->desc->defname, opt->value.u_uint);
|
||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||
}
|
||||
if (Tcgetattr(fd, &tdata.termarg) < 0) {
|
||||
Error3("tcgetattr(%d, %p): %s",
|
||||
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));
|
||||
if (xiotermios_value(fd, opt->desc->major, opt->desc->minor,
|
||||
(opt->value.u_uint << opt->desc->arg3) & opt->desc->minor) < 0) {
|
||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||
}
|
||||
|
||||
} else if (opt->desc->func == OFUNC_TERMIOS_PATTERN) {
|
||||
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));
|
||||
if (xiotermios_value(fd, opt->desc->major, opt->desc->arg3, opt->desc->minor) < 0) {
|
||||
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) {
|
||||
struct termios termarg;
|
||||
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));
|
||||
if (xiotermios_char(fd, opt->desc->major, opt->value.u_byte) < 0) {
|
||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TERMIOS_ISPEED
|
||||
} else if (opt->desc->func == OFUNC_TERMIOS_SPEED) {
|
||||
union {
|
||||
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));
|
||||
if (xiotermios_speed(fd, opt->desc->major, opt->value.u_uint) < 0) {
|
||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||
}
|
||||
#endif /* HAVE_TERMIOS_ISPEED */
|
||||
|
||||
} else if (opt->desc->func == OFUNC_TERMIOS_SPEC) {
|
||||
struct termios termarg;
|
||||
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));
|
||||
if (xiotermios_spec(fd, opt->desc->optcode) < 0) {
|
||||
opt->desc = ODESC_ERROR; ++opt; continue;
|
||||
}
|
||||
|
||||
|
@ -3782,7 +3571,13 @@ int applyopts(int fd, struct opt *opts, enum e_phase phase) {
|
|||
opt->desc = ODESC_DONE;
|
||||
++opt;
|
||||
}
|
||||
return 0;
|
||||
|
||||
#if WITH_TERMIOS
|
||||
if (phase == PH_FD) {
|
||||
xiotermios_flush(fd);
|
||||
}
|
||||
#endif /* WITH_TERMIOS */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* applies to fd all options belonging to phases */
|
||||
|
|
Loading…
Reference in a new issue