summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2010-11-02 17:00:56 +0000
committered <ed@FreeBSD.org>2010-11-02 17:00:56 +0000
commit568dc19750ccec553ab3df463967352da528cd93 (patch)
treef242e644964b102fa1b89235f6f64b8ce56638ed
parent3108c93ec3c2c606e4ec78a5f471565ab55e31a9 (diff)
downloadFreeBSD-src-568dc19750ccec553ab3df463967352da528cd93.zip
FreeBSD-src-568dc19750ccec553ab3df463967352da528cd93.tar.gz
Add a new libc function: cfmakesane(3).
I've noticed various terminal emulators that need to obtain a sane default termios structure use very complex `hacks'. Even though POSIX doesn't provide any functionality for this, extend our termios API with cfmakesane(3), which is similar to the commonly supported cfmakeraw(3), except that it fills the termios structure with sane defaults. Change all code in our base system to use this function, instead of depending on <sys/ttydefaults.h> to provide TTYDEF_*.
-rw-r--r--bin/stty/key.c11
-rw-r--r--include/termios.h1
-rw-r--r--lib/libc/gen/Makefile.inc6
-rw-r--r--lib/libc/gen/Symbol.map1
-rw-r--r--lib/libc/gen/tcsetattr.317
-rw-r--r--lib/libc/gen/termios.c19
-rw-r--r--libexec/getty/main.c12
-rw-r--r--libexec/rlogind/rlogind.c9
8 files changed, 56 insertions, 20 deletions
diff --git a/bin/stty/key.c b/bin/stty/key.c
index 413f4d5..1241301 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 92d1861..e41da9f 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 32888dd..d55bc46 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 dd375b0..f9abab5 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 01628d3..9be012e 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 fc21757..7e9f169 100644
--- a/lib/libc/gen/termios.c
+++ b/lib/libc/gen/termios.c
@@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$");
#include <sys/time.h>
#include <errno.h>
+#include <string.h>
+#define TTYDEFCHARS
#include <termios.h>
#include <unistd.h>
#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 ad53411..ced1573 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 5831a25..874112d 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) {
OpenPOWER on IntegriCloud