Use struct termios instead of TTY_state typedef

Use tc[gs]etattr() instead of [gs]et_tty() abstraction
From: Todd C. Miller <millert@cvs.openbsd.org>
This commit is contained in:
tg 2004-12-31 17:39:12 +00:00
parent 2b6df533b9
commit 665202f561
4 changed files with 27 additions and 216 deletions

11
edit.c
View File

@ -1,4 +1,4 @@
/** $MirBSD: src/bin/ksh/edit.c,v 2.7 2004/12/31 17:11:11 tg Exp $ */ /** $MirBSD: src/bin/ksh/edit.c,v 2.8 2004/12/31 17:39:12 tg Exp $ */
/* $OpenBSD: edit.c,v 1.23 2004/12/18 22:12:23 millert Exp $ */ /* $OpenBSD: edit.c,v 1.23 2004/12/18 22:12:23 millert Exp $ */
/* /*
@ -21,7 +21,7 @@
#include <ctype.h> #include <ctype.h>
#include "ksh_stat.h" #include "ksh_stat.h"
__RCSID("$MirBSD: src/bin/ksh/edit.c,v 2.7 2004/12/31 17:11:11 tg Exp $"); __RCSID("$MirBSD: src/bin/ksh/edit.c,v 2.8 2004/12/31 17:39:12 tg Exp $");
#if defined(TIOCGWINSZ) #if defined(TIOCGWINSZ)
static RETSIGTYPE x_sigwinch(int sig); static RETSIGTYPE x_sigwinch(int sig);
@ -175,7 +175,7 @@ x_mode(bool onoff)
x_cur_mode = onoff; x_cur_mode = onoff;
if (onoff) { if (onoff) {
TTY_state cb; struct termios cb;
X_chars oldchars; X_chars oldchars;
oldchars = edchars; oldchars = edchars;
@ -245,7 +245,7 @@ x_mode(bool onoff)
# endif /* TIOCGATC */ # endif /* TIOCGATC */
#endif /* HAVE_TERMIOS_H || HAVE_TERMIO_H */ #endif /* HAVE_TERMIOS_H || HAVE_TERMIO_H */
set_tty(tty_fd, &cb, TF_WAIT); tcsetattr(tty_fd, TCSADRAIN, &cb);
#ifdef __CYGWIN__ #ifdef __CYGWIN__
if (edchars.eof == '\0') if (edchars.eof == '\0')
@ -268,8 +268,7 @@ x_mode(bool onoff)
if (memcmp(&edchars, &oldchars, sizeof(edchars)) != 0) if (memcmp(&edchars, &oldchars, sizeof(edchars)) != 0)
x_emacs_keys(&edchars); x_emacs_keys(&edchars);
} else { } else {
/* TF_WAIT doesn't seem to be necessary when leaving xmode */ tcsetattr(tty_fd, TCSADRAIN, &tty_state);
set_tty(tty_fd, &tty_state, TF_NONE);
} }
return prev; return prev;

32
jobs.c
View File

