3 # This inserts all the needed #ifdefs for IF{} statements
7 # Stupid cpp on A/UX barfs on ``#if defined(FOO) && FOO < 17'' when
8 # FOO is undefined. Reported by Robert C. Tindall (rtindall@uidaho.edu)
12 -e 's%^IF{\([^}]*\)}\(.*\)%#if defined(\1)\
15 -e 's%^IFN{\([^}]*\)}\(.*\)%#if !defined(\1)\
18 -e 's%^XIF{\([^}]*\)}\(.*\)%#if defined(\1)\
27 /* Copyright
(c
) 1993-2002
28 * Juergen Weigert
(jnweiger@immd4.informatik.uni-erlangen.de
)
29 * Michael Schroeder
(mlschroe@immd4.informatik.uni-erlangen.de
)
30 * Copyright
(c
) 1987 Oliver Laumann
32 * This program is free software
; you can redistribute it and
/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation
; either version
2, or
(at your option
)
37 * This program is distributed
in the hope that it will be useful
,
38 * but WITHOUT ANY WARRANTY
; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License
for more details.
42 * You should have received a copy of the GNU General Public License
43 * along with this program
(see the
file COPYING
); if not
, write to the
44 * Free Software Foundation
, Inc.
,
45 * 59 Temple Place
- Suite
330, Boston
, MA
02111-1307, USA
47 ****************************************************************
51 * NOTICE
: tty.c is automatically generated from tty.sh
52 * Do not change anything here. If you
then change tty.sh.
55 #include <sys/types.h>
59 # include <sys/file.h>
61 #if !defined(sun) || defined(SUNOS3)
62 # include <sys/ioctl.h> /* collosions with termios.h */
65 # include <sys/ttold.h> /* needed for TIOCEXCL */
69 # include <sys/modem.h>
74 # include <sys/sioctl.h>
80 #include <sys/stropts.h> /* for I_POP */
86 #if !defined(TIOCCONS) && defined(sun) && defined(SVR4)
87 # include <sys/strredir.h>
90 extern struct display
*display
, *displays
;
92 #if (!defined(TIOCCONS) && defined(SRIOCSREDIR)) || defined(linux)
93 extern struct win
*console_window
;
94 static void consredir_readev_fn __P
((struct event
*, char
*));
97 int separate_sids
= 1;
99 static void DoSendBreak __P
((int
, int
, int
));
100 static sigret_t SigAlrmDummy __P
(SIGPROTOARG
);
103 /* Frank Schulz
(fschulz@pyramid.com
):
104 * I have no idea why VSTART is not defined and my fix is probably not
105 * the cleanest
, but it works.
107 #if !defined(VSTART) && defined(_VSTART)
108 #define VSTART _VSTART
110 #if !defined(VSTOP) && defined(_VSTOP)
127 SigAlrmDummy SIGDEFARG
129 debug
("SigAlrmDummy()\n");
134 * Carefully open a charcter device. Not used to open display ttys.
135 * The second parameter is parsed
for a few stty style options.
144 sigret_t
(*sigalrm
)__P
(SIGPROTOARG
);
146 sigalrm
= signal
(SIGALRM
, SigAlrmDummy
);
149 /* this open only succeeds
, if real uid is allowed
*/
150 if ((f
= secopen
(line
, O_RDWR | O_NONBLOCK | O_NOCTTY
, 0)) == -1)
153 Msg
(0, "Cannot open line '%s' for R/W: open() blocked, aborted.", line
);
155 Msg
(errno
, "Cannot open line '%s' for R/W", line
);
157 signal
(SIGALRM
, sigalrm
);
162 Msg
(0, "'%s' is not a tty", line
);
164 signal
(SIGALRM
, sigalrm
);
168 #if defined(I_POP) && defined(POP_TTYMODULES)
169 debug
("OpenTTY I_POP\n");
170 while (ioctl
(f
, I_POP
, (char
*)0) >= 0)
174 * We come here exclusively. This is to stop all kermit and cu
type things
175 * accessing the same tty line.
176 * Perhaps we should better create a lock
in some
/usr
/spool
/locks directory?
180 if (ioctl
(f
, TIOCEXCL
, (char
*) 0) < 0)
181 Msg
(errno
, "%s: ioctl TIOCEXCL failed", line
);
182 debug3
("%d %d %d\n", getuid
(), geteuid
(), getpid
());
183 debug2
("%s TIOCEXCL errno %d\n", line
, errno
);
184 #endif /* TIOCEXCL */
186 * We create a sane tty mode. We
do not copy things from the display tty
188 #if WE_REALLY_WANT_TO_COPY_THE_TTY_MODE
191 debug1
("OpenTTY: using mode of display for %s\n", line
);
196 InitTTY
(&Mode
, W_TYPE_PLAIN
);
198 SttyMode
(&Mode
, opt
);
204 #if defined(linux) && defined(TIOCMSET)
207 ioctl
(f
, TIOCMGET
, &mcs
);
209 ioctl
(f
, TIOCMSET
, &mcs
);
215 signal
(SIGALRM
, sigalrm
);
216 debug2
("'%s' CONNECT fd=%d.\n", line
, f
);
230 bzero
((char
*)m
, sizeof
(*m
));
232 /* struct termios tio
233 * defaults
, as seen on SunOS
4.1.3
235 debug1
("InitTTY: POSIX: termios defaults based on SunOS 4.1.3, but better (%d)\n", ttyflag
);
236 IF
{BRKINT
} m-
>tio.c_iflag |
= BRKINT
;
237 IF
{IGNPAR
} m-
>tio.c_iflag |
= IGNPAR
;
238 /* IF
{ISTRIP
} m-
>tio.c_iflag |
= ISTRIP
; may be needed
, let's try. jw. */
239 IF{IXON} m->tio.c_iflag |= IXON;
240 /* IF{IMAXBEL} m->tio.c_iflag |= IMAXBEL; sorry, this one is ridiculus. jw */
242 if (!ttyflag) /* may not even be good for ptys.. */
244 IF{ICRNL} m->tio.c_iflag |= ICRNL;
245 IF{ONLCR} m->tio.c_oflag |= ONLCR;
246 IF{TAB3} m->tio.c_oflag |= TAB3;
247 IF{OXTABS} m->tio.c_oflag |= OXTABS;
248 /* IF{PARENB} m->tio.c_cflag |= PARENB; nah! jw. */
249 IF{OPOST} m->tio.c_oflag |= OPOST;
254 * Or-ing the speed into c_cflags is dangerous.
255 * It breaks on bsdi, where c_ispeed and c_ospeed are extra longs.
257 * IF{B9600} m->tio.c_cflag |= B9600;
258 * IF{IBSHIFT) && defined(B9600} m->tio.c_cflag |= B9600 << IBSHIFT;
260 * We hope that we have the posix calls to do it right:
261 * If these are not available you might try the above.
263 IF{B9600} cfsetospeed(&m->tio, B9600);
264 IF{B9600} cfsetispeed(&m->tio, B9600);
266 IF{CS8} m->tio.c_cflag |= CS8;
267 IF{CREAD} m->tio.c_cflag |= CREAD;
268 IF{CLOCAL} m->tio.c_cflag |= CLOCAL;
270 IF{ECHOCTL} m->tio.c_lflag |= ECHOCTL;
271 IF{ECHOKE} m->tio.c_lflag |= ECHOKE;
275 IF{ISIG} m->tio.c_lflag |= ISIG;
276 IF{ICANON} m->tio.c_lflag |= ICANON;
277 IF{ECHO} m->tio.c_lflag |= ECHO;
279 IF{ECHOE} m->tio.c_lflag |= ECHOE;
280 IF{ECHOK} m->tio.c_lflag |= ECHOK;
281 IF{IEXTEN} m->tio.c_lflag |= IEXTEN;
283 XIF{VINTR} m->tio.c_cc[VINTR] = Ctrl('C
');
284 XIF{VQUIT} m->tio.c_cc[VQUIT] = Ctrl('\\');
285 XIF{VERASE} m->tio.c_cc[VERASE] = 0x7f; /* DEL */
286 XIF{VKILL} m->tio.c_cc[VKILL] = Ctrl('H
');
287 XIF{VEOF} m->tio.c_cc[VEOF] = Ctrl('D
');
288 XIF{VEOL} m->tio.c_cc[VEOL] = 0000;
289 XIF{VEOL2} m->tio.c_cc[VEOL2] = 0000;
290 XIF{VSWTCH} m->tio.c_cc[VSWTCH] = 0000;
291 XIF{VSTART} m->tio.c_cc[VSTART] = Ctrl('Q
');
292 XIF{VSTOP} m->tio.c_cc[VSTOP] = Ctrl('S
');
293 XIF{VSUSP} m->tio.c_cc[VSUSP] = Ctrl('Z
');
294 XIF{VDSUSP} m->tio.c_cc[VDSUSP] = Ctrl('Y
');
295 XIF{VREPRINT} m->tio.c_cc[VREPRINT] = Ctrl('R
');
296 XIF{VDISCARD} m->tio.c_cc[VDISCARD] = Ctrl('O
');
297 XIF{VWERASE} m->tio.c_cc[VWERASE] = Ctrl('W
');
298 XIF{VLNEXT} m->tio.c_cc[VLNEXT] = Ctrl('V
');
299 XIF{VSTATUS} m->tio.c_cc[VSTATUS] = Ctrl('T
');
303 m->tio.c_cc[VMIN] = TTYVMIN;
304 m->tio.c_cc[VTIME] = TTYVTIME;
307 # ifdef HPUX_LTCHARS_HACK
308 m->m_ltchars.t_suspc = Ctrl('Z
');
309 m->m_ltchars.t_dsuspc = Ctrl('Y
');
310 m->m_ltchars.t_rprntc = Ctrl('R
');
311 m->m_ltchars.t_flushc = Ctrl('O
');
312 m->m_ltchars.t_werasc = Ctrl('W
');
313 m->m_ltchars.t_lnextc = Ctrl('V
');
314 # endif /* HPUX_LTCHARS_HACK */
319 debug1("InitTTY: nonPOSIX, struct termio a la Motorola SYSV68 (%d)\n", ttyflag);
321 * defaults, as seen on Mototola SYSV68:
322 * input: 7bit, CR->NL, ^S/^Q flow control
323 * output: POSTprocessing: NL->NL-CR, Tabs to spaces
324 * control: 9600baud, 8bit CSIZE, enable input
325 * local: enable signals, erase/kill processing, echo on.
327 IF{ISTRIP} m->tio.c_iflag |= ISTRIP;
328 IF{IXON} m->tio.c_iflag |= IXON;
330 if (!ttyflag) /* may not even be good for ptys.. */
332 IF{OPOST} m->tio.c_oflag |= OPOST;
333 IF{ICRNL} m->tio.c_iflag |= ICRNL;
334 IF{ONLCR} m->tio.c_oflag |= ONLCR;
335 IF{TAB3} m->tio.c_oflag |= TAB3;
339 )-: cannot handle BSDI without POSIX
341 IF{B9600} m->tio.c_cflag = B9600;
343 IF{CS8} m->tio.c_cflag |= CS8;
344 IF{CREAD} m->tio.c_cflag |= CREAD;
348 IF{ISIG} m->tio.c_lflag |= ISIG;
349 IF{ICANON} m->tio.c_lflag |= ICANON;
350 IF{ECHO} m->tio.c_lflag |= ECHO;
352 IF{ECHOE} m->tio.c_lflag |= ECHOE;
353 IF{ECHOK} m->tio.c_lflag |= ECHOK;
355 XIF{VINTR} m->tio.c_cc[VINTR] = Ctrl('C
');
356 XIF{VQUIT} m->tio.c_cc[VQUIT] = Ctrl('\\');
357 XIF{VERASE} m->tio.c_cc[VERASE] = 0177; /* DEL */
358 XIF{VKILL} m->tio.c_cc[VKILL] = Ctrl('H
');
359 XIF{VEOF} m->tio.c_cc[VEOF] = Ctrl('D
');
360 XIF{VEOL} m->tio.c_cc[VEOL] = 0377;
361 XIF{VEOL2} m->tio.c_cc[VEOL2] = 0377;
362 XIF{VSWTCH} m->tio.c_cc[VSWTCH] = 0000;
366 m->tio.c_cc[VMIN] = TTYVMIN;
367 m->tio.c_cc[VTIME] = TTYVTIME;
371 debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
372 m->m_ttyb.sg_ispeed = B9600;
373 m->m_ttyb.sg_ospeed = B9600;
374 m->m_ttyb.sg_erase = 0177; /*DEL */
375 m->m_ttyb.sg_kill = Ctrl('H
');
377 m->m_ttyb.sg_flags = CRMOD | ECHO
381 m->m_ttyb.sg_flags = CBREAK
385 m->m_tchars.t_intrc = Ctrl('C
');
386 m->m_tchars.t_quitc = Ctrl('\\');
387 m->m_tchars.t_startc = Ctrl('Q
');
388 m->m_tchars.t_stopc = Ctrl('S
');
389 m->m_tchars.t_eofc = Ctrl('D
');
390 m->m_tchars.t_brkc = -1;
392 m->m_ltchars.t_suspc = Ctrl('Z
');
393 m->m_ltchars.t_dsuspc = Ctrl('Y
');
394 m->m_ltchars.t_rprntc = Ctrl('R
');
395 m->m_ltchars.t_flushc = Ctrl('O
');
396 m->m_ltchars.t_werasc = Ctrl('W
');
397 m->m_ltchars.t_lnextc = Ctrl('V
');
399 IF{NTTYDISC} m->m_ldisc = NTTYDISC;
402 IF{LDECCTQ} | LDECCTQ
403 IF{LCTLECH} | LCTLECH
405 IF{LCRTKIL} | LCRTKIL
406 IF{LCRTERA} | LCRTERA
412 #if defined(ENCODINGS) && defined(TIOCKSET)
413 m->m_jtchars.t_ascii = 'J
';
414 m->m_jtchars.t_kanji = 'B
';
415 m->m_knjmode = KM_ASCII | KM_SYSSJIS;
426 tcsetattr(fd, TCSADRAIN, &mp->tio);
427 # ifdef HPUX_LTCHARS_HACK
428 ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars);
432 ioctl(fd, TCSETAW, (char *)&mp->tio);
434 if (mp->tio.c_line == 3)
436 ioctl(fd, LDSETMAPKEY, (char *)&mp->m_mapkey);
437 ioctl(fd, LDSETMAPSCREEN, (char *)&mp->m_mapscreen);
438 ioctl(fd, LDSETBACKSPACE, (char *)&mp->m_backspace);
442 /* ioctl(fd, TIOCSETP, (char *)&mp->m_ttyb); */
443 ioctl(fd, TIOCSETC, (char *)&mp->m_tchars);
444 ioctl(fd, TIOCLSET, (char *)&mp->m_lmode);
445 ioctl(fd, TIOCSETD, (char *)&mp->m_ldisc);
446 ioctl(fd, TIOCSETP, (char *)&mp->m_ttyb);
447 ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars); /* moved here for apollo. jw */
450 #if defined(ENCODINGS) && defined(TIOCKSET)
451 ioctl(fd, TIOCKSETC, &mp->m_jtchars);
452 ioctl(fd, TIOCKSET, &mp->m_knjmode);
455 Msg(errno, "SetTTY (fd %d): ioctl failed", fd);
465 tcgetattr(fd, &mp->tio);
466 # ifdef HPUX_LTCHARS_HACK
467 ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
471 ioctl(fd, TCGETA, (char *)&mp->tio);
473 if (mp->tio.c_line == 3)
475 ioctl(fd, LDGETMAPKEY, (char *)&mp->m_mapkey);
476 ioctl(fd, LDGETMAPSCREEN, (char *)&mp->m_mapscreen);
477 ioctl(fd, LDGETBACKSPACE, (char *)&mp->m_backspace);
481 mp->m_mapkey = NOMAPKEY;
482 mp->m_mapscreen = NOMAPSCREEN;
483 mp->m_backspace = '\b';
487 ioctl(fd, TIOCGETP, (char *)&mp->m_ttyb);
488 ioctl(fd, TIOCGETC, (char *)&mp->m_tchars);
489 ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
490 ioctl(fd, TIOCLGET, (char *)&mp->m_lmode);
491 ioctl(fd, TIOCGETD, (char *)&mp->m_ldisc);
494 #if defined(ENCODINGS) && defined(TIOCKSET)
495 ioctl(fd, TIOCKGETC, &mp->m_jtchars);
496 ioctl(fd, TIOCKGET, &mp->m_knjmode);
499 Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
503 * needs interrupt = iflag and flow = d->d_flow
506 SetMode(op, np, flow, interrupt)
507 struct mode *op, *np;
513 #if defined(TERMIO) || defined(POSIX)
515 np->m_mapkey = NOMAPKEY;
516 np->m_mapscreen = NOMAPSCREEN;
519 IF{ICRNL} np->tio.c_iflag &= ~ICRNL;
520 IF{ISTRIP} np->tio.c_iflag &= ~ISTRIP;
521 IF{ONLCR} np->tio.c_oflag &= ~ONLCR;
522 np->tio.c_lflag &= ~(ICANON | ECHO);
524 * From Andrew Myers (andru@tonic.lcs.mit.edu)
525 * to avoid ^V^V-Problem on OSF1
527 IF{IEXTEN} np->tio.c_lflag &= ~IEXTEN;
530 * Unfortunately, the master process never will get SIGINT if the real
531 * terminal is different from the one on which it was originaly started
532 * (process group membership has not been restored or the new tty could not
533 * be made controlling again). In my solution, it is the attacher who
534 * receives SIGINT (because it is always correctly associated with the real
535 * tty) and forwards it to the master [kill(MasterPid, SIGINT)].
536 * Marc Boucher (marc@CAM.ORG)
539 np->tio.c_lflag |= ISIG;
541 np->tio.c_lflag &= ~ISIG;
543 * careful, careful catche monkey..
544 * never set VMIN and VTIME to zero, if you want blocking io.
546 * We may want to do a VMIN > 0, VTIME > 0 read on the ptys too, to
547 * reduce interrupt frequency. But then we would not know how to
548 * handle read returning 0. jw.
550 np->tio.c_cc[VMIN] = 1;
551 np->tio.c_cc[VTIME] = 0;
552 if (!interrupt || !flow)
553 np->tio.c_cc[VINTR] = VDISABLE;
554 np->tio.c_cc[VQUIT] = VDISABLE;
557 XIF{VSTART} np->tio.c_cc[VSTART] = VDISABLE;
558 XIF{VSTOP} np->tio.c_cc[VSTOP] = VDISABLE;
559 np->tio.c_iflag &= ~IXON;
561 XIF{VDISCARD} np->tio.c_cc[VDISCARD] = VDISABLE;
562 XIF{VLNEXT} np->tio.c_cc[VLNEXT] = VDISABLE;
563 XIF{VSTATUS} np->tio.c_cc[VSTATUS] = VDISABLE;
564 XIF{VSUSP} np->tio.c_cc[VSUSP] = VDISABLE;
565 /* Set VERASE to DEL, rather than VDISABLE, to avoid libvte
566 "autodetect" issues. */
567 XIF{VERASE} np->tio.c_cc[VERASE] = 0x7f;
568 XIF{VKILL} np->tio.c_cc[VKILL] = VDISABLE;
569 # ifdef HPUX_LTCHARS_HACK
570 np->m_ltchars.t_suspc = VDISABLE;
571 np->m_ltchars.t_dsuspc = VDISABLE;
572 np->m_ltchars.t_rprntc = VDISABLE;
573 np->m_ltchars.t_flushc = VDISABLE;
574 np->m_ltchars.t_werasc = VDISABLE;
575 np->m_ltchars.t_lnextc = VDISABLE;
576 # else /* HPUX_LTCHARS_HACK */
577 XIF{VDSUSP} np->tio.c_cc[VDSUSP] = VDISABLE;
578 XIF{VREPRINT} np->tio.c_cc[VREPRINT] = VDISABLE;
579 XIF{VWERASE} np->tio.c_cc[VWERASE] = VDISABLE;
580 # endif /* HPUX_LTCHARS_HACK */
581 #else /* TERMIO || POSIX */
582 if (!interrupt || !flow)
583 np->m_tchars.t_intrc = -1;
584 np->m_ttyb.sg_flags &= ~(CRMOD | ECHO);
585 np->m_ttyb.sg_flags |= CBREAK;
586 # if defined(CYRILL) && defined(CSTYLE) && defined(CS_8BITS)
587 np->m_ttyb.sg_flags &= ~CSTYLE;
588 np->m_ttyb.sg_flags |= CS_8BITS;
590 np->m_tchars.t_quitc = -1;
593 np->m_tchars.t_startc = -1;
594 np->m_tchars.t_stopc = -1;
596 np->m_ltchars.t_suspc = -1;
597 np->m_ltchars.t_dsuspc = -1;
598 np->m_ltchars.t_flushc = -1;
599 np->m_ltchars.t_lnextc = -1;
600 #endif /* defined(TERMIO) || defined(POSIX) */
603 /* operates on display */
611 #if defined(TERMIO) || defined(POSIX)
614 D_NewMode.tio.c_cc[VINTR] = iflag ? D_OldMode.tio.c_cc[VINTR] : VDISABLE;
615 XIF{VSTART} D_NewMode.tio.c_cc[VSTART] = D_OldMode.tio.c_cc[VSTART];
616 XIF{VSTOP} D_NewMode.tio.c_cc[VSTOP] = D_OldMode.tio.c_cc[VSTOP];
617 D_NewMode.tio.c_iflag |= D_OldMode.tio.c_iflag & IXON;
621 D_NewMode.tio.c_cc[VINTR] = VDISABLE;
622 XIF{VSTART} D_NewMode.tio.c_cc[VSTART] = VDISABLE;
623 XIF{VSTOP} D_NewMode.tio.c_cc[VSTOP] = VDISABLE;
624 D_NewMode.tio.c_iflag &= ~IXON;
629 tcflow(D_userfd, TCOON);
631 if (tcsetattr(D_userfd, TCSANOW, &D_NewMode.tio))
633 if (ioctl(D_userfd, TCSETAW, (char *)&D_NewMode.tio) != 0)
635 debug1("SetFlow: ioctl errno %d\n", errno);
636 #else /* POSIX || TERMIO */
639 D_NewMode.m_tchars.t_intrc = iflag ? D_OldMode.m_tchars.t_intrc : -1;
640 D_NewMode.m_tchars.t_startc = D_OldMode.m_tchars.t_startc;
641 D_NewMode.m_tchars.t_stopc = D_OldMode.m_tchars.t_stopc;
645 D_NewMode.m_tchars.t_intrc = -1;
646 D_NewMode.m_tchars.t_startc = -1;
647 D_NewMode.m_tchars.t_stopc = -1;
649 if (ioctl(D_userfd, TIOCSETC, (char *)&D_NewMode.m_tchars) != 0)
650 debug1("SetFlow: ioctl errno %d\n", errno);
651 #endif /* POSIX || TERMIO */
655 /* parse commands from opt and modify m */
661 static const char sep[] = " \t:;,";
668 while (index(sep, *opt)) opt++;
669 if (*opt >= '0' && *opt <= '9')
671 if (SetBaud(m, atoi(opt), atoi(opt)))
674 else if (!strncmp("cs7", opt, 3))
676 #if defined(POSIX) || defined(TERMIO)
677 m->tio.c_cflag &= ~CSIZE;
678 m->tio.c_cflag |= CS7;
680 m->m_lmode &= ~LPASS8;
683 else if (!strncmp("cs8", opt, 3))
685 #if defined(POSIX) || defined(TERMIO)
686 m->tio.c_cflag &= ~CSIZE;
687 m->tio.c_cflag |= CS8;
689 m->m_lmode |= LPASS8;
692 else if (!strncmp("istrip", opt, 6))
694 #if defined(POSIX) || defined(TERMIO)
695 m->tio.c_iflag |= ISTRIP;
697 m->m_lmode &= ~LPASS8;
700 else if (!strncmp("-istrip", opt, 7))
702 #if defined(POSIX) || defined(TERMIO)
703 m->tio.c_iflag &= ~ISTRIP;
705 m->m_lmode |= LPASS8;
708 else if (!strncmp("ixon", opt, 4))
710 #if defined(POSIX) || defined(TERMIO)
711 m->tio.c_iflag |= IXON;
713 debug("SttyMode: no ixon in old bsd land.\n");
716 else if (!strncmp("-ixon", opt, 5))
718 #if defined(POSIX) || defined(TERMIO)
719 m->tio.c_iflag &= ~IXON;
721 debug("SttyMode: no -ixon in old bsd land.\n");
724 else if (!strncmp("ixoff", opt, 5))
726 #if defined(POSIX) || defined(TERMIO)
727 m->tio.c_iflag |= IXOFF;
729 m->m_ttyb.sg_flags |= TANDEM;
732 else if (!strncmp("-ixoff", opt, 6))
734 #if defined(POSIX) || defined(TERMIO)
735 m->tio.c_iflag &= ~IXOFF;
737 m->m_ttyb.sg_flags &= ~TANDEM;
740 else if (!strncmp("crtscts", opt, 7))
742 #if (defined(POSIX) || defined(TERMIO)) && defined(CRTSCTS)
743 m->tio.c_cflag |= CRTSCTS;
746 else if (!strncmp("-crtscts", opt, 8))
748 #if (defined(POSIX) || defined(TERMIO)) && defined(CRTSCTS)
749 m->tio.c_cflag &= ~CRTSCTS;
754 while (*opt && !index(sep, *opt)) opt++;
760 * Job control handling
762 * Somehow the ultrix session handling is broken, so use
763 * the bsdish variant.
771 #if defined(POSIX) && !defined(ultrix)
773 setsid(); /* will break terminal affiliation */
774 /* GNU added for Hurd systems 2001-10-10 */
775 # if defined(BSD) && defined(TIOCSCTTY) && !defined(__GNU__)
776 ioctl(fd, TIOCSCTTY, (char *)0);
777 # endif /* BSD && TIOCSCTTY */
781 setpgrp(); /* will break terminal affiliation */
786 if ((devtty = open("/dev/tty", O_RDWR | O_NONBLOCK)) >= 0)
788 if (ioctl(devtty, TIOCNOTTY, (char *)0))
789 debug2("brktty: ioctl(devtty=%d, TIOCNOTTY, 0) = %d\n", devtty, errno);
792 # endif /* BSDJOBS */
806 /* The next lines should be obsolete. Can anybody check if they
807 * are really needed on the BSD platforms?
809 * this is to avoid the message:
810 * fgtty: Not a typewriter (25)
812 # if defined(__osf__) || (BSD >= 199103) || defined(ISC)
814 setsid(); /* should be already done */
816 ioctl(fd, TIOCSCTTY, (char *)0);
822 if (tcsetpgrp(fd, mypid))
824 debug1("fgtty: tcsetpgrp: %d\n", errno);
828 if (ioctl(fd, TIOCSPGRP, (char *)&mypid) != 0)
829 debug1("fgtty: TIOSETPGRP: %d\n", errno);
830 # ifndef SYSV /* Already done in brktty():setpgrp() */
832 if (setpgrp(fd, mypid))
833 debug1("fgtty: setpgrp: %d\n", errno);
841 * The alm boards on our sparc center 1000 have a lousy driver.
842 * We cannot generate long breaks unless we use the most ugly form
855 #if defined(sun) && !defined(SVR4)
856 # define HAVE_SUPER_TCSENDBREAK
861 * 0: TIOCSBRK / TIOCCBRK
864 * n: approximate duration in 1/4 seconds.
867 DoSendBreak(fd, n, type)
872 case 2: /* tcsendbreak() =============================== */
874 # ifdef HAVE_SUPER_TCSENDBREAK
875 /* There is one rare case that I have tested, where tcsendbreak works
876 * really great: this was an alm driver that came with SunOS 4.1.3
877 * If you have this one, define the above symbol.
878 * here we can use the second parameter to specify the duration.
880 debug2("tcsendbreak(fd=%d, %d)\n", fd, n);
881 if (tcsendbreak(fd, n) < 0)
882 Msg(errno, "cannot send BREAK (tcsendbreak)");
885 * here we hope, that multiple calls to tcsendbreak() can
886 * be concatenated to form a long break, as we do not know
887 * what exact interpretation the second parameter has:
889 * - sunos 4: duration in quarter seconds
890 * - sunos 5: 0 a short break, nonzero a tcdrain()
891 * - hpux, irix: ignored
892 * - mot88: duration in milliseconds
893 * - aix: duration in milliseconds, but 0 is 25 milliseconds.
895 debug2("%d * tcsendbreak(fd=%d, 0)\n", n, fd);
901 for (i = 0; i < n; i++)
902 if (tcsendbreak(fd, 0) < 0)
904 Msg(errno, "cannot send BREAK (tcsendbreak SVR4)");
910 Msg(0, "tcsendbreak() not available, change breaktype");
914 case 1: /* TCSBRK ======================================= */
919 * Here too, we assume that short breaks can be concatenated to
920 * perform long breaks. But for SOLARIS, this is not true, of course.
922 debug2("%d * TCSBRK fd=%d\n", n, fd);
926 for (i = 0; i < n; i++)
927 if (ioctl(fd, TCSBRK, (char *)0) < 0)
929 Msg(errno, "Cannot send BREAK (TCSBRK)");
934 Msg(0, "TCSBRK not available, change breaktype");
938 case 0: /* TIOCSBRK / TIOCCBRK ========================== */
939 #if defined(TIOCSBRK) && defined(TIOCCBRK)
941 * This is very rude. Screen actively celebrates the break.
942 * But it may be the only save way to issue long breaks.
944 debug("TIOCSBRK TIOCCBRK\n");
945 if (ioctl(fd, TIOCSBRK, (char *)0) < 0)
947 Msg(errno, "Can't send BREAK
(TIOCSBRK
)");
950 sleep1000(n ? n * 250 : 250);
951 if (ioctl(fd, TIOCCBRK, (char *)0) < 0)
953 Msg(errno, "BREAK stuck
!!! -- HELP
! (TIOCCBRK
)");
956 #else /* TIOCSBRK && TIOCCBRK */
957 Msg(0, "TIOCSBRK
/CBRK not available
, change breaktype
");
958 #endif /* TIOCSBRK && TIOCCBRK */
961 default: /* unknown ========================== */
962 Msg(0, "Internal SendBreak error
: method
%d unknown
", type);
967 * Send a break for n * 0.25 seconds. Tty must be PLAIN.
968 * The longest possible break allowed here is 15 seconds.
972 SendBreak(wp, n, closeopen)
976 sigret_t (*sigalrm)__P(SIGPROTOARG);
978 #ifdef BUILTIN_TELNET
979 if (wp->w_type == W_TYPE_TELNET)
985 if (wp->w_type != W_TYPE_PLAIN)
988 debug3("break(%d
, %d
) fd
%d
\n", n, closeopen, wp->w_ptyfd);
991 (void) tcflush(wp->w_ptyfd, TCIOFLUSH);
994 (void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
995 # endif /* TIOCFLUSH */
1001 sleep1000(n ? n * 250 : 250);
1002 if ((wp->w_ptyfd = OpenTTY(wp->w_tty, wp->w_cmdargs[1])) < 1)
1004 Msg(0, "Ouch
, cannot reopen line
%s
, please try harder
", wp->w_tty);
1007 (void) fcntl(wp->w_ptyfd, F_SETFL, FNBLOCK);
1011 sigalrm = signal(SIGALRM, SigAlrmDummy);
1014 DoSendBreak(wp->w_ptyfd, n, breaktype);
1017 signal(SIGALRM, sigalrm);
1019 debug(" broken.
\n");
1026 #if (!defined(TIOCCONS) && defined(SRIOCSREDIR)) || defined(linux)
1028 static struct event consredir_ev;
1029 static int consredirfd[2] = {-1, -1};
1032 consredir_readev_fn(ev, data)
1036 char *p, *n, buf[256];
1039 if (!console_window || (l = read(consredirfd[0], buf, sizeof(buf))) <= 0)
1041 close(consredirfd[0]);
1042 close(consredirfd[1]);
1043 consredirfd[0] = consredirfd[1] = -1;
1047 for (p = n = buf; l > 0; n++, l--)
1051 WriteString(console_window, p, n - p);
1052 WriteString(console_window, "\r\n", 2);
1056 WriteString(console_window, p, n - p);
1063 TtyGrabConsole(fd, on, rc_name)
1067 #if defined(TIOCCONS) && !defined(linux)
1073 return 0; /* pty close will ungrab */
1078 Msg(0, "I need a display
");
1081 for (d = displays; d; d = d->d_next)
1082 if (strcmp(d->d_usertty, "/dev
/console
") == 0)
1086 Msg(0, "too dangerous
- screen is running on
/dev
/console
");
1094 if ((fd = OpenPTY(&slave)) < 0)
1096 Msg(errno, "%s
: could not open detach pty master
", rc_name);
1099 if ((sfd = open(slave, O_RDWR | O_NOCTTY)) < 0)
1101 Msg(errno, "%s
: could not open detach pty slave
", rc_name);
1106 if (UserContext() == 1)
1107 UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
1110 Msg(errno, "%s
: ioctl TIOCCONS failed
", rc_name);
1119 # if defined(SRIOCSREDIR) || defined(linux)
1124 struct mode new1, new2;
1132 Msg(0, "I need a display
");
1135 for (d = displays; d; d = d->d_next)
1136 if (strcmp(d->d_usertty, "/dev
/console
") == 0)
1140 Msg(0, "too dangerous
- screen is running on
/dev
/console
");
1144 if (consredirfd[0] >= 0)
1146 evdeq(&consredir_ev);
1147 close(consredirfd[0]);
1148 close(consredirfd[1]);
1149 consredirfd[0] = consredirfd[1] = -1;
1154 if ((cfd = secopen("/dev
/console
", O_RDWR|O_NOCTTY, 0)) == -1)
1156 Msg(errno, "/dev
/console
");
1159 if (pipe(consredirfd))
1163 consredirfd[0] = consredirfd[1] = -1;
1166 if (ioctl(cfd, SRIOCSREDIR, consredirfd[1]))
1168 Msg(errno, "SRIOCSREDIR ioctl
");
1170 close(consredirfd[0]);
1171 close(consredirfd[1]);
1172 consredirfd[0] = consredirfd[1] = -1;
1177 /* special linux workaround for a too restrictive kernel */
1178 if ((consredirfd[0] = OpenPTY(&slave)) < 0)
1180 Msg(errno, "%s
: could not open detach pty master
", rc_name);
1183 if ((consredirfd[1] = open(slave, O_RDWR | O_NOCTTY)) < 0)
1185 Msg(errno, "%s
: could not open detach pty slave
", rc_name);
1186 close(consredirfd[0]);
1190 SetMode(&new1, &new2, 0, 0);
1191 SetTTY(consredirfd[1], &new2);
1192 if (UserContext() == 1)
1193 UserReturn(ioctl(consredirfd[1], TIOCCONS, (char *)&on));
1196 Msg(errno, "%s
: ioctl TIOCCONS failed
", rc_name);
1197 close(consredirfd[0]);
1198 close(consredirfd[1]);
1202 consredir_ev.fd = consredirfd[0];
1203 consredir_ev.type = EV_READ;
1204 consredir_ev.handler = consredir_readev_fn;
1205 evenq(&consredir_ev);
1209 Msg(0, "%s
: don
't know how to grab the console", rc_name);
1216 * Read modem control lines of a physical tty and write them to buf
1217 * in a readable format.
1218 * Will not write more than 256 characters to buf.
1222 TtyGetModemStatus(fd, buf)
1228 unsigned int softcar;
1230 #if defined(TIOCMGET) || defined(TIOCMODG)
1231 unsigned int mflags;
1234 /* this is yet another interface, found on hpux. grrr */
1236 IF{MDTR}# define TIOCM_DTR MDTR
1237 IF{MRTS}# define TIOCM_RTS MRTS
1238 IF{MDSR}# define TIOCM_DSR MDSR
1239 IF{MDCD}# define TIOCM_CAR MDCD
1240 IF{MRI}# define TIOCM_RNG MRI
1241 IF{MCTS}# define TIOCM_CTS MCTS
1244 #if defined(CLOCAL) || defined(CRTSCTS)
1245 struct mode mtio; /* screen.h */
1247 #if defined(CRTSCTS) || defined(TIOCM_CTS)
1252 #if defined(CLOCAL) || defined(CRTSCTS)
1257 if (mtio.tio.c_cflag & CLOCAL)
1266 if (!(mtio.tio.c_cflag & CRTSCTS))
1269 # endif /* CRTSCTS */
1271 #endif /* TIOCM_CTS */
1274 if (ioctl(fd, TIOCGSOFTCAR, (char *)&softcar) < 0)
1278 #if defined(TIOCMGET) || defined(TIOCMODG) || defined(MCGETA)
1280 if (ioctl(fd, TIOCMGET, (char *)&mflags) < 0)
1283 if (ioctl(fd, TIOCMODG, (char *)&mflags) < 0)
1285 if (ioctl(fd, MCGETA, &mflags) < 0)
1290 sprintf(p, "NO-TTY? %s", softcar ? "(CD)" : "CD");
1292 sprintf(p, "NO-TTY?");
1301 if (!(mflags & TIOCM_LE))
1302 for (s = "!LE "; *s; *p++ = *s++);
1304 # endif /* FANCY_MODEM */
1307 s = "!RTS "; if (mflags & TIOCM_RTS) s++;
1308 while (*s) *p++ = *s++;
1317 if (mflags & TIOCM_CTS) s++;
1318 while (*s) *p++ = *s++;
1322 s = "!DTR "; if (mflags & TIOCM_DTR) s++;
1323 while (*s) *p++ = *s++;
1326 s = "!DSR "; if (mflags & TIOCM_DSR) s++;
1327 while (*s) *p++ = *s++;
1329 # if defined(TIOCM_CD) || defined(TIOCM_CAR)
1331 # ifdef TIOCGSOFTCAR
1339 if (mflags & TIOCM_CD) s++;
1341 if (mflags & TIOCM_CAR) s++;
1343 while (*s) *p++ = *s++;
1345 # if defined(TIOCM_RI) || defined(TIOCM_RNG)
1347 if (mflags & TIOCM_RI)
1349 if (mflags & TIOCM_RNG)
1351 for (s = "RI "; *s; *p++ = *s++);
1355 s = "!ST "; if (mflags & TIOCM_ST) s++;
1356 while (*s) *p++ = *s++;
1359 s = "!SR "; if (mflags & TIOCM_SR) s++;
1360 while (*s) *p++ = *s++;
1362 # endif /* FANCY_MODEM */
1363 if (p > buf && p[-1] == ' ')
1368 # ifdef TIOCGSOFTCAR
1369 sprintf(p, " %s", softcar ? "(CD)", "CD");
1380 * Old bsd-ish machines may not have any of the baudrate B... symbols.
1381 * We hope to detect them here, so that the btable[] below always has
1386 # if !defined(B9600) && !defined(B2400) && !defined(B1200) && !defined(B300)
1388 IFN{B50}#define B50 1
1389 IFN{B75}#define B75 2
1390 IFN{B110}#define B110 3
1391 IFN{B134}#define B134 4
1392 IFN{B150}#define B150 5
1393 IFN{B200}#define B200 6
1394 IFN{B300}#define B300 7
1395 IFN{B600}#define B600 8
1396 IFN{B1200}#define B1200 9
1397 IFN{B1800}#define B1800 10
1398 IFN{B2400}#define B2400 11
1399 IFN{B4800}#define B4800 12
1400 IFN{B9600}#define B9600 13
1401 IFN{EXTA}#define EXTA 14
1402 IFN{EXTB}#define EXTB 15
1408 * On hpux, idx and sym will be different.
1409 * Rumor has it that, we need idx in D_dospeed to make tputs
1411 * Frequently used entries come first.
1413 static struct baud_values btable[] =
1415 IF{B9600} { 13, 9600, B9600 },
1416 IF{B19200} { 14, 19200, B19200 },
1417 IF{EXTA} { 14, 19200, EXTA },
1418 IF{B38400} { 15, 38400, B38400 },
1419 IF{EXTB} { 15, 38400, EXTB },
1420 IF{B57600} { 16, 57600, B57600 },
1421 IF{B115200} { 17, 115200, B115200 },
1422 IF{B230400} { 18, 230400, B230400 },
1423 IF{B460800} { 19, 460800, B460800 },
1424 IF{B7200} { 13, 7200, B7200 },
1425 IF{B4800} { 12, 4800, B4800 },
1426 IF{B3600} { 12, 3600, B3600 },
1427 IF{B2400} { 11, 2400, B2400 },
1428 IF{B1800} { 10, 1800, B1800 },
1429 IF{B1200} { 9, 1200, B1200 },
1430 IF{B900} { 9, 900, B900 },
1431 IF{B600} { 8, 600, B600 },
1432 IF{B300} { 7, 300, B300 },
1433 IF{B200} { 6, 200, B200 },
1434 IF{B150} { 5, 150, B150 },
1435 IF{B134} { 4, 134, B134 },
1436 IF{B110} { 3, 110, B110 },
1437 IF{B75} { 2, 75, B75 },
1438 IF{B50} { 1, 50, B50 },
1439 IF{B0} { 0, 0, B0 },
1444 * baud may either be a bits-per-second value or a symbolic
1445 * value as returned by cfget?speed()
1447 struct baud_values *
1451 struct baud_values *p;
1453 for (p = btable; p->idx >= 0; p++)
1454 if (baud == p->bps || baud == p->sym)
1460 * change the baud rate in a mode structure.
1461 * ibaud and obaud are given in bit/second, or at your option as
1462 * termio B... symbols as defined in e.g. suns sys/ttydev.h
1463 * -1 means don't change.
1466 SetBaud
(m
, ibaud
, obaud
)
1470 struct baud_values
*ip
, *op
;
1472 if ((!(ip
= lookup_baud
(ibaud
)) && ibaud
!= -1) ||
1473 (!(op
= lookup_baud
(obaud
)) && obaud
!= -1))
1477 if (ip
) cfsetispeed
(&m-
>tio
, ip-
>sym
);
1478 if (op
) cfsetospeed
(&m-
>tio
, op-
>sym
);
1484 m-
>tio.c_cflag
&= ~
(CBAUD
<< IBSHIFT);
1485 m->tio.c_cflag |= (ip->sym & CBAUD) << IBSHIFT;
1486 # else /* IBSHIFT */
1489 # endif /* IBSHIFT */
1493 m-
>tio.c_cflag
&= ~CBAUD
;
1494 m-
>tio.c_cflag |
= op-
>sym
& CBAUD
;
1497 if (ip
) m-
>m_ttyb.sg_ispeed
= ip-
>idx
;
1498 if (op
) m-
>m_ttyb.sg_ospeed
= op-
>idx
;
1499 # endif /* TERMIO */
1505 * Write out the mode struct
in a readable form
1516 debug
("struct termios tio:\n");
1517 debug1
("c_iflag = %#x\n", (unsigned int
)m-
>tio.c_iflag
);
1518 debug1
("c_oflag = %#x\n", (unsigned int
)m-
>tio.c_oflag
);
1519 debug1
("c_cflag = %#x\n", (unsigned int
)m-
>tio.c_cflag
);
1520 debug1
("c_lflag = %#x\n", (unsigned int
)m-
>tio.c_lflag
);
1521 debug1
("cfgetospeed() = %d\n", (int
)cfgetospeed
(&m-
>tio
));
1522 debug1
("cfgetispeed() = %d\n", (int
)cfgetispeed
(&m-
>tio
));
1523 for (i
= 0; i
< sizeof
(m-
>tio.c_cc
)/sizeof
(*m-
>tio.c_cc
); i
++)
1525 debug2
("c_cc[%d] = %#x\n", i
, m-
>tio.c_cc
[i
]);
1527 # ifdef HPUX_LTCHARS_HACK
1528 debug1
("suspc = %#02x\n", m-
>m_ltchars.t_suspc
);
1529 debug1
("dsuspc = %#02x\n", m-
>m_ltchars.t_dsuspc
);
1530 debug1
("rprntc = %#02x\n", m-
>m_ltchars.t_rprntc
);
1531 debug1
("flushc = %#02x\n", m-
>m_ltchars.t_flushc
);
1532 debug1
("werasc = %#02x\n", m-
>m_ltchars.t_werasc
);
1533 debug1
("lnextc = %#02x\n", m-
>m_ltchars.t_lnextc
);
1534 # endif /* HPUX_LTCHARS_HACK */
1537 debug
("struct termio tio:\n");
1538 debug1
("c_iflag = %04o\n", m-
>tio.c_iflag
);
1539 debug1
("c_oflag = %04o\n", m-
>tio.c_oflag
);
1540 debug1
("c_cflag = %04o\n", m-
>tio.c_cflag
);
1541 debug1
("c_lflag = %04o\n", m-
>tio.c_lflag
);
1542 for (i
= 0; i
< sizeof
(m-
>tio.c_cc
)/sizeof
(*m-
>tio.c_cc
); i
++)
1544 debug2
("c_cc[%d] = %04o\n", i
, m-
>tio.c_cc
[i
]);
1547 debug1
("sg_ispeed = %d\n", m-
>m_ttyb.sg_ispeed
);
1548 debug1
("sg_ospeed = %d\n", m-
>m_ttyb.sg_ospeed
);
1549 debug1
("sg_erase = %#02x\n", m-
>m_ttyb.sg_erase
);
1550 debug1
("sg_kill = %#02x\n", m-
>m_ttyb.sg_kill
);
1551 debug1
("sg_flags = %#04x\n", (unsigned short
)m-
>m_ttyb.sg_flags
);
1552 debug1
("intrc = %#02x\n", m-
>m_tchars.t_intrc
);
1553 debug1
("quitc = %#02x\n", m-
>m_tchars.t_quitc
);
1554 debug1
("startc = %#02x\n", m-
>m_tchars.t_startc
);
1555 debug1
("stopc = %#02x\n", m-
>m_tchars.t_stopc
);
1556 debug1
("eofc = %#02x\n", m-
>m_tchars.t_eofc
);
1557 debug1
("brkc = %#02x\n", m-
>m_tchars.t_brkc
);
1558 debug1
("suspc = %#02x\n", m-
>m_ltchars.t_suspc
);
1559 debug1
("dsuspc = %#02x\n", m-
>m_ltchars.t_dsuspc
);
1560 debug1
("rprntc = %#02x\n", m-
>m_ltchars.t_rprntc
);
1561 debug1
("flushc = %#02x\n", m-
>m_ltchars.t_flushc
);
1562 debug1
("werasc = %#02x\n", m-
>m_ltchars.t_werasc
);
1563 debug1
("lnextc = %#02x\n", m-
>m_ltchars.t_lnextc
);
1564 debug1
("ldisc = %d\n", m-
>m_ldisc
);
1565 debug1
("lmode = %#x\n", m-
>m_lmode
);
1566 # endif /* TERMIO */