summaryrefslogtreecommitdiff
path: root/tty.c.dist
diff options
context:
space:
mode:
Diffstat (limited to 'tty.c.dist')
-rw-r--r--tty.c.dist1333
1 files changed, 1084 insertions, 249 deletions
diff --git a/tty.c.dist b/tty.c.dist
index 572a3ff..2ce97b4 100644
--- a/tty.c.dist
+++ b/tty.c.dist
@@ -42,6 +42,9 @@ RCS_ID("$Id: tty.sh,v 1.13 1994/05/31 12:33:17 mlschroe Exp $ FAU")
# include <sys/ttold.h> /* needed for TIOCEXCL */
# endif
#endif
+#ifdef __hpux
+# include <sys/modem.h>
+#endif
#ifdef ISC
# include <sys/tty.h>
@@ -50,11 +53,27 @@ RCS_ID("$Id: tty.sh,v 1.13 1994/05/31 12:33:17 mlschroe Exp $ FAU")
#endif
#include "config.h"
+#ifdef SVR4
+#include <sys/stropts.h> /* for I_POP */
+#endif
+
#include "screen.h"
#include "extern.h"
+#if !defined(TIOCCONS) && defined(sun) && defined(SVR4)
+# include <sys/strredir.h>
+#endif
+
extern struct display *display, *displays;
extern int iflag;
+#if !defined(TIOCCONS) && defined(SRIOCSREDIR)
+extern struct win *console_window;
+static void consredir_readev_fn __P((struct event *, char *));
+#endif
+
+static void DoSendBreak __P((int, int, int));
+static sigret_t SigAlrmDummy __P(SIGPROTOARG);
+
/* Frank Schulz (fschulz@pyramid.com):
* I have no idea why VSTART is not defined and my fix is probably not
@@ -67,6 +86,18 @@ extern int iflag;
#define VSTOP _VSTOP
#endif
+#ifndef O_NOCTTY
+# define O_NOCTTY 0
+#endif
+
+#ifndef TTYVMIN
+# define TTYVMIN 1
+#endif
+#ifndef TTYVTIME
+#define TTYVTIME 0
+#endif
+
+
static sigret_t
SigAlrmDummy SIGDEFARG
{
@@ -75,27 +106,41 @@ SigAlrmDummy SIGDEFARG
}
/*
- * Carefully open a charcter device. Not used to open ttys.
+ * Carefully open a charcter device. Not used to open display ttys.
+ * The second parameter is parsed for a few stty style options.
*/
int
-OpenTTY(line)
-char *line;
+OpenTTY(line, opt)
+char *line, *opt;
{
int f;
+ struct mode Mode;
sigret_t (*sigalrm)__P(SIGPROTOARG);
sigalrm = signal(SIGALRM, SigAlrmDummy);
alarm(2);
+
/* this open only succeeds, if real uid is allowed */
- if ((f = secopen(line, O_RDWR | O_NONBLOCK, 0)) == -1)
+ if ((f = secopen(line, O_RDWR | O_NONBLOCK | O_NOCTTY, 0)) == -1)
{
- Msg(errno, "Cannot open line '%s' for R/W", line);
+ if (errno == EINTR)
+ Msg(0, "Cannot open line '%s' for R/W: open() blocked, aborted.", line);
+ else
+ Msg(errno, "Cannot open line '%s' for R/W", line);
alarm(0);
signal(SIGALRM, sigalrm);
return -1;
}
-#ifdef I_POP
+ if (!isatty(f))
+ {
+ Msg(0, "'%s' is not a tty", line);
+ alarm(0);
+ signal(SIGALRM, sigalrm);
+ close(f);
+ return -1;
+ }
+#if defined(I_POP) && defined(POP_TTYMODULES)
debug("OpenTTY I_POP\n");
while (ioctl(f, I_POP, (char *)0) >= 0)
;
@@ -109,7 +154,7 @@ char *line;
errno = 0;
if (ioctl(f, TIOCEXCL, (char *) 0) < 0)
Msg(errno, "%s: ioctl TIOCEXCL failed", line);
- debug3("%d %d %d\n", (int)getuid(), (int)geteuid(), (int)getpid());
+ debug3("%d %d %d\n", getuid(), geteuid(), getpid());
debug2("%s TIOCEXCL errno %d\n", line, errno);
#endif /* TIOCEXCL */
/*
@@ -119,22 +164,18 @@ char *line;
if (display)
{
debug1("OpenTTY: using mode of display for %s\n", line);
- SetTTY(f, &D_NewMode);
-#ifdef DEBUG
- DebugTTY(&D_NewMode);
-#endif
+ Mode = D_NewMode;
}
else
-#endif
- {
- struct mode Mode;
-
- InitTTY(&Mode, TTY_FLAG_PLAIN);
+#endif
+ InitTTY(&Mode, W_TYPE_PLAIN);
+
+ SttyMode(&Mode, opt);
#ifdef DEBUG
- DebugTTY(&Mode);
+ DebugTTY(&Mode);
#endif
- SetTTY(f, &Mode);
- }
+ SetTTY(f, &Mode);
+
brktty(f);
alarm(0);
signal(SIGALRM, sigalrm);
@@ -152,7 +193,7 @@ int intrc, origintrc = VDISABLE; /* display? */
#else
int intrc, origintrc = -1; /* display? */
#endif
-static startc, stopc; /* display? */
+static int startc, stopc; /* display? */
void
@@ -165,151 +206,196 @@ int ttyflag;
/* struct termios tio
* defaults, as seen on SunOS 4.1.3
*/
- debug1("InitTTY: POSIX: termios defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
+ debug1("InitTTY: POSIX: termios defaults based on SunOS 4.1.3, but better (%d)\n", ttyflag);
#if defined(BRKINT)
- m->tio.c_iflag |= BRKINT;
+ m->tio.c_iflag |= BRKINT;
#endif /* BRKINT */
#if defined(IGNPAR)
- m->tio.c_iflag |= IGNPAR;
+ m->tio.c_iflag |= IGNPAR;
#endif /* IGNPAR */
-#if defined(ISTRIP)
- m->tio.c_iflag |= ISTRIP;
-#endif /* ISTRIP */
+/* IF{ISTRIP} m->tio.c_iflag |= ISTRIP; may be needed, let's try. jw. */
#if defined(IXON)
- m->tio.c_iflag |= IXON;
+ m->tio.c_iflag |= IXON;
#endif /* IXON */
-#if defined(IMAXBEL)
- m->tio.c_iflag |= IMAXBEL;
-#endif /* IMAXBEL */
+/* IF{IMAXBEL} m->tio.c_iflag |= IMAXBEL; sorry, this one is ridiculus. jw */
if (!ttyflag) /* may not even be good for ptys.. */
{
#if defined(ICRNL)
- m->tio.c_iflag |= ICRNL;
+ m->tio.c_iflag |= ICRNL;
#endif /* ICRNL */
#if defined(ONLCR)
- m->tio.c_oflag |= ONLCR;
+ m->tio.c_oflag |= ONLCR;
#endif /* ONLCR */
#if defined(TAB3)
- m->tio.c_oflag |= TAB3;
+ m->tio.c_oflag |= TAB3;
#endif /* TAB3 */
-#if defined(PARENB)
- m->tio.c_cflag |= PARENB;
-#endif /* PARENB */
+#if defined(OXTABS)
+ m->tio.c_oflag |= OXTABS;
+#endif /* OXTABS */
+/* IF{PARENB} m->tio.c_cflag |= PARENB; nah! jw. */
}
#if defined(OPOST)
- m->tio.c_oflag |= OPOST;
+ m->tio.c_oflag |= OPOST;
#endif /* OPOST */
+/*
+ * Or-ing the speed into c_cflags is dangerous.
+ * It breaks on bsdi, where c_ispeed and c_ospeed are extra longs.
+ *
+ * IF{B9600} m->tio.c_cflag |= B9600;
+ * IF{IBSHIFT) && defined(B9600} m->tio.c_cflag |= B9600 << IBSHIFT;
+ *
+ * We hope that we have the posix calls to do it right:
+ * If these are not available you might try the above.
+ */
#if defined(B9600)
- m->tio.c_cflag |= B9600;
+ cfsetospeed(&m->tio, B9600);
#endif /* B9600 */
+#if defined(B9600)
+ cfsetispeed(&m->tio, B9600);
+#endif /* B9600 */
+
#if defined(CS8)
- m->tio.c_cflag |= CS8;
+ m->tio.c_cflag |= CS8;
#endif /* CS8 */
#if defined(CREAD)
- m->tio.c_cflag |= CREAD;
+ m->tio.c_cflag |= CREAD;
#endif /* CREAD */
-#if defined(IBSHIFT) && defined(B9600)
- m->tio.c_cflag |= B9600 << IBSHIFT;
-#endif /* IBSHIFT) && defined(B9600 */
-/* IF{CLOCAL} m->tio.c_cflag |= CLOCAL; */
+#if defined(CLOCAL)
+ m->tio.c_cflag |= CLOCAL;
+#endif /* CLOCAL */
#if defined(ECHOCTL)
- m->tio.c_lflag |= ECHOCTL;
+ m->tio.c_lflag |= ECHOCTL;
#endif /* ECHOCTL */
#if defined(ECHOKE)
- m->tio.c_lflag |= ECHOKE;
+ m->tio.c_lflag |= ECHOKE;
#endif /* ECHOKE */
if (!ttyflag)
{
#if defined(ISIG)
- m->tio.c_lflag |= ISIG;
+ m->tio.c_lflag |= ISIG;
#endif /* ISIG */
#if defined(ICANON)
- m->tio.c_lflag |= ICANON;
+ m->tio.c_lflag |= ICANON;
#endif /* ICANON */
#if defined(ECHO)
- m->tio.c_lflag |= ECHO;
+ m->tio.c_lflag |= ECHO;
#endif /* ECHO */
}
#if defined(ECHOE)
- m->tio.c_lflag |= ECHOE;
+ m->tio.c_lflag |= ECHOE;
#endif /* ECHOE */
#if defined(ECHOK)
- m->tio.c_lflag |= ECHOK;
+ m->tio.c_lflag |= ECHOK;
#endif /* ECHOK */
#if defined(IEXTEN)
- m->tio.c_lflag |= IEXTEN;
+ m->tio.c_lflag |= IEXTEN;
#endif /* IEXTEN */
-#if defined(VINTR) && VINTR < MAXCC
- m->tio.c_cc[VINTR] = Ctrl('C');
+#if defined(VINTR)
+#if (VINTR < MAXCC)
+ m->tio.c_cc[VINTR] = Ctrl('C');
+#endif
#endif /* VINTR */
-#if defined(VQUIT) && VQUIT < MAXCC
- m->tio.c_cc[VQUIT] = Ctrl('\\');
+#if defined(VQUIT)
+#if (VQUIT < MAXCC)
+ m->tio.c_cc[VQUIT] = Ctrl('\\');
+#endif
#endif /* VQUIT */
-#if defined(VERASE) && VERASE < MAXCC
- m->tio.c_cc[VERASE] = 0x7f; /* DEL */
+#if defined(VERASE)
+#if (VERASE < MAXCC)
+ m->tio.c_cc[VERASE] = 0x7f; /* DEL */
+#endif
#endif /* VERASE */
-#if defined(VKILL) && VKILL < MAXCC
- m->tio.c_cc[VKILL] = Ctrl('H');
+#if defined(VKILL)
+#if (VKILL < MAXCC)
+ m->tio.c_cc[VKILL] = Ctrl('H');
+#endif
#endif /* VKILL */
-#if defined(VEOF) && VEOF < MAXCC
- m->tio.c_cc[VEOF] = Ctrl('D');
+#if defined(VEOF)
+#if (VEOF < MAXCC)
+ m->tio.c_cc[VEOF] = Ctrl('D');
+#endif
#endif /* VEOF */
-#if defined(VEOL) && VEOL < MAXCC
- m->tio.c_cc[VEOL] = 0000;
+#if defined(VEOL)
+#if (VEOL < MAXCC)
+ m->tio.c_cc[VEOL] = 0000;
+#endif
#endif /* VEOL */
-#if defined(VEOL2) && VEOL2 < MAXCC
- m->tio.c_cc[VEOL2] = 0000;
+#if defined(VEOL2)
+#if (VEOL2 < MAXCC)
+ m->tio.c_cc[VEOL2] = 0000;
+#endif
#endif /* VEOL2 */
-#if defined(VSWTCH) && VSWTCH < MAXCC
- m->tio.c_cc[VSWTCH] = 0000;
+#if defined(VSWTCH)
+#if (VSWTCH < MAXCC)
+ m->tio.c_cc[VSWTCH] = 0000;
+#endif
#endif /* VSWTCH */
-#if defined(VSTART) && VSTART < MAXCC
- m->tio.c_cc[VSTART] = Ctrl('Q');
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ m->tio.c_cc[VSTART] = Ctrl('Q');
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- m->tio.c_cc[VSTOP] = Ctrl('S');
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ m->tio.c_cc[VSTOP] = Ctrl('S');
+#endif
#endif /* VSTOP */
-#if defined(VSUSP) && VSUSP < MAXCC
- m->tio.c_cc[VSUSP] = Ctrl('Z');
+#if defined(VSUSP)
+#if (VSUSP < MAXCC)
+ m->tio.c_cc[VSUSP] = Ctrl('Z');
+#endif
#endif /* VSUSP */
-#if defined(VDSUSP) && VDSUSP < MAXCC
- m->tio.c_cc[VDSUSP] = Ctrl('Y');
+#if defined(VDSUSP)
+#if (VDSUSP < MAXCC)
+ m->tio.c_cc[VDSUSP] = Ctrl('Y');
+#endif
#endif /* VDSUSP */
-#if defined(VREPRINT) && VREPRINT < MAXCC
- m->tio.c_cc[VREPRINT] = Ctrl('R');
+#if defined(VREPRINT)
+#if (VREPRINT < MAXCC)
+ m->tio.c_cc[VREPRINT] = Ctrl('R');
+#endif
#endif /* VREPRINT */
-#if defined(VDISCARD) && VDISCARD < MAXCC
- m->tio.c_cc[VDISCARD] = Ctrl('O');
+#if defined(VDISCARD)
+#if (VDISCARD < MAXCC)
+ m->tio.c_cc[VDISCARD] = Ctrl('O');
+#endif
#endif /* VDISCARD */
-#if defined(VWERASE) && VWERASE < MAXCC
- m->tio.c_cc[VWERASE] = Ctrl('W');
+#if defined(VWERASE)
+#if (VWERASE < MAXCC)
+ m->tio.c_cc[VWERASE] = Ctrl('W');
+#endif
#endif /* VWERASE */
-#if defined(VLNEXT) && VLNEXT < MAXCC
- m->tio.c_cc[VLNEXT] = Ctrl('V');
+#if defined(VLNEXT)
+#if (VLNEXT < MAXCC)
+ m->tio.c_cc[VLNEXT] = Ctrl('V');
+#endif
#endif /* VLNEXT */
-#if defined(VSTATUS) && VSTATUS < MAXCC
- m->tio.c_cc[VSTATUS] = Ctrl('T');
+#if defined(VSTATUS)
+#if (VSTATUS < MAXCC)
+ m->tio.c_cc[VSTATUS] = Ctrl('T');
+#endif
#endif /* VSTATUS */
if (ttyflag)
{
- m->tio.c_cc[VMIN] = 1;
- m->tio.c_cc[VTIME] = 0;
+ m->tio.c_cc[VMIN] = TTYVMIN;
+ m->tio.c_cc[VTIME] = TTYVTIME;
}
-# ifdef hpux
+
+# ifdef HPUX_LTCHARS_HACK
m->m_ltchars.t_suspc = Ctrl('Z');
m->m_ltchars.t_dsuspc = Ctrl('Y');
m->m_ltchars.t_rprntc = Ctrl('R');
m->m_ltchars.t_flushc = Ctrl('O');
m->m_ltchars.t_werasc = Ctrl('W');
m->m_ltchars.t_lnextc = Ctrl('V');
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* POSIX */
@@ -323,87 +409,109 @@ int ttyflag;
* local: enable signals, erase/kill processing, echo on.
*/
#if defined(ISTRIP)
- m->tio.c_iflag |= ISTRIP;
+ m->tio.c_iflag |= ISTRIP;
#endif /* ISTRIP */
#if defined(IXON)
- m->tio.c_iflag |= IXON;
+ m->tio.c_iflag |= IXON;
#endif /* IXON */
#if defined(OPOST)
- m->tio.c_oflag |= OPOST;
+ m->tio.c_oflag |= OPOST;
#endif /* OPOST */
if (!ttyflag) /* may not even be good for ptys.. */
{
#if defined(ICRNL)
- m->tio.c_iflag |= ICRNL;
+ m->tio.c_iflag |= ICRNL;
#endif /* ICRNL */
#if defined(ONLCR)
- m->tio.c_oflag |= ONLCR;
+ m->tio.c_oflag |= ONLCR;
#endif /* ONLCR */
#if defined(TAB3)
- m->tio.c_oflag |= TAB3;
+ m->tio.c_oflag |= TAB3;
#endif /* TAB3 */
}
+#ifdef __bsdi__
+ )-: cannot handle BSDI without POSIX
+#else
#if defined(B9600)
- m->tio.c_cflag = B9600;
+ m->tio.c_cflag = B9600;
#endif /* B9600 */
+#endif
#if defined(CS8)
- m->tio.c_cflag |= CS8;
+ m->tio.c_cflag |= CS8;
#endif /* CS8 */
#if defined(CREAD)
- m->tio.c_cflag |= CREAD;
+ m->tio.c_cflag |= CREAD;
#endif /* CREAD */
if (!ttyflag)
{
#if defined(ISIG)
- m->tio.c_lflag |= ISIG;
+ m->tio.c_lflag |= ISIG;
#endif /* ISIG */
#if defined(ICANON)
- m->tio.c_lflag |= ICANON;
+ m->tio.c_lflag |= ICANON;
#endif /* ICANON */
#if defined(ECHO)
- m->tio.c_lflag |= ECHO;
+ m->tio.c_lflag |= ECHO;
#endif /* ECHO */
}
#if defined(ECHOE)
- m->tio.c_lflag |= ECHOE;
+ m->tio.c_lflag |= ECHOE;
#endif /* ECHOE */
#if defined(ECHOK)
- m->tio.c_lflag |= ECHOK;
+ m->tio.c_lflag |= ECHOK;
#endif /* ECHOK */
-#if defined(VINTR) && VINTR < MAXCC
- m->tio.c_cc[VINTR] = Ctrl('C');
+#if defined(VINTR)
+#if (VINTR < MAXCC)
+ m->tio.c_cc[VINTR] = Ctrl('C');
+#endif
#endif /* VINTR */
-#if defined(VQUIT) && VQUIT < MAXCC
- m->tio.c_cc[VQUIT] = Ctrl('\\');
+#if defined(VQUIT)
+#if (VQUIT < MAXCC)
+ m->tio.c_cc[VQUIT] = Ctrl('\\');
+#endif
#endif /* VQUIT */
-#if defined(VERASE) && VERASE < MAXCC
- m->tio.c_cc[VERASE] = 0177; /* DEL */
+#if defined(VERASE)
+#if (VERASE < MAXCC)
+ m->tio.c_cc[VERASE] = 0177; /* DEL */
+#endif
#endif /* VERASE */
-#if defined(VKILL) && VKILL < MAXCC
- m->tio.c_cc[VKILL] = Ctrl('H');
+#if defined(VKILL)
+#if (VKILL < MAXCC)
+ m->tio.c_cc[VKILL] = Ctrl('H');
+#endif
#endif /* VKILL */
-#if defined(VEOF) && VEOF < MAXCC
- m->tio.c_cc[VEOF] = Ctrl('D');
+#if defined(VEOF)
+#if (VEOF < MAXCC)
+ m->tio.c_cc[VEOF] = Ctrl('D');
+#endif
#endif /* VEOF */
-#if defined(VEOL) && VEOL < MAXCC
- m->tio.c_cc[VEOL] = 0377;
+#if defined(VEOL)
+#if (VEOL < MAXCC)
+ m->tio.c_cc[VEOL] = 0377;
+#endif
#endif /* VEOL */
-#if defined(VEOL2) && VEOL2 < MAXCC
- m->tio.c_cc[VEOL2] = 0377;
+#if defined(VEOL2)
+#if (VEOL2 < MAXCC)
+ m->tio.c_cc[VEOL2] = 0377;
+#endif
#endif /* VEOL2 */
-#if defined(VSWTCH) && VSWTCH < MAXCC
- m->tio.c_cc[VSWTCH] = 0000;
+#if defined(VSWTCH)
+#if (VSWTCH < MAXCC)
+ m->tio.c_cc[VSWTCH] = 0000;
+#endif
#endif /* VSWTCH */
+
if (ttyflag)
- {
- m->tio.c_cc[VMIN] = 1;
- m->tio.c_cc[VTIME] = 0;
- }
+ {
+ m->tio.c_cc[VMIN] = TTYVMIN;
+ m->tio.c_cc[VTIME] = TTYVTIME;
+ }
+
# else /* TERMIO */
debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
m->m_ttyb.sg_ispeed = B9600;
@@ -413,13 +521,13 @@ int ttyflag;
if (!ttyflag)
m->m_ttyb.sg_flags = CRMOD | ECHO
#if defined(ANYP)
- | ANYP
+ | ANYP
#endif /* ANYP */
;
else
m->m_ttyb.sg_flags = CBREAK
#if defined(ANYP)
- | ANYP
+ | ANYP
#endif /* ANYP */
;
@@ -438,33 +546,33 @@ int ttyflag;
m->m_ltchars.t_lnextc = Ctrl('V');
#if defined(NTTYDISC)
- m->m_ldisc = NTTYDISC;
+ m->m_ldisc = NTTYDISC;
#endif /* NTTYDISC */
m->m_lmode = 0
#if defined(LDECCTQ)
- | LDECCTQ
+ | LDECCTQ
#endif /* LDECCTQ */
#if defined(LCTLECH)
- | LCTLECH
+ | LCTLECH
#endif /* LCTLECH */
#if defined(LPASS8)
- | LPASS8
+ | LPASS8
#endif /* LPASS8 */
#if defined(LCRTKIL)
- | LCRTKIL
+ | LCRTKIL
#endif /* LCRTKIL */
#if defined(LCRTERA)
- | LCRTERA
+ | LCRTERA
#endif /* LCRTERA */
#if defined(LCRTBS)
- | LCRTBS
+ | LCRTBS
#endif /* LCRTBS */
-;
+ ;
# endif /* TERMIO */
#endif /* POSIX */
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
m->m_jtchars.t_ascii = 'J';
m->m_jtchars.t_kanji = 'B';
m->m_knjmode = KM_ASCII | KM_SYSSJIS;
@@ -479,7 +587,7 @@ struct mode *mp;
errno = 0;
#ifdef POSIX
tcsetattr(fd, TCSADRAIN, &mp->tio);
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars);
# endif
#else
@@ -502,7 +610,7 @@ struct mode *mp;
ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars); /* moved here for apollo. jw */
# endif
#endif
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
ioctl(fd, TIOCKSETC, &mp->m_jtchars);
ioctl(fd, TIOCKSET, &mp->m_knjmode);
#endif
@@ -518,7 +626,7 @@ struct mode *mp;
errno = 0;
#ifdef POSIX
tcgetattr(fd, &mp->tio);
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
# endif
#else
@@ -546,7 +654,7 @@ struct mode *mp;
ioctl(fd, TIOCGETD, (char *)&mp->m_ldisc);
# endif
#endif
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
ioctl(fd, TIOCKGETC, &mp->m_jtchars);
ioctl(fd, TIOCKGET, &mp->m_knjmode);
#endif
@@ -554,9 +662,13 @@ struct mode *mp;
Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
}
+/*
+ * needs interrupt = iflag and flow = d->d_flow
+ */
void
-SetMode(op, np)
+SetMode(op, np, flow, interrupt)
struct mode *op, *np;
+int flow, interrupt;
{
*np = *op;
@@ -567,17 +679,21 @@ struct mode *op, *np;
np->tio.c_line = 0;
# endif
#if defined(ICRNL)
- np->tio.c_iflag &= ~ICRNL;
+ np->tio.c_iflag &= ~ICRNL;
#endif /* ICRNL */
+#if defined(ISTRIP)
+ np->tio.c_iflag &= ~ISTRIP;
+#endif /* ISTRIP */
#if defined(ONLCR)
- np->tio.c_oflag &= ~ONLCR;
+ np->tio.c_oflag &= ~ONLCR;
#endif /* ONLCR */
np->tio.c_lflag &= ~(ICANON | ECHO);
/*
* From Andrew Myers (andru@tonic.lcs.mit.edu)
+ * to avoid ^V^V-Problem on OSF1
*/
#if defined(IEXTEN)
- np->tio.c_lflag &= ~IEXTEN;
+ np->tio.c_lflag &= ~IEXTEN;
#endif /* IEXTEN */
/*
@@ -589,23 +705,31 @@ struct mode *op, *np;
* tty) and forwards it to the master [kill(MasterPid, SIGINT)].
* Marc Boucher (marc@CAM.ORG)
*/
- if (iflag)
+ if (interrupt)
np->tio.c_lflag |= ISIG;
else
np->tio.c_lflag &= ~ISIG;
/*
* careful, careful catche monkey..
* never set VMIN and VTIME to zero, if you want blocking io.
+ *
+ * We may want to do a VMIN > 0, VTIME > 0 read on the ptys too, to
+ * reduce interrupt frequency. But then we would not know how to
+ * handle read returning 0. jw.
*/
np->tio.c_cc[VMIN] = 1;
np->tio.c_cc[VTIME] = 0;
-#if defined(VSTART) && VSTART < MAXCC
- startc = op->tio.c_cc[VSTART];
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ startc = op->tio.c_cc[VSTART];
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- stopc = op->tio.c_cc[VSTOP];
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ stopc = op->tio.c_cc[VSTOP];
+#endif
#endif /* VSTOP */
- if (iflag)
+ if (interrupt)
origintrc = intrc = op->tio.c_cc[VINTR];
else
{
@@ -613,57 +737,79 @@ struct mode *op, *np;
intrc = np->tio.c_cc[VINTR] = VDISABLE;
}
np->tio.c_cc[VQUIT] = VDISABLE;
- if (D_flow == 0)
+ if (flow == 0)
{
np->tio.c_cc[VINTR] = VDISABLE;
-#if defined(VSTART) && VSTART < MAXCC
- np->tio.c_cc[VSTART] = VDISABLE;
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ np->tio.c_cc[VSTART] = VDISABLE;
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- np->tio.c_cc[VSTOP] = VDISABLE;
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ np->tio.c_cc[VSTOP] = VDISABLE;
+#endif
#endif /* VSTOP */
np->tio.c_iflag &= ~IXON;
}
-#if defined(VDISCARD) && VDISCARD < MAXCC
- np->tio.c_cc[VDISCARD] = VDISABLE;
+#if defined(VDISCARD)
+#if (VDISCARD < MAXCC)
+ np->tio.c_cc[VDISCARD] = VDISABLE;
+#endif
#endif /* VDISCARD */
-#if defined(VLNEXT) && VLNEXT < MAXCC
- np->tio.c_cc[VLNEXT] = VDISABLE;
+#if defined(VLNEXT)
+#if (VLNEXT < MAXCC)
+ np->tio.c_cc[VLNEXT] = VDISABLE;
+#endif
#endif /* VLNEXT */
-#if defined(VSTATUS) && VSTATUS < MAXCC
- np->tio.c_cc[VSTATUS] = VDISABLE;
+#if defined(VSTATUS)
+#if (VSTATUS < MAXCC)
+ np->tio.c_cc[VSTATUS] = VDISABLE;
+#endif
#endif /* VSTATUS */
-#if defined(VSUSP) && VSUSP < MAXCC
- np->tio.c_cc[VSUSP] = VDISABLE;
+#if defined(VSUSP)
+#if (VSUSP < MAXCC)
+ np->tio.c_cc[VSUSP] = VDISABLE;
+#endif
#endif /* VSUSP */
-#if defined(VERASE) && VERASE < MAXCC
- np->tio.c_cc[VERASE] = VDISABLE;
+#if defined(VERASE)
+#if (VERASE < MAXCC)
+ np->tio.c_cc[VERASE] = VDISABLE;
+#endif
#endif /* VERASE */
-#if defined(VKILL) && VKILL < MAXCC
- np->tio.c_cc[VKILL] = VDISABLE;
+#if defined(VKILL)
+#if (VKILL < MAXCC)
+ np->tio.c_cc[VKILL] = VDISABLE;
+#endif
#endif /* VKILL */
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
np->m_ltchars.t_suspc = VDISABLE;
np->m_ltchars.t_dsuspc = VDISABLE;
np->m_ltchars.t_rprntc = VDISABLE;
np->m_ltchars.t_flushc = VDISABLE;
np->m_ltchars.t_werasc = VDISABLE;
np->m_ltchars.t_lnextc = VDISABLE;
-# else /* hpux */
-#if defined(VDSUSP) && VDSUSP < MAXCC
- np->tio.c_cc[VDSUSP] = VDISABLE;
+# else /* HPUX_LTCHARS_HACK */
+#if defined(VDSUSP)
+#if (VDSUSP < MAXCC)
+ np->tio.c_cc[VDSUSP] = VDISABLE;
+#endif
#endif /* VDSUSP */
-#if defined(VREPRINT) && VREPRINT < MAXCC
- np->tio.c_cc[VREPRINT] = VDISABLE;
+#if defined(VREPRINT)
+#if (VREPRINT < MAXCC)
+ np->tio.c_cc[VREPRINT] = VDISABLE;
+#endif
#endif /* VREPRINT */
-#if defined(VWERASE) && VWERASE < MAXCC
- np->tio.c_cc[VWERASE] = VDISABLE;
+#if defined(VWERASE)
+#if (VWERASE < MAXCC)
+ np->tio.c_cc[VWERASE] = VDISABLE;
+#endif
#endif /* VWERASE */
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* TERMIO || POSIX */
startc = op->m_tchars.t_startc;
stopc = op->m_tchars.t_stopc;
- if (iflag)
+ if (interrupt)
origintrc = intrc = op->m_tchars.t_intrc;
else
{
@@ -677,7 +823,7 @@ struct mode *op, *np;
np->m_ttyb.sg_flags |= CS_8BITS;
# endif
np->m_tchars.t_quitc = -1;
- if (D_flow == 0)
+ if (flow == 0)
{
np->m_tchars.t_intrc = -1;
np->m_tchars.t_startc = -1;
@@ -690,6 +836,7 @@ struct mode *op, *np;
#endif /* defined(TERMIO) || defined(POSIX) */
}
+/* operates on display */
void
SetFlow(on)
int on;
@@ -701,22 +848,30 @@ int on;
if (on)
{
D_NewMode.tio.c_cc[VINTR] = intrc;
-#if defined(VSTART) && VSTART < MAXCC
- D_NewMode.tio.c_cc[VSTART] = startc;
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ D_NewMode.tio.c_cc[VSTART] = startc;
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- D_NewMode.tio.c_cc[VSTOP] = stopc;
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ D_NewMode.tio.c_cc[VSTOP] = stopc;
+#endif
#endif /* VSTOP */
D_NewMode.tio.c_iflag |= IXON;
}
else
{
D_NewMode.tio.c_cc[VINTR] = VDISABLE;
-#if defined(VSTART) && VSTART < MAXCC
- D_NewMode.tio.c_cc[VSTART] = VDISABLE;
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ D_NewMode.tio.c_cc[VSTART] = VDISABLE;
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- D_NewMode.tio.c_cc[VSTOP] = VDISABLE;
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ D_NewMode.tio.c_cc[VSTOP] = VDISABLE;
+#endif
#endif /* VSTOP */
D_NewMode.tio.c_iflag &= ~IXON;
}
@@ -745,6 +900,97 @@ int on;
D_flow = on;
}
+/* parse commands from opt and modify m */
+int
+SttyMode(m, opt)
+struct mode *m;
+char *opt;
+{
+ static const char sep[] = " \t:;,";
+
+ if (!opt)
+ return 0;
+
+ while (*opt)
+ {
+ while (index(sep, *opt)) opt++;
+ if (*opt >= '0' && *opt <= '9')
+ {
+ if (SetBaud(m, atoi(opt), atoi(opt)))
+ return -1;
+ }
+ else if (!strncmp("cs7", opt, 3))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_cflag &= ~CSIZE;
+ m->tio.c_cflag |= CS7;
+#else
+ m->m_lmode &= ~LPASS8;
+#endif
+ }
+ else if (!strncmp("cs8", opt, 3))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_cflag &= ~CSIZE;
+ m->tio.c_cflag |= CS8;
+#else
+ m->m_lmode |= LPASS8;
+#endif
+ }
+ else if (!strncmp("istrip", opt, 6))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag |= ISTRIP;
+#else
+ m->m_lmode &= ~LPASS8;
+#endif
+ }
+ else if (!strncmp("-istrip", opt, 7))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag &= ~ISTRIP;
+#else
+ m->m_lmode |= LPASS8;
+#endif
+ }
+ else if (!strncmp("ixon", opt, 4))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag |= IXON;
+#else
+ debug("SttyMode: no ixon in old bsd land.\n");
+#endif
+ }
+ else if (!strncmp("-ixon", opt, 5))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag &= ~IXON;
+#else
+ debug("SttyMode: no -ixon in old bsd land.\n");
+#endif
+ }
+ else if (!strncmp("ixoff", opt, 5))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag |= IXOFF;
+#else
+ m->m_ttyb.sg_flags |= TANDEM;
+#endif
+ }
+ else if (!strncmp("-ixoff", opt, 6))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag &= ~IXOFF;
+#else
+ m->m_ttyb.sg_flags &= ~TANDEM;
+#endif
+ }
+ else
+ return -1;
+ while (*opt && !index(sep, *opt)) opt++;
+ }
+ return 0;
+}
/*
* Job control handling
@@ -792,6 +1038,9 @@ int fd;
/* The next lines should be obsolete. Can anybody check if they
* are really needed on the BSD platforms?
+ *
+ * this is to avoid the message:
+ * fgtty: Not a typewriter (25)
*/
# if defined(__osf__) || (BSD >= 199103) || defined(ISC)
setsid(); /* should be already done */
@@ -818,19 +1067,154 @@ int fd;
return 0;
}
+/*
+ * The alm boards on our sparc center 1000 have a lousy driver.
+ * We cannot generate long breaks unless we use the most ugly form
+ * of ioctls. jw.
+ */
+#ifdef POSIX
+int breaktype = 2;
+#else /* POSIX */
+# ifdef TCSBRK
+int breaktype = 1;
+# else
+int breaktype = 0;
+# endif
+#endif /* POSIX */
+
+#if defined(sun) && !defined(SVR4)
+# define HAVE_SUPER_TCSENDBREAK
+#endif
+
+/*
+ * type:
+ * 0: TIOCSBRK / TIOCCBRK
+ * 1: TCSBRK
+ * 2: tcsendbreak()
+ * n: approximate duration in 1/4 seconds.
+ */
+static void
+DoSendBreak(fd, n, type)
+int fd, n, type;
+{
+ switch (type)
+ {
+ case 2: /* tcsendbreak() =============================== */
+#ifdef POSIX
+# ifdef HAVE_SUPER_TCSENDBREAK
+ /* There is one rare case that I have tested, where tcsendbreak works
+ * really great: this was an alm driver that came with SunOS 4.1.3
+ * If you have this one, define the above symbol.
+ * here we can use the second parameter to specify the duration.
+ */
+ debug2("tcsendbreak(fd=%d, %d)\n", fd, n);
+ if (tcsendbreak(fd, n) < 0)
+ Msg(errno, "cannot send BREAK (tcsendbreak)");
+# else
+ /*
+ * here we hope, that multiple calls to tcsendbreak() can
+ * be concatenated to form a long break, as we do not know
+ * what exact interpretation the second parameter has:
+ *
+ * - sunos 4: duration in quarter seconds
+ * - sunos 5: 0 a short break, nonzero a tcdrain()
+ * - hpux, irix: ignored
+ * - mot88: duration in milliseconds
+ * - aix: duration in milliseconds, but 0 is 25 milliseconds.
+ */
+ debug2("%d * tcsendbreak(fd=%d, 0)\n", n, fd);
+ {
+ int i;
+
+ for (i = 0; i < n; i++)
+ if (tcsendbreak(fd, 0) < 0)
+ {
+ Msg(errno, "cannot send BREAK (tcsendbreak SVR4)");
+ return;
+ }
+ }
+# endif
+#else /* POSIX */
+ Msg(0, "tcsendbreak() not available, change breaktype");
+#endif /* POSIX */
+ break;
+
+ case 1: /* TCSBRK ======================================= */
+#ifdef TCSBRK
+ if (!n)
+ n++;
+ /*
+ * Here too, we assume that short breaks can be concatenated to
+ * perform long breaks. But for SOLARIS, this is not true, of course.
+ */
+ debug2("%d * TCSBRK fd=%d\n", n, fd);
+ {
+ int i;
+
+ for (i = 0; i < n; i++)
+ if (ioctl(fd, TCSBRK, (char *)0) < 0)
+ {
+ Msg(errno, "Cannot send BREAK (TCSBRK)");
+ return;
+ }
+ }
+#else /* TCSBRK */
+ Msg(0, "TCSBRK not available, change breaktype");
+#endif /* TCSBRK */
+ break;
+
+ case 0: /* TIOCSBRK / TIOCCBRK ========================== */
+#if defined(TIOCSBRK) && defined(TIOCCBRK)
+ /*
+ * This is very rude. Screen actively celebrates the break.
+ * But it may be the only save way to issue long breaks.
+ */
+ debug("TIOCSBRK TIOCCBRK\n");
+ if (ioctl(fd, TIOCSBRK, (char *)0) < 0)
+ {
+ Msg(errno, "Can't send BREAK (TIOCSBRK)");
+ return;
+ }
+ sleep1000(n ? n * 250 : 250);
+ if (ioctl(fd, TIOCCBRK, (char *)0) < 0)
+ {
+ Msg(errno, "BREAK stuck!!! -- HELP! (TIOCCBRK)");
+ return;
+ }
+#else /* TIOCSBRK && TIOCCBRK */
+ Msg(0, "TIOCSBRK/CBRK not available, change breaktype");
+#endif /* TIOCSBRK && TIOCCBRK */
+ break;
+
+ default: /* unknown ========================== */
+ Msg(0, "Internal SendBreak error: method %d unknown", type);
+ }
+}
/*
* Send a break for n * 0.25 seconds. Tty must be PLAIN.
+ * The longest possible break allowed here is 15 seconds.
*/
-void SendBreak(wp, n, closeopen)
+void
+SendBreak(wp, n, closeopen)
struct win *wp;
int n, closeopen;
{
- if ((wp->w_t.flags & TTY_FLAG_PLAIN) == 0)
+ sigret_t (*sigalrm)__P(SIGPROTOARG);
+
+#ifdef BUILTIN_TELNET
+ if (wp->w_type == W_TYPE_TELNET)
+ {
+ TelBreak(wp);
+ return;
+ }
+#endif
+ if (wp->w_type != W_TYPE_PLAIN)
return;
debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
+
#ifdef POSIX
(void) tcflush(wp->w_ptyfd, TCIOFLUSH);
#else
@@ -838,11 +1222,12 @@ int n, closeopen;
(void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
# endif /* TIOCFLUSH */
#endif /* POSIX */
+
if (closeopen)
{
close(wp->w_ptyfd);
- sleep((n + 3) / 4);
- if ((wp->w_ptyfd = OpenTTY(wp->w_tty)) < 1)
+ sleep1000(n ? n * 250 : 250);
+ if ((wp->w_ptyfd = OpenTTY(wp->w_tty, wp->w_cmdargs[1])) < 1)
{
Msg(0, "Ouch, cannot reopen line %s, please try harder", wp->w_tty);
return;
@@ -851,56 +1236,56 @@ int n, closeopen;
}
else
{
-#ifdef POSIX
- debug("tcsendbreak\n");
- if (tcsendbreak(wp->w_ptyfd, n) < 0)
- {
- Msg(errno, "cannot send BREAK");
- return;
- }
-#else
- if (!n)
- n++;
-# ifdef TCSBRK
- debug("TCSBRK\n");
- {
- int i;
- for (i = 0; i < n; i++)
- if (ioctl(wp->w_ptyfd, TCSBRK, (char *)0) < 0)
- {
- Msg(errno, "Cannot send BREAK");
- return;
- }
- }
-# else /* TCSBRK */
-# if defined(TIOCSBRK) && defined(TIOCCBRK)
- debug("TIOCSBRK TIOCCBRK\n");
- if (ioctl(wp->w_ptyfd, TIOCSBRK, (char *)0) < 0)
- {
- Msg(errno, "Can't send BREAK");
- return;
- }
- sleep((n + 3) / 4);
- if (ioctl(wp->w_ptyfd, TIOCCBRK, (char *)0) < 0)
- {
- Msg(errno, "BREAK stuck!!! -- HELP!");
- return;
- }
-# else /* TIOCSBRK && TIOCCBRK */
- Msg(0, "Break not simulated yet");
- return;
-# endif /* TIOCSBRK && TIOCCBRK */
-# endif /* TCSBRK */
-#endif /* POSIX */
- debug(" broken\n");
+ sigalrm = signal(SIGALRM, SigAlrmDummy);
+ alarm(15);
+
+ DoSendBreak(wp->w_ptyfd, n, breaktype);
+
+ alarm(0);
+ signal(SIGALRM, sigalrm);
}
+ debug(" broken.\n");
}
-
/*
* Console grabbing
*/
+#if !defined(TIOCCONS) && defined(SRIOCSREDIR)
+
+struct event consredir_ev;
+int consredirfd[2] = {-1, -1};
+
+static void
+consredir_readev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ char *p, *n, buf[256];
+ int l;
+
+ if (!console_window || (l = read(consredirfd[0], buf, sizeof(buf))) <= 0)
+ {
+ close(consredirfd[0]);
+ close(consredirfd[1]);
+ consredirfd[0] = consredirfd[1] = -1;
+ evdeq(ev);
+ return;
+ }
+ for (p = n = buf; l > 0; n++, l--)
+ if (*n == '\n')
+ {
+ if (n > p)
+ WriteString(console_window, p, n - p);
+ WriteString(console_window, "\r\n", 2);
+ p = n + 1;
+ }
+ if (n > p)
+ WriteString(console_window, p, n - p);
+}
+
+#endif
+
/*ARGSUSED*/
int
TtyGrabConsole(fd, on, rc_name)
@@ -908,12 +1293,32 @@ int fd, on;
char *rc_name;
{
#ifdef TIOCCONS
- char *slave;
- int sfd = -1, ret = 0;
struct display *d;
+ int ret = 0;
+ int sfd = -1;
+
+ if (on < 0)
+ return; /* pty close will ungrab */
+ if (on)
+ {
+ if (displays == 0)
+ {
+ Msg(0, "I need a display");
+ return -1;
+ }
+ for (d = displays; d; d = d->d_next)
+ if (strcmp(d->d_usertty, "/dev/console") == 0)
+ break;
+ if (d)
+ {
+ Msg(0, "too dangerous - screen is running on /dev/console");
+ return -1;
+ }
+ }
if (!on)
{
+ char *slave;
if ((fd = OpenPTY(&slave)) < 0)
{
Msg(errno, "%s: could not open detach pty master", rc_name);
@@ -926,7 +1331,24 @@ char *rc_name;
return -1;
}
}
- else
+ if (UserContext() == 1)
+ UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
+ ret = UserStatus();
+ if (ret)
+ Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
+ if (!on)
+ {
+ close(sfd);
+ close(fd);
+ }
+ return ret;
+
+#else
+# ifdef SRIOCSREDIR
+ struct display *d;
+ int cfd;
+
+ if (on > 0)
{
if (displays == 0)
{
@@ -942,23 +1364,434 @@ char *rc_name;
return -1;
}
}
- if (UserContext() == 1)
- UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
- ret = UserStatus();
- if (ret)
- Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
- if (!on)
+ if (consredirfd[0] >= 0)
{
- close(sfd);
- close(fd);
+ evdeq(&consredir_ev);
+ close(consredirfd[0]);
+ close(consredirfd[1]);
+ consredirfd[0] = consredirfd[1] = -1;
}
- return ret;
-#else /* TIOCCONS */
- Msg(0, "%s: no TIOCCONS on this machine", rc_name);
+ if (on <= 0)
+ return 0;
+ if ((cfd = secopen("/dev/console", O_RDWR|O_NOCTTY, 0)) == -1)
+ {
+ Msg(errno, "/dev/console");
+ return -1;
+ }
+ if (pipe(consredirfd))
+ {
+ Msg(errno, "pipe");
+ close(cfd);
+ consredirfd[0] = consredirfd[1] = -1;
+ return -1;
+ }
+ if (ioctl(cfd, SRIOCSREDIR, consredirfd[1]))
+ {
+ Msg(errno, "SRIOCSREDIR ioctl");
+ close(cfd);
+ close(consredirfd[0]);
+ close(consredirfd[1]);
+ consredirfd[0] = consredirfd[1] = -1;
+ return -1;
+ }
+
+ consredir_ev.fd = consredirfd[0];
+ consredir_ev.type = EV_READ;
+ consredir_ev.handler = consredir_readev_fn;
+ evenq(&consredir_ev);
+ close(cfd);
+ return 0;
+# else
+ if (on > 0)
+ Msg(0, "%s: don't know how to grab the console", rc_name);
return -1;
-#endif /* TIOCCONS */
+# endif
+#endif
}
+/*
+ * Read modem control lines of a physical tty and write them to buf
+ * in a readable format.
+ * Will not write more than 256 characters to buf.
+ * Returns buf;
+ */
+char *
+TtyGetModemStatus(fd, buf)
+int fd;
+char *buf;
+{
+ char *p = buf;
+#ifdef TIOCGSOFTCAR
+ unsigned int softcar;
+#endif
+#if defined(TIOCMGET) || defined(TIOCMODG)
+ unsigned int mflags;
+#else
+# ifdef MCGETA
+ /* this is yet another interface, found on hpux. grrr */
+ mflag mflags;
+#if defined(MDTR)
+# define TIOCM_DTR MDTR
+#endif /* MDTR */
+#if defined(MRTS)
+# define TIOCM_RTS MRTS
+#endif /* MRTS */
+#if defined(MDSR)
+# define TIOCM_DSR MDSR
+#endif /* MDSR */
+#if defined(MDCD)
+# define TIOCM_CAR MDCD
+#endif /* MDCD */
+#if defined(MRI)
+# define TIOCM_RNG MRI
+#endif /* MRI */
+#if defined(MCTS)
+# define TIOCM_CTS MCTS
+#endif /* MCTS */
+# endif
+#endif
+#if defined(CLOCAL) || defined(CRTSCTS)
+ struct mode mtio; /* screen.h */
+#endif
+#if defined(CRTSCTS) || defined(TIOCM_CTS)
+ int rtscts;
+#endif
+ int clocal;
+
+#if defined(CLOCAL) || defined(CRTSCTS)
+ GetTTY(fd, &mtio);
+#endif
+#ifdef CLOCAL
+ if (mtio.tio.c_cflag & CLOCAL)
+ {
+ clocal = 1;
+ *p++ = '{';
+ }
+ else
+#endif
+ clocal = 0;
+
+#ifdef TIOCM_CTS
+# ifdef CRTSCTS
+ if (!(mtio.tio.c_cflag & CRTSCTS))
+ rtscts = 0;
+ else
+# endif /* CRTSCTS */
+ rtscts = 1;
+#endif /* TIOCM_CTS */
+
+#ifdef TIOCGSOFTCAR
+ if (ioctl(fd, TIOCGSOFTCAR, (char *)&softcar) < 0)
+ softcar = 0;
+#endif
+
+#if defined(TIOCMGET) || defined(TIOCMODG) || defined(MCGETA)
+# ifdef TIOCMGET
+ if (ioctl(fd, TIOCMGET, (char *)&mflags) < 0)
+# else
+# ifdef TIOCMODG
+ if (ioctl(fd, TIOCMODG, (char *)&mflags) < 0)
+# else
+ if (ioctl(fd, TIOCMODG, &mflags) < 0)
+# endif
+# endif
+ {
+#ifdef TIOCGSOFTCAR
+ sprintf(p, "NO-TTY? %s", softcar ? "(CD)" : "CD");
+#else
+ sprintf(p, "NO-TTY?");
+#endif
+ p += strlen(p);
+ }
+ else
+ {
+ char *s;
+# ifdef FANCY_MODEM
+# ifdef TIOCM_LE
+ if (!(mflags & TIOCM_LE))
+ for (s = "!LE "; *s; *p++ = *s++);
+# endif
+# endif /* FANCY_MODEM */
+
+# ifdef TIOCM_RTS
+ s = "!RTS "; if (mflags & TIOCM_RTS) s++;
+ while (*s) *p++ = *s++;
+# endif
+# ifdef TIOCM_CTS
+ if (!rtscts)
+ {
+ *p++ = '(';
+ s = "!CTS) ";
+ }
+ if (mflags & TIOCM_CTS) s++;
+ while (*s) *p++ = *s++;
+# endif
+
+# ifdef TIOCM_DTR
+ s = "!DTR "; if (mflags & TIOCM_DTR) s++;
+ while (*s) *p++ = *s++;
+# endif
+# ifdef TIOCM_DSR
+ s = "!DSR "; if (mflags & TIOCM_DSR) s++;
+ while (*s) *p++ = *s++;
+# endif
+# if defined(TIOCM_CD) || defined(TIOCM_CAR)
+# ifdef TIOCGSOFTCAR
+ if (softcar)
+ {
+ *p++ = '(';
+ s = "!CD) ";
+ }
+ else
+# endif
+ s = "!CD ";
+# ifdef TIOCM_CD
+ if (mflags & TIOCM_CD) s++;
+# else
+ if (mflags & TIOCM_CAR) s++;
+# endif
+ while (*s) *p++ = *s++;
+# endif
+# if defined(TIOCM_RI) || defined(TIOCM_RNG)
+# ifdef TIOCM_RI
+ if (mflags & TIOCM_RI)
+# else
+ if (mflags & TIOCM_RNG)
+# endif
+ for (s = "RI "; *s; *p++ = *s++);
+# endif
+# ifdef FANCY_MODEM
+# ifdef TIOCM_ST
+ s = "!ST "; if (mflags & TIOCM_ST) s++;
+ while (*s) *p++ = *s++;
+# endif
+# ifdef TIOCM_SR
+ s = "!SR "; if (mflags & TIOCM_SR) s++;
+ while (*s) *p++ = *s++;
+# endif
+# endif /* FANCY_MODEM */
+ if (p > buf && p[-1] == ' ')
+ p--;
+ *p = '\0';
+ }
+#else
+# ifdef TIOCGSOFTCAR
+ sprintf(p, " %s", softcar ? "(CD)", "CD");
+ p += strlen(p);
+# endif
+#endif
+ if (clocal)
+ *p++ = '}';
+ *p = '\0';
+ return buf;
+}
+
+/*
+ * Old bsd-ish machines may not have any of the baudrate B... symbols.
+ * We hope to detect them here, so that the btable[] below always has
+ * many entries.
+ */
+#ifndef POSIX
+# ifndef TERMIO
+# if !defined(B9600) && !defined(B2400) && !defined(B1200) && !defined(B300)
+#if !defined(B0)
+#define B0 0
+#endif /* B0 */
+#if !defined(B50)
+#define B50 1
+#endif /* B50 */
+#if !defined(B75)
+#define B75 2
+#endif /* B75 */
+#if !defined(B110)
+#define B110 3
+#endif /* B110 */
+#if !defined(B134)
+#define B134 4
+#endif /* B134 */
+#if !defined(B150)
+#define B150 5
+#endif /* B150 */
+#if !defined(B200)
+#define B200 6
+#endif /* B200 */
+#if !defined(B300)
+#define B300 7
+#endif /* B300 */
+#if !defined(B600)
+#define B600 8
+#endif /* B600 */
+#if !defined(B1200)
+#define B1200 9
+#endif /* B1200 */
+#if !defined(B1800)
+#define B1800 10
+#endif /* B1800 */
+#if !defined(B2400)
+#define B2400 11
+#endif /* B2400 */
+#if !defined(B4800)
+#define B4800 12
+#endif /* B4800 */
+#if !defined(B9600)
+#define B9600 13
+#endif /* B9600 */
+#if !defined(EXTA)
+#define EXTA 14
+#endif /* EXTA */
+#if !defined(EXTB)
+#define EXTB 15
+#endif /* EXTB */
+# endif
+# endif
+#endif
+
+/*
+ * On hpux, idx and sym will be different.
+ * Rumor has it that, we need idx in D_dospeed to make tputs
+ * padding correct.
+ * Frequently used entries come first.
+ */
+static struct baud_values btable[] =
+{
+#if defined(B9600)
+ { 13, 9600, B9600 },
+#endif /* B9600 */
+#if defined(B19200)
+ { 14, 19200, B19200 },
+#endif /* B19200 */
+#if defined(EXTA)
+ { 14, 19200, EXTA },
+#endif /* EXTA */
+#if defined(B38400)
+ { 15, 38400, B38400 },
+#endif /* B38400 */
+#if defined(EXTB)
+ { 15, 38400, EXTB },
+#endif /* EXTB */
+#if defined(B57600)
+ { 16, 57600, B57600 },
+#endif /* B57600 */
+#if defined(B115200)
+ { 17, 115200, B115200 },
+#endif /* B115200 */
+#if defined(B230400)
+ { 18, 230400, B230400 },
+#endif /* B230400 */
+#if defined(B460800)
+ { 19, 460800, B460800 },
+#endif /* B460800 */
+#if defined(B7200)
+ { 13, 7200, B7200 },
+#endif /* B7200 */
+#if defined(B4800)
+ { 12, 4800, B4800 },
+#endif /* B4800 */
+#if defined(B3600)
+ { 12, 3600, B3600 },
+#endif /* B3600 */
+#if defined(B2400)
+ { 11, 2400, B2400 },
+#endif /* B2400 */
+#if defined(B1800)
+ { 10, 1800, B1800 },
+#endif /* B1800 */
+#if defined(B1200)
+ { 9, 1200, B1200 },
+#endif /* B1200 */
+#if defined(B900)
+ { 9, 900, B900 },
+#endif /* B900 */
+#if defined(B600)
+ { 8, 600, B600 },
+#endif /* B600 */
+#if defined(B300)
+ { 7, 300, B300 },
+#endif /* B300 */
+#if defined(B200)
+ { 6, 200, B200 },
+#endif /* B200 */
+#if defined(B150)
+ { 5, 150, B150 },
+#endif /* B150 */
+#if defined(B134)
+ { 4, 134, B134 },
+#endif /* B134 */
+#if defined(B110)
+ { 3, 110, B110 },
+#endif /* B110 */
+#if defined(B75)
+ { 2, 75, B75 },
+#endif /* B75 */
+#if defined(B50)
+ { 1, 50, B50 },
+#endif /* B50 */
+#if defined(B0)
+ { 0, 0, B0 },
+#endif /* B0 */
+ { -1, -1, -1 }
+};
+
+/*
+ * baud may either be a bits-per-second value or a symbolic
+ * value as returned by cfget?speed()
+ */
+struct baud_values *
+lookup_baud(baud)
+int baud;
+{
+ struct baud_values *p;
+
+ for (p = btable; p->idx >= 0; p++)
+ if (baud == p->bps || baud == p->sym)
+ return p;
+ return NULL;
+}
+
+/*
+ * change the baud rate in a mode structure.
+ * ibaud and obaud are given in bit/second, or at your option as
+ * termio B... symbols as defined in e.g. suns sys/ttydev.h
+ * -1 means don't change.
+ */
+int
+SetBaud(m, ibaud, obaud)
+struct mode *m;
+int ibaud, obaud;
+{
+ struct baud_values *ip, *op;
+
+ if ((!(ip = lookup_baud(ibaud)) && ibaud != -1) ||
+ (!(op = lookup_baud(obaud)) && obaud != -1))
+ return -1;
+
+#ifdef POSIX
+ if (ip) cfsetispeed(&m->tio, ip->sym);
+ if (op) cfsetospeed(&m->tio, op->sym);
+#else /* POSIX */
+# ifdef TERMIO
+ if (ip)
+ {
+# ifdef IBSHIFT
+ m->tio.c_cflag &= ~(CBAUD << IBSHIFT);
+ m->tio.c_cflag |= (ip->sym & CBAUD) << IBSHIFT;
+# else /* IBSHIFT */
+ if (ibaud != obaud)
+ return -1;
+# endif /* IBSHIFT */
+ }
+ if (op)
+ {
+ m->tio.c_cflag &= ~CBAUD;
+ m->tio.c_cflag |= op->sym & CBAUD;
+ }
+# else /* TERMIO */
+ if (ip) m->m_ttyb.sg_ispeed = ip->idx;
+ if (op) m->m_ttyb.sg_ospeed = op->idx;
+# endif /* TERMIO */
+#endif /* POSIX */
+ return 0;
+}
/*
* Write out the mode struct in a readable form
@@ -977,18 +1810,20 @@ struct mode *m;
debug1("c_oflag = %#x\n", (unsigned int)m->tio.c_oflag);
debug1("c_cflag = %#x\n", (unsigned int)m->tio.c_cflag);
debug1("c_lflag = %#x\n", (unsigned int)m->tio.c_lflag);
+ debug1("cfgetospeed() = %d\n", (int)cfgetospeed(&m->tio));
+ debug1("cfgetispeed() = %d\n", (int)cfgetispeed(&m->tio));
for (i = 0; i < sizeof(m->tio.c_cc)/sizeof(*m->tio.c_cc); i++)
{
debug2("c_cc[%d] = %#x\n", i, m->tio.c_cc[i]);
}
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
debug1("suspc = %#02x\n", m->m_ltchars.t_suspc);
debug1("dsuspc = %#02x\n", m->m_ltchars.t_dsuspc);
debug1("rprntc = %#02x\n", m->m_ltchars.t_rprntc);
debug1("flushc = %#02x\n", m->m_ltchars.t_flushc);
debug1("werasc = %#02x\n", m->m_ltchars.t_werasc);
debug1("lnextc = %#02x\n", m->m_ltchars.t_lnextc);
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* POSIX */
# ifdef TERMIO
debug("struct termio tio:\n");