diff --git a/bin/stty/key.c b/bin/stty/key.c index 413f4d58dfa9..12413019f964 100644 --- a/bin/stty/key.c +++ b/bin/stty/key.c @@ -257,14 +257,15 @@ f_rows(struct info *ip) void f_sane(struct info *ip) { + struct termios def; - ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & CLOCAL); - ip->t.c_iflag = TTYDEF_IFLAG; - ip->t.c_iflag |= ICRNL; + cfmakesane(&def); + ip->t.c_cflag = def.c_cflag | (ip->t.c_cflag & CLOCAL); + ip->t.c_iflag = def.c_iflag; /* preserve user-preference flags in lflag */ #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) - ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP); - ip->t.c_oflag = TTYDEF_OFLAG; + ip->t.c_lflag = def.c_lflag | (ip->t.c_lflag & LKEEP); + ip->t.c_oflag = def.c_oflag; ip->set = 1; } diff --git a/include/termios.h b/include/termios.h index 92d186105f94..e41da9fea12a 100644 --- a/include/termios.h +++ b/include/termios.h @@ -88,6 +88,7 @@ pid_t tcgetsid(int); int tcsetsid(int, pid_t); void cfmakeraw(struct termios *); +void cfmakesane(struct termios *); int cfsetspeed(struct termios *, speed_t); #endif __END_DECLS diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index 32888ddfecce..d55bc4610587 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -180,9 +180,9 @@ MLINKS+=syslog.3 closelog.3 syslog.3 openlog.3 syslog.3 setlogmask.3 \ syslog.3 vsyslog.3 MLINKS+=tcsendbreak.3 tcdrain.3 tcsendbreak.3 tcflow.3 tcsendbreak.3 tcflush.3 MLINKS+=tcsetattr.3 cfgetispeed.3 tcsetattr.3 cfgetospeed.3 \ - tcsetattr.3 cfmakeraw.3 tcsetattr.3 cfsetispeed.3 \ - tcsetattr.3 cfsetospeed.3 tcsetattr.3 cfsetspeed.3 \ - tcsetattr.3 tcgetattr.3 + tcsetattr.3 cfmakeraw.3 tcsetattr.3 cfmakesane.3 \ + tcsetattr.3 cfsetispeed.3 tcsetattr.3 cfsetospeed.3 \ + tcsetattr.3 cfsetspeed.3 tcsetattr.3 tcgetattr.3 MLINKS+=ttyname.3 isatty.3 ttyname.3 ttyname_r.3 MLINKS+=tzset.3 tzsetwall.3 MLINKS+=unvis.3 strunvis.3 unvis.3 strunvisx.3 diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index dd375b07e89c..f9abab51f2c3 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -358,6 +358,7 @@ FBSD_1.1 { FBSD_1.2 { basename_r; + cfmakesane; endutxent; getpagesizes; getutxent; diff --git a/lib/libc/gen/tcsetattr.3 b/lib/libc/gen/tcsetattr.3 index 01628d3d330a..9be012eda8b8 100644 --- a/lib/libc/gen/tcsetattr.3 +++ b/lib/libc/gen/tcsetattr.3 @@ -38,6 +38,7 @@ .Nm cfsetospeed , .Nm cfsetspeed , .Nm cfmakeraw , +.Nm cfmakesane , .Nm tcgetattr , .Nm tcsetattr .Nd manipulating the termios structure @@ -57,6 +58,8 @@ .Fn cfsetspeed "struct termios *t" "speed_t speed" .Ft void .Fn cfmakeraw "struct termios *t" +.Ft void +.Fn cfmakesane "struct termios *t" .Ft int .Fn tcgetattr "int fd" "struct termios *t" .Ft int @@ -64,6 +67,7 @@ .Sh DESCRIPTION The .Fn cfmakeraw , +.Fn cfmakesane , .Fn tcgetattr and .Fn tcsetattr @@ -180,14 +184,20 @@ The .Fn cfmakeraw function sets the flags stored in the termios structure to a state disabling all input and output processing, giving a -.Dq raw I/O path . +.Dq raw I/O path , +while the +.Fn cfmakesane +function sets them to a state similar to those of a newly created +terminal device. It should be noted that there is no function to reverse this effect. This is because there are a variety of processing options that could be re-enabled and the correct method is for an application to snapshot the current terminal state using the function .Fn tcgetattr , -setting raw mode with +setting raw or sane mode with .Fn cfmakeraw +or +.Fn cfmakesane and the subsequent .Fn tcsetattr , and then using another @@ -316,7 +326,8 @@ functions are expected to be compliant with the .St -p1003.1-88 specification. The -.Fn cfmakeraw +.Fn cfmakeraw , +.Fn cfmakesane and .Fn cfsetspeed functions, diff --git a/lib/libc/gen/termios.c b/lib/libc/gen/termios.c index fc21757d106f..7e9f1691876f 100644 --- a/lib/libc/gen/termios.c +++ b/lib/libc/gen/termios.c @@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#define TTYDEFCHARS #include #include #include "un-namespace.h" @@ -173,6 +175,23 @@ cfmakeraw(struct termios *t) t->c_cc[VTIME] = 0; } +/* + * Obtain a termios structure which is similar to the one provided by + * the kernel. + */ +void +cfmakesane(struct termios *t) +{ + + t->c_cflag = TTYDEF_CFLAG; + t->c_iflag = TTYDEF_IFLAG; + t->c_lflag = TTYDEF_LFLAG; + t->c_oflag = TTYDEF_OFLAG; + t->c_ispeed = TTYDEF_SPEED; + t->c_ospeed = TTYDEF_SPEED; + memcpy(&t->c_cc, ttydefchars, sizeof ttydefchars); +} + int tcsendbreak(int fd, int len __unused) { diff --git a/libexec/getty/main.c b/libexec/getty/main.c index ad53411b57fb..ced1573df70a 100644 --- a/libexec/getty/main.c +++ b/libexec/getty/main.c @@ -454,8 +454,9 @@ opentty(const char *tty, int flags) } static void -defttymode() +defttymode(void) { + struct termios def; /* Start with default tty settings. */ if (tcgetattr(STDIN_FILENO, &tmode) < 0) { @@ -471,10 +472,11 @@ defttymode() * to leave their idea of the preferred VERASE key value * there. */ - tmode.c_iflag = TTYDEF_IFLAG; - tmode.c_oflag = TTYDEF_OFLAG; - tmode.c_lflag = TTYDEF_LFLAG; - tmode.c_cflag = TTYDEF_CFLAG; + cfmakesane(&def); + tmode.c_iflag = def.c_iflag; + tmode.c_oflag = def.c_oflag; + tmode.c_lflag = def.c_lflag; + tmode.c_cflag = def.c_cflag; if (NC) tmode.c_cflag |= CLOCAL; omode = tmode; diff --git a/libexec/rlogind/rlogind.c b/libexec/rlogind/rlogind.c index 5831a2515b70..874112d70e9e 100644 --- a/libexec/rlogind/rlogind.c +++ b/libexec/rlogind/rlogind.c @@ -545,7 +545,7 @@ setup_term(int fd) { char *cp = index(term+ENVSIZE, '/'); char *speed; - struct termios tt; + struct termios tt, def; #ifndef notyet tcgetattr(fd, &tt); @@ -558,9 +558,10 @@ setup_term(int fd) cfsetspeed(&tt, atoi(speed)); } - tt.c_iflag = TTYDEF_IFLAG; - tt.c_oflag = TTYDEF_OFLAG; - tt.c_lflag = TTYDEF_LFLAG; + cfmakesane(&def); + tt.c_iflag = def.c_iflag; + tt.c_oflag = def.c_oflag; + tt.c_lflag = def.c_lflag; tcsetattr(fd, TCSAFLUSH, &tt); #else if (cp) {