Skip to content

Commit

Permalink
Add a new libc function: cfmakesane(3).
Browse files Browse the repository at this point in the history
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_*.
  • Loading branch information
ed authored and ed committed Nov 2, 2010
1 parent 3108c93 commit 568dc19
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 20 deletions.
11 changes: 6 additions & 5 deletions bin/stty/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions include/termios.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions lib/libc/gen/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions lib/libc/gen/Symbol.map
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ FBSD_1.1 {

FBSD_1.2 {
basename_r;
cfmakesane;
endutxent;
getpagesizes;
getutxent;
Expand Down
17 changes: 14 additions & 3 deletions lib/libc/gen/tcsetattr.3
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
.Nm cfsetospeed ,
.Nm cfsetspeed ,
.Nm cfmakeraw ,
.Nm cfmakesane ,
.Nm tcgetattr ,
.Nm tcsetattr
.Nd manipulating the termios structure
Expand All @@ -57,13 +58,16 @@
.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
.Fn tcsetattr "int fd" "int action" "const struct termios *t"
.Sh DESCRIPTION
The
.Fn cfmakeraw ,
.Fn cfmakesane ,
.Fn tcgetattr
and
.Fn tcsetattr
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions lib/libc/gen/termios.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
{
Expand Down
12 changes: 7 additions & 5 deletions libexec/getty/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand Down
9 changes: 5 additions & 4 deletions libexec/rlogind/rlogind.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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) {
Expand Down

0 comments on commit 568dc19

Please sign in to comment.