@ -1,4 +1,4 @@
/** $MirBSD: src/bin/ksh/jobs.c,v 2.6 2004/12/28 22:32:08 tg Exp $ */ /** $MirBSD: src/bin/ksh/jobs.c,v 2.7 2004/12/31 17:39:12 tg Exp $ */
/* $OpenBSD: jobs.c,v 1.26 2004/12/18 22:12:23 millert Exp $ */ /* $OpenBSD: jobs.c,v 1.26 2004/12/18 22:12:23 millert Exp $ */
/* /*
@ -31,7 +31,7 @@
#include "ksh_times.h" #include "ksh_times.h"
#include "tty.h" #include "tty.h"
__RCSID("$MirBSD: src/bin/ksh/jobs.c,v 2.6 2004/12/28 22:32:08 tg Exp $"); __RCSID("$MirBSD: src/bin/ksh/jobs.c,v 2.7 2004/12/31 17:39:12 tg Exp $");
/* Start of system configuration stuff */ /* Start of system configuration stuff */
@ -143,7 +143,7 @@ struct job {
Proc *last_proc; /* last process in list */ Proc *last_proc; /* last process in list */
Coproc_id coproc_id; /* 0 or id of coprocess output pipe */ Coproc_id coproc_id; /* 0 or id of coprocess output pipe */
#ifdef TTY_PGRP #ifdef TTY_PGRP
TTY_state ttystate; /* saved tty state for stopped jobs */ struct termios ttystate;/* saved tty state for stopped jobs */
pid_t saved_ttypgrp; /* saved tty process group for stopped jobs */ pid_t saved_ttypgrp; /* saved tty process group for stopped jobs */
#endif /* TTY_PGRP */ #endif /* TTY_PGRP */
}; };
@ -339,7 +339,7 @@ j_change(void)
int i; int i;
if (Flag(FMONITOR)) { if (Flag(FMONITOR)) {
/* Don't call get_tty() 'til we own the tty process group */ /* Don't call tcgetattr() 'til we own the tty process group */
tty_init(false); tty_init(false);
# ifdef TTY_PGRP # ifdef TTY_PGRP
@ -404,7 +404,7 @@ j_change(void)
warningf(false, "warning: won't have full job control"); warningf(false, "warning: won't have full job control");
# endif /* TTY_PGRP */ # endif /* TTY_PGRP */
if (tty_fd >= 0) if (tty_fd >= 0)
get_tty(tty_fd, &tty_state); tcgetattr(tty_fd, &tty_state);
} else { } else {
# ifdef TTY_PGRP # ifdef TTY_PGRP
ttypgrp_ok = 0; ttypgrp_ok = 0;
@ -887,14 +887,12 @@ j_resume(const char *cp, int bg)
# ifdef TTY_PGRP # ifdef TTY_PGRP
/* attach tty to job */ /* attach tty to job */
if (j->state == PRUNNING) { if (j->state == PRUNNING) {
if (ttypgrp_ok && (j->flags & JF_SAVEDTTY)) { if (ttypgrp_ok && (j->flags & JF_SAVEDTTY))
set_tty(tty_fd, &j->ttystate, TF_NONE); tcsetattr(tty_fd, TCSADRAIN, &j->ttystate);
}
/* See comment in j_waitj regarding saved_ttypgrp. */ /* See comment in j_waitj regarding saved_ttypgrp. */
if (ttypgrp_ok && tcsetpgrp(tty_fd, (j->flags & JF_SAVEDTTYPGRP) ? j->saved_ttypgrp : j->pgrp) < 0) { if (ttypgrp_ok && tcsetpgrp(tty_fd, (j->flags & JF_SAVEDTTYPGRP) ? j->saved_ttypgrp : j->pgrp) < 0) {
if (j->flags & JF_SAVEDTTY) { if (j->flags & JF_SAVEDTTY)
set_tty(tty_fd, &tty_state, TF_NONE); tcsetattr(tty_fd, TCSADRAIN, &tty_state);
}
sigprocmask(SIG_SETMASK, &omask, sigprocmask(SIG_SETMASK, &omask,
NULL); NULL);
bi_errorf("1st tcsetpgrp(%d, %d) failed: %s", bi_errorf("1st tcsetpgrp(%d, %d) failed: %s",
@ -915,9 +913,8 @@ j_resume(const char *cp, int bg)
if (!bg) { if (!bg) {
j->flags &= ~JF_FG; j->flags &= ~JF_FG;
# ifdef TTY_PGRP # ifdef TTY_PGRP
if (ttypgrp_ok && (j->flags & JF_SAVEDTTY)) { if (ttypgrp_ok && (j->flags & JF_SAVEDTTY))
set_tty(tty_fd, &tty_state, TF_NONE); tcsetattr(tty_fd, TCSADRAIN, &tty_state);
}
if (ttypgrp_ok && tcsetpgrp(tty_fd, our_pgrp) < 0) { if (ttypgrp_ok && tcsetpgrp(tty_fd, our_pgrp) < 0) {
warningf(true, warningf(true,
"fg: 2nd tcsetpgrp(%d, %d) failed: %s", "fg: 2nd tcsetpgrp(%d, %d) failed: %s",
@ -1216,7 +1213,7 @@ j_waitj(Job *j, int flags, const char *where)
} }
if (j->state == PSTOPPED) { if (j->state == PSTOPPED) {
j->flags |= JF_SAVEDTTY; j->flags |= JF_SAVEDTTY;
get_tty(tty_fd, &j->ttystate); tcgetattr(tty_fd, &j->ttystate);
} }
} }
#endif /* TTY_PGRP */ #endif /* TTY_PGRP */
@ -1232,10 +1229,9 @@ j_waitj(Job *j, int flags, const char *where)
if (j->state == PEXITED && j->status == 0 if (j->state == PEXITED && j->status == 0
&& (j->flags & JF_USETTYMODE)) && (j->flags & JF_USETTYMODE))
{ {
get_tty(tty_fd, &tty_state); tcgetattr(tty_fd, &tty_state);
} else { } else {
set_tty(tty_fd, &tty_state, tcsetattr(tty_fd, TCSADRAIN, &tty_state);
(j->state == PEXITED) ? 0 : TF_MIPSKLUDGE);
/* Don't use tty mode if job is stopped and /* Don't use tty mode if job is stopped and
* later restarted and exits. Consider * later restarted and exits. Consider
* the sequence: * the sequence:

121
tty.c
View File

@ -1,5 +1,5 @@
/** $MirBSD: src/bin/ksh/tty.c,v 2.2 2004/12/28 22:32:08 tg Exp $ */ /** $MirBSD: src/bin/ksh/tty.c,v 2.3 2004/12/31 17:39:12 tg Exp $ */
/* $OpenBSD: tty.c,v 1.2 1996/10/01 02:05:51 downsj Exp $ */ /* $OpenBSD: tty.c,v 1.4 2004/12/18 22:12:23 millert Exp $ */
#include "sh.h" #include "sh.h"
#include "ksh_stat.h" #include "ksh_stat.h"
@ -7,91 +7,7 @@
#include "tty.h" #include "tty.h"
#undef EXTERN #undef EXTERN
__RCSID("$MirBSD: src/bin/ksh/tty.c,v 2.2 2004/12/28 22:32:08 tg Exp $"); __RCSID("$MirBSD: src/bin/ksh/tty.c,v 2.3 2004/12/31 17:39:12 tg Exp $");
int
get_tty(int fd, TTY_state *ts)
{
int ret;
# ifdef HAVE_TERMIOS_H
ret = tcgetattr(fd, ts);
# else /* HAVE_TERIOS_H */
# ifdef HAVE_TERMIO_H
ret = ioctl(fd, TCGETA, ts);
# else /* HAVE_TERMIO_H */
ret = ioctl(fd, TIOCGETP, &ts->sgttyb);
# ifdef TIOCGATC
if (ioctl(fd, TIOCGATC, &ts->lchars) < 0)
ret = -1;
# else
if (ioctl(fd, TIOCGETC, &ts->tchars) < 0)
ret = -1;
# ifdef TIOCGLTC
if (ioctl(fd, TIOCGLTC, &ts->ltchars) < 0)
ret = -1;
# endif /* TIOCGLTC */
# endif /* TIOCGATC */
# endif /* HAVE_TERMIO_H */
# endif /* HAVE_TERIOS_H */
return ret;
}
int
set_tty(int fd, TTY_state *ts, int flags GCC_FUNC_ATTR(unused))
{
int ret = 0;
# ifdef HAVE_TERMIOS_H
ret = tcsetattr(fd, TCSADRAIN, ts);
# else /* HAVE_TERIOS_H */
# ifdef HAVE_TERMIO_H
# ifndef TCSETAW /* e.g. Cray-2 */
/* first wait for output to drain */
# ifdef TCSBRK
if (ioctl(tty_fd, TCSBRK, 1) < 0)
ret = -1;
# else /* the following kludge is minimally intrusive, but sometimes fails */
if (flags & TF_WAIT)
sleep((unsigned)1); /* fake it */
# endif
# endif /* !TCSETAW */
# if defined(_BSD_SYSV) || !defined(TCSETAW)
/* _BSD_SYSV must force TIOCSETN instead of TIOCSETP (preserve type-ahead) */
if (ioctl(tty_fd, TCSETA, ts) < 0)
ret = -1;
# else
if (ioctl(tty_fd, TCSETAW, ts) < 0)
ret = -1;
# endif
# else /* HAVE_TERMIO_H */
# if defined(__mips) && (defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
/* Under RISC/os 5.00, bsd43 environment, after a tty driver
* generated interrupt (eg, INTR, TSTP), all output to tty is
* lost until a SETP is done (there must be a better way of
* doing this...).
*/
if (flags & TF_MIPSKLUDGE)
ret = ioctl(fd, TIOCSETP, &ts->sgttyb);
else
# endif /* _SYSTYPE_BSD43 */
ret = ioctl(fd, TIOCSETN, &ts->sgttyb);
# ifdef TIOCGATC
if (ioctl(fd, TIOCSATC, &ts->lchars) < 0)
ret = -1;
# else
if (ioctl(fd, TIOCSETC, &ts->tchars) < 0)
ret = -1;
# ifdef TIOCGLTC
if (ioctl(fd, TIOCSLTC, &ts->ltchars) < 0)
ret = -1;
# endif /* TIOCGLTC */
# endif /* TIOCGATC */
# endif /* HAVE_TERMIO_H */
# endif /* HAVE_TERIOS_H */
return ret;
}
/* Initialize tty_fd. Used for saving/reseting tty modes upon /* Initialize tty_fd. Used for saving/reseting tty modes upon
* foreground job completion and for setting up tty process group. * foreground job completion and for setting up tty process group.
@ -108,40 +24,11 @@ tty_init(int init_ttystate)
} }
tty_devtty = 1; tty_devtty = 1;
/* SCO can't job control on /dev/tty, so don't try... */
#if !defined(__SCO__)
if ((tfd = open("/dev/tty", O_RDWR, 0)) < 0) { if ((tfd = open("/dev/tty", O_RDWR, 0)) < 0) {
#ifdef __NeXT
/* rlogin on NeXT boxes does not set up the controlling tty,
* so force it to be done here...
*/
{
extern char *ttyname(int);
char *s = ttyname(isatty(2) ? 2 : 0);
int fd;
if (s && (fd = open(s, O_RDWR, 0)) >= 0) {
close(fd);
tfd = open("/dev/tty", O_RDWR, 0);
}
}
#endif /* __NeXT */
/* X11R5 xterm on mips doesn't set controlling tty properly - temporary hack */
# if !defined(__mips) || !(defined(_SYSTYPE_BSD43) || defined(__SYSTYPE_BSD43))
if (tfd < 0) {
tty_devtty = 0; tty_devtty = 0;
warningf(false, warningf(false,
"No controlling tty (open /dev/tty: %s)", "No controlling tty (open /dev/tty: %s)",
strerror(errno)); strerror(errno));
}
# endif /* __mips */
}
#else /* !__SCO__ */
tfd = -1;
#endif /* __SCO__ */
if (tfd < 0) {
do_close = 0; do_close = 0;
if (isatty(0)) if (isatty(0))
tfd = 0; tfd = 0;
@ -161,7 +48,7 @@ tty_init(int init_ttystate)
close(tty_fd); close(tty_fd);
tty_fd = -1; tty_fd = -1;
} else if (init_ttystate) } else if (init_ttystate)
get_tty(tty_fd, &tty_state); tcgetattr(tty_fd, &tty_state);
if (do_close) if (do_close)
close(tfd); close(tfd);
} }

79
tty.h
View File

@ -1,20 +1,9 @@
/** $MirBSD: src/bin/ksh/tty.h,v 2.1 2004/12/10 18:09:42 tg Exp $ */ /** $MirBSD: src/bin/ksh/tty.h,v 2.2 2004/12/31 17:39:12 tg Exp $ */
/* $OpenBSD: tty.h,v 1.2 1996/11/21 07:59:36 downsj Exp $ */ /* $OpenBSD: tty.h,v 1.4 2004/12/18 22:12:23 millert Exp $ */
#ifndef TTY_H #ifndef TTY_H
#define TTY_H #define TTY_H
/*
tty.h -- centralized definitions for a variety of terminal interfaces
created by DPK, Oct. 1986
Rearranged to work with autoconf, added TTY_state, get_tty/set_tty
Michael Rendell, May '94
last edit: 30-Jul-1987 D A Gwyn
*/
/* some useful #defines */ /* some useful #defines */
#ifdef EXTERN #ifdef EXTERN
# define I__(i) = i # define I__(i) = i
@ -35,73 +24,13 @@
# define SYS_IOCTL_WITH_TERMIO # define SYS_IOCTL_WITH_TERMIO
#endif /* SYS_IOCTL_WITH_TERMIO */ #endif /* SYS_IOCTL_WITH_TERMIO */
#ifdef HAVE_TERMIOS_H #include <termios.h>
# include <termios.h>
# ifdef SYS_IOCTL_WITH_TERMIOS
# if !(defined(sun) && !defined(__svr4__)) /* too many warnings on sunos */
/* Need to include sys/ioctl.h on some systems to get the TIOCGWINSZ
* stuff (eg, digital unix).
*/
# include <sys/ioctl.h>
# endif /* !(sun && !__svr4__) */
# endif /* SYS_IOCTL_WITH_TERMIOS */
typedef struct termios TTY_state; typedef struct termios TTY_state;
#else
# ifdef HAVE_TERMIO_H
# include <termio.h>
# ifdef SYS_IOCTL_WITH_TERMIO
# include <sys/ioctl.h> /* see comment above in termios stuff */
# endif /* SYS_IOCTL_WITH_TERMIO */
# if _BSD_SYSV /* BRL UNIX System V emulation */
# ifndef NTTYDISC
# define TIOCGETD _IOR( 't', 0, int )
# define TIOCSETD _IOW( 't', 1, int )
# define NTTYDISC 2
# endif
# ifndef TIOCSTI
# define TIOCSTI _IOW( 't', 114, char )
# endif
# ifndef TIOCSPGRP
# define TIOCSPGRP _IOW( 't', 118, int )
# endif
# endif /* _BSD_SYSV */
typedef struct termio TTY_state;
# else /* HAVE_TERMIO_H */
/* Assume BSD tty stuff. Uses TIOCGETP, TIOCSETN; uses TIOCGATC/TIOCSATC if
* available, otherwise it uses TIOCGETC/TIOCSETC (also uses TIOCGLTC/TIOCSLTC
* if available)
*/
# ifdef _MINIX
# include <sgtty.h>
# define TIOCSETN TIOCSETP
# else
# include <sys/ioctl.h>
# endif
typedef struct {
struct sgttyb sgttyb;
# ifdef TIOCGATC
struct lchars lchars;
# else /* TIOCGATC */
struct tchars tchars;
# ifdef TIOCGLTC
struct ltchars ltchars;
# endif /* TIOCGLTC */
# endif /* TIOCGATC */
} TTY_state;
# endif /* HAVE_TERMIO_H */
#endif /* HAVE_TERMIOS_H */
/* Flags for set_tty() */
#define TF_NONE 0x00
#define TF_WAIT 0x01 /* drain output, even it requires sleep() */
#define TF_MIPSKLUDGE 0x02 /* kludge to unwedge RISC/os 5.0 tty driver */
EXTERN int tty_fd I__(-1); /* dup'd tty file descriptor */ EXTERN int tty_fd I__(-1); /* dup'd tty file descriptor */
EXTERN int tty_devtty; /* true if tty_fd is from /dev/tty */ EXTERN int tty_devtty; /* true if tty_fd is from /dev/tty */
EXTERN TTY_state tty_state; /* saved tty state */ EXTERN struct termios tty_state; /* saved tty state */
extern int get_tty(int fd, TTY_state *ts);
extern int set_tty(int fd, TTY_state *ts, int flags);
extern void tty_init(int init_ttystate); extern void tty_init(int init_ttystate);
extern void tty_close(void); extern void tty_close(void);