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
) 2008, 2009
28 * Juergen Weigert
(jnweiger@immd4.informatik.uni-erlangen.de
)
29 * Michael Schroeder
(mlschroe@immd4.informatik.uni-erlangen.de
)
30 * Micah Cowan
(micah@cowan.name
)
31 * Sadrul Habib Chowdhury
(sadrul@users.sourceforge.net
)
32 * Copyright
(c
) 1993-2002, 2003, 2005, 2006, 2007
33 * Juergen Weigert
(jnweiger@immd4.informatik.uni-erlangen.de
)
34 * Michael Schroeder
(mlschroe@immd4.informatik.uni-erlangen.de
)
35 * Copyright
(c
) 1987 Oliver Laumann
37 * This program is free software
; you can redistribute it and
/or modify
38 * it under the terms of the GNU General Public License as published by
39 * the Free Software Foundation
; either version
3, or
(at your option
)
42 * This program is distributed
in the hope that it will be useful
,
43 * but WITHOUT ANY WARRANTY
; without even the implied warranty of
44 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45 * GNU General Public License
for more details.
47 * You should have received a copy of the GNU General Public License
48 * along with this program
(see the
file COPYING
); if not
, see
49 * http
://www.gnu.org
/licenses
/, or contact Free Software Foundation
, Inc.
,
50 * 51 Franklin Street
, Fifth Floor
, Boston
, MA
02111-1301 USA
52 ****************************************************************
56 * NOTICE
: tty.c is automatically generated from tty.sh
57 * Do not change anything here. If you
then change tty.sh.
60 #include <sys/types.h>
64 # include <sys/file.h>
66 #if !defined(sun) || defined(SUNOS3)
67 # include <sys/ioctl.h> /* collosions with termios.h */
70 # include <sys/ttold.h> /* needed for TIOCEXCL */
74 # include <sys/modem.h>
79 # include <sys/sioctl.h>
85 #include <sys/stropts.h> /* for I_POP */
91 #if !defined(TIOCCONS) && defined(sun) && defined(SVR4)
92 # include <sys/strredir.h>
95 extern struct display
*display
, *displays
;
97 #if (!defined(TIOCCONS) && defined(SRIOCSREDIR)) || defined(linux)
98 extern struct win
*console_window
;
99 static void consredir_readev_fn __P
((struct event
*, char
*));
102 int separate_sids
= 1;
104 static void DoSendBreak __P
((int
, int
, int
));
105 static sigret_t SigAlrmDummy __P
(SIGPROTOARG
);
108 /* Frank Schulz
(fschulz@pyramid.com
):
109 * I have no idea why VSTART is not defined and my fix is probably not
110 * the cleanest
, but it works.
112 #if !defined(VSTART) && defined(_VSTART)
113 #define VSTART _VSTART
115 #if !defined(VSTOP) && defined(_VSTOP)
132 SigAlrmDummy SIGDEFARG
134 debug
("SigAlrmDummy()\n");
139 * Carefully open a charcter device. Not used to open display ttys.
140 * The second parameter is parsed
for a few stty style options.
149 sigret_t
(*sigalrm
)__P
(SIGPROTOARG
);
151 sigalrm
= signal
(SIGALRM
, SigAlrmDummy
);
154 /* this open only succeeds
, if real uid is allowed
*/
155 if ((f
= secopen
(line
, O_RDWR | O_NONBLOCK | O_NOCTTY
, 0)) == -1)
158 Msg
(0, "Cannot open line '%s' for R/W: open() blocked, aborted.", line
);
160 Msg
(errno
, "Cannot open line '%s' for R/W", line
);
162 signal
(SIGALRM
, sigalrm
);
167 Msg
(0, "'%s' is not a tty", line
);
169 signal
(SIGALRM
, sigalrm
);
173 #if defined(I_POP) && defined(POP_TTYMODULES)
174 debug
("OpenTTY I_POP\n");
175 while (ioctl
(f
, I_POP
, (char
*)0) >= 0)
179 * We come here exclusively. This is to stop all kermit and cu
type things
180 * accessing the same tty line.
181 * Perhaps we should better create a lock
in some
/usr
/spool
/locks directory?
185 if (ioctl
(f
, TIOCEXCL
, (char
*) 0) < 0)
186 Msg
(errno
, "%s: ioctl TIOCEXCL failed", line
);
187 debug3
("%d %d %d\n", getuid
(), geteuid
(), getpid
());
188 debug2
("%s TIOCEXCL errno %d\n", line
, errno
);
189 #endif /* TIOCEXCL */
191 * We create a sane tty mode. We
do not copy things from the display tty
193 #if WE_REALLY_WANT_TO_COPY_THE_TTY_MODE
196 debug1
("OpenTTY: using mode of display for %s\n", line
);
201 InitTTY
(&Mode
, W_TYPE_PLAIN
);
203 SttyMode
(&Mode
, opt
);
209 #if defined(linux) && defined(TIOCMSET)
212 ioctl
(f
, TIOCMGET
, &mcs
);
214 ioctl
(f
, TIOCMSET
, &mcs
);
220 signal
(SIGALRM
, sigalrm
);
221 debug2
("'%s' CONNECT fd=%d.\n", line
, f
);
235 bzero
((char
*)m
, sizeof
(*m
));
237 /* struct termios tio
238 * defaults
, as seen on SunOS
4.1.3
240 debug1
("InitTTY: POSIX: termios defaults based on SunOS 4.1.3, but better (%d)\n", ttyflag
);
241 IF
{BRKINT
} m-
>tio.c_iflag |
= BRKINT
;
242 IF
{IGNPAR
} m-
>tio.c_iflag |
= IGNPAR
;
243 /* IF
{ISTRIP
} m-
>tio.c_iflag |
= ISTRIP
; may be needed
, let's try. jw. */
244 IF{IXON} m->tio.c_iflag |= IXON;
245 /* IF{IMAXBEL} m->tio.c_iflag |= IMAXBEL; sorry, this one is ridiculus. jw */
247 if (!ttyflag) /* may not even be good for ptys.. */
249 IF{ICRNL} m->tio.c_iflag |= ICRNL;
250 IF{ONLCR} m->tio.c_oflag |= ONLCR;
251 IF{TAB3} m->tio.c_oflag |= TAB3;
252 IF{OXTABS} m->tio.c_oflag |= OXTABS;
253 /* IF{PARENB} m->tio.c_cflag |= PARENB; nah! jw. */
254 IF{OPOST} m->tio.c_oflag |= OPOST;
259 * Or-ing the speed into c_cflags is dangerous.
260 * It breaks on bsdi, where c_ispeed and c_ospeed are extra longs.
262 * IF{B9600} m->tio.c_cflag |= B9600;
263 * IF{IBSHIFT) && defined(B9600} m->tio.c_cflag |= B9600 << IBSHIFT;
265 * We hope that we have the posix calls to do it right:
266 * If these are not available you might try the above.
268 IF{B9600} cfsetospeed(&m->tio, B9600);
269 IF{B9600} cfsetispeed(&m->tio, B9600);
271 IF{CS8} m->tio.c_cflag |= CS8;
272 IF{CREAD} m->tio.c_cflag |= CREAD;
273 IF{CLOCAL} m->tio.c_cflag |= CLOCAL;
275 IF{ECHOCTL} m->tio.c_lflag |= ECHOCTL;
276 IF{ECHOKE} m->tio.c_lflag |= ECHOKE;
280 IF{ISIG} m->tio.c_lflag |= ISIG;
281 IF{ICANON} m->tio.c_lflag |= ICANON;
282 IF{ECHO} m->tio.c_lflag |= ECHO;
284 IF{ECHOE} m->tio.c_lflag |= ECHOE;
285 IF{ECHOK} m->tio.c_lflag |= ECHOK;
286 IF{IEXTEN} m->tio.c_lflag |= IEXTEN;
288 XIF{VINTR} m->tio.c_cc[VINTR] = Ctrl('C
');
289 XIF{VQUIT} m->tio.c_cc[VQUIT] = Ctrl('\\');
290 XIF{VERASE} m->tio.c_cc[VERASE] = 0x7f; /* DEL */
291 XIF{VKILL} m->tio.c_cc[VKILL] = Ctrl('H
');
292 XIF{VEOF} m->tio.c_cc[VEOF] = Ctrl('D
');
293 XIF{VEOL} m->tio.c_cc[VEOL] = 0000;
294 XIF{VEOL2} m->tio.c_cc[VEOL2] = 0000;
295 XIF{VSWTCH} m->tio.c_cc[VSWTCH] = 0000;
296 XIF{VSTART} m->tio.c_cc[VSTART] = Ctrl('Q
');
297 XIF{VSTOP} m->tio.c_cc[VSTOP] = Ctrl('S
');
298 XIF{VSUSP} m->tio.c_cc[VSUSP] = Ctrl('Z
');
299 XIF{VDSUSP} m->tio.c_cc[VDSUSP] = Ctrl('Y
');
300 XIF{VREPRINT} m->tio.c_cc[VREPRINT] = Ctrl('R
');
301 XIF{VDISCARD} m->tio.c_cc[VDISCARD] = Ctrl('O
');
302 XIF{VWERASE} m->tio.c_cc[VWERASE] = Ctrl('W
');
303 XIF{VLNEXT} m->tio.c_cc[VLNEXT] = Ctrl('V
');
304 XIF{VSTATUS} m->tio.c_cc[VSTATUS] = Ctrl('T
');
308 m->tio.c_cc[VMIN] = TTYVMIN;
309 m->tio.c_cc[VTIME] = TTYVTIME;
312 # ifdef HPUX_LTCHARS_HACK
313 m->m_ltchars.t_suspc = Ctrl('Z
');
314 m->m_ltchars.t_dsuspc = Ctrl('Y
');
315 m->m_ltchars.t_rprntc = Ctrl('R
');
316 m->m_ltchars.t_flushc = Ctrl('O
');
317 m->m_ltchars.t_werasc = Ctrl('W
');
318 m->m_ltchars.t_lnextc = Ctrl('V
');
319 # endif /* HPUX_LTCHARS_HACK */
324 debug1("InitTTY: nonPOSIX, struct termio a la Motorola SYSV68 (%d)\n", ttyflag);
326 * defaults, as seen on Mototola SYSV68:
327 * input: 7bit, CR->NL, ^S/^Q flow control
328 * output: POSTprocessing: NL->NL-CR, Tabs to spaces
329 * control: 9600baud, 8bit CSIZE, enable input
330 * local: enable signals, erase/kill processing, echo on.
332 IF{ISTRIP} m->tio.c_iflag |= ISTRIP;
333 IF{IXON} m->tio.c_iflag |= IXON;
335 if (!ttyflag) /* may not even be good for ptys.. */
337 IF{OPOST} m->tio.c_oflag |= OPOST;
338 IF{ICRNL} m->tio.c_iflag |= ICRNL;
339 IF{ONLCR} m->tio.c_oflag |= ONLCR;
340 IF{TAB3} m->tio.c_oflag |= TAB3;
344 )-: cannot handle BSDI without POSIX
346 IF{B9600} m->tio.c_cflag = B9600;
348 IF{CS8} m->tio.c_cflag |= CS8;
349 IF{CREAD} m->tio.c_cflag |= CREAD;
353 IF{ISIG} m->tio.c_lflag |= ISIG;
354 IF{ICANON} m->tio.c_lflag |= ICANON;
355 IF{ECHO} m->tio.c_lflag |= ECHO;
357 IF{ECHOE} m->tio.c_lflag |= ECHOE;
358 IF{ECHOK} m->tio.c_lflag |= ECHOK;
360 XIF{VINTR} m->tio.c_cc[VINTR] = Ctrl('C
');
361 XIF{VQUIT} m->tio.c_cc[VQUIT] = Ctrl('\\');
362 XIF{VERASE} m->tio.c_cc[VERASE] = 0177; /* DEL */
363 XIF{VKILL} m->tio.c_cc[VKILL] = Ctrl('H
');
364 XIF{VEOF} m->tio.c_cc[VEOF] = Ctrl('D
');
365 XIF{VEOL} m->tio.c_cc[VEOL] = 0377;
366 XIF{VEOL2} m->tio.c_cc[VEOL2] = 0377;
367 XIF{VSWTCH} m->tio.c_cc[VSWTCH] = 0000;
371 m->tio.c_cc[VMIN] = TTYVMIN;
372 m->tio.c_cc[VTIME] = TTYVTIME;
376 debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
377 m->m_ttyb.sg_ispeed = B9600;
378 m->m_ttyb.sg_ospeed = B9600;
379 m->m_ttyb.sg_erase = 0177; /*DEL */
380 m->m_ttyb.sg_kill = Ctrl('H
');
382 m->m_ttyb.sg_flags = CRMOD | ECHO
386 m->m_ttyb.sg_flags = CBREAK
390 m->m_tchars.t_intrc = Ctrl('C
');
391 m->m_tchars.t_quitc = Ctrl('\\');
392 m->m_tchars.t_startc = Ctrl('Q
');
393 m->m_tchars.t_stopc = Ctrl('S
');
394 m->m_tchars.t_eofc = Ctrl('D
');
395 m->m_tchars.t_brkc = -1;
397 m->m_ltchars.t_suspc = Ctrl('Z
');
398 m->m_ltchars.t_dsuspc = Ctrl('Y
');
399 m->m_ltchars.t_rprntc = Ctrl('R
');
400 m->m_ltchars.t_flushc = Ctrl('O
');
401 m->m_ltchars.t_werasc = Ctrl('W
');
402 m->m_ltchars.t_lnextc = Ctrl('V
');
404 IF{NTTYDISC} m->m_ldisc = NTTYDISC;
407 IF{LDECCTQ} | LDECCTQ
408 IF{LCTLECH} | LCTLECH
410 IF{LCRTKIL} | LCRTKIL
411 IF{LCRTERA} | LCRTERA
417 #if defined(ENCODINGS) && defined(TIOCKSET)
418 m->m_jtchars.t_ascii = 'J
';
419 m->m_jtchars.t_kanji = 'B
';
420 m->m_knjmode = KM_ASCII | KM_SYSSJIS;
431 tcsetattr(fd, TCSADRAIN, &mp->tio);
432 # ifdef HPUX_LTCHARS_HACK
433 ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars);
437 ioctl(fd, TCSETAW, (char *)&mp->tio);
439 if (mp->tio.c_line == 3)
441 ioctl(fd, LDSETMAPKEY, (char *)&mp->m_mapkey);
442 ioctl(fd, LDSETMAPSCREEN, (char *)&mp->m_mapscreen);
443 ioctl(fd, LDSETBACKSPACE, (char *)&mp->m_backspace);
447 /* ioctl(fd, TIOCSETP, (char *)&mp->m_ttyb); */
448 ioctl(fd, TIOCSETC, (char *)&mp->m_tchars);
449 ioctl(fd, TIOCLSET, (char *)&mp->m_lmode);
450 ioctl(fd, TIOCSETD, (char *)&mp->m_ldisc);
451 ioctl(fd, TIOCSETP, (char *)&mp->m_ttyb);
452 ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars); /* moved here for apollo. jw */
455 #if defined(ENCODINGS) && defined(TIOCKSET)
456 ioctl(fd, TIOCKSETC, &mp->m_jtchars);
457 ioctl(fd, TIOCKSET, &mp->m_knjmode);
460 Msg(errno, "SetTTY (fd %d): ioctl failed", fd);
470 tcgetattr(fd, &mp->tio);
471 # ifdef HPUX_LTCHARS_HACK
472 ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
476 ioctl(fd, TCGETA, (char *)&mp->tio);
478 if (mp->tio.c_line == 3)
480 ioctl(fd, LDGETMAPKEY, (char *)&mp->m_mapkey);
481 ioctl(fd, LDGETMAPSCREEN, (char *)&mp->m_mapscreen);
482 ioctl(fd, LDGETBACKSPACE, (char *)&mp->m_backspace);
486 mp->m_mapkey = NOMAPKEY;
487 mp->m_mapscreen = NOMAPSCREEN;
488 mp->m_backspace = '\b';
492 ioctl(fd, TIOCGETP, (char *)&mp->m_ttyb);
493 ioctl(fd, TIOCGETC, (char *)&mp->m_tchars);
494 ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
495 ioctl(fd, TIOCLGET, (char *)&mp->m_lmode);
496 ioctl(fd, TIOCGETD, (char *)&mp->m_ldisc);
499 #if defined(ENCODINGS) && defined(TIOCKSET)
500 ioctl(fd, TIOCKGETC, &mp->m_jtchars);
501 ioctl(fd, TIOCKGET, &mp->m_knjmode);
504 Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
508 * needs interrupt = iflag and flow = d->d_flow
511 SetMode(op, np, flow, interrupt)
512 struct mode *op, *np;
518 #if defined(TERMIO) || defined(POSIX)
520 np->m_mapkey = NOMAPKEY;
521 np->m_mapscreen = NOMAPSCREEN;
524 IF{ICRNL} np->tio.c_iflag &= ~ICRNL;
525 IF{ISTRIP} np->tio.c_iflag &= ~ISTRIP;
526 IF{ONLCR} np->tio.c_oflag &= ~ONLCR;
527 np->tio.c_lflag &= ~(ICANON | ECHO);
529 * From Andrew Myers (andru@tonic.lcs.mit.edu)
530 * to avoid ^V^V-Problem on OSF1
532 IF{IEXTEN} np->tio.c_lflag &= ~IEXTEN;
535 * Unfortunately, the master process never will get SIGINT if the real
536 * terminal is different from the one on which it was originaly started
537 * (process group membership has not been restored or the new tty could not
538 * be made controlling again). In my solution, it is the attacher who
539 * receives SIGINT (because it is always correctly associated with the real
540 * tty) and forwards it to the master [kill(MasterPid, SIGINT)].
541 * Marc Boucher (marc@CAM.ORG)
544 np->tio.c_lflag |= ISIG;
546 np->tio.c_lflag &= ~ISIG;
548 * careful, careful catche monkey..
549 * never set VMIN and VTIME to zero, if you want blocking io.
551 * We may want to do a VMIN > 0, VTIME > 0 read on the ptys too, to
552 * reduce interrupt frequency. But then we would not know how to
553 * handle read returning 0. jw.
555 np->tio.c_cc[VMIN] = 1;
556 np->tio.c_cc[VTIME] = 0;
557 if (!interrupt || !flow)
558 np->tio.c_cc[VINTR] = VDISABLE;
559 np->tio.c_cc[VQUIT] = VDISABLE;
562 XIF{VSTART} np->tio.c_cc[VSTART] = VDISABLE;
563 XIF{VSTOP} np->tio.c_cc[VSTOP] = VDISABLE;
564 np->tio.c_iflag &= ~IXON;
566 XIF{VDISCARD} np->tio.c_cc[VDISCARD] = VDISABLE;
567 XIF{VLNEXT} np->tio.c_cc[VLNEXT] = VDISABLE;
568 XIF{VSTATUS} np->tio.c_cc[VSTATUS] = VDISABLE;
569 XIF{VSUSP} np->tio.c_cc[VSUSP] = VDISABLE;
570 /* Set VERASE to DEL, rather than VDISABLE, to avoid libvte
571 "autodetect" issues. */
572 XIF{VERASE} np->tio.c_cc[VERASE] = 0x7f;
573 XIF{VKILL} np->tio.c_cc[VKILL] = VDISABLE;
574 # ifdef HPUX_LTCHARS_HACK
575 np->m_ltchars.t_suspc = VDISABLE;
576 np->m_ltchars.t_dsuspc = VDISABLE;
577 np->m_ltchars.t_rprntc = VDISABLE;
578 np->m_ltchars.t_flushc = VDISABLE;
579 np->m_ltchars.t_werasc = VDISABLE;
580 np->m_ltchars.t_lnextc = VDISABLE;
581 # else /* HPUX_LTCHARS_HACK */
582 XIF{VDSUSP} np->tio.c_cc[VDSUSP] = VDISABLE;
583 XIF{VREPRINT} np->tio.c_cc[VREPRINT] = VDISABLE;
584 XIF{VWERASE} np->tio.c_cc[VWERASE] = VDISABLE;
585 # endif /* HPUX_LTCHARS_HACK */
586 #else /* TERMIO || POSIX */
587 if (!interrupt || !flow)
588 np->m_tchars.t_intrc = -1;
589 np->m_ttyb.sg_flags &= ~(CRMOD | ECHO);
590 np->m_ttyb.sg_flags |= CBREAK;
591 # if defined(CYRILL) && defined(CSTYLE) && defined(CS_8BITS)
592 np->m_ttyb.sg_flags &= ~CSTYLE;
593 np->m_ttyb.sg_flags |= CS_8BITS;
595 np->m_tchars.t_quitc = -1;
598 np->m_tchars.t_startc = -1;
599 np->m_tchars.t_stopc = -1;
601 np->m_ltchars.t_suspc = -1;
602 np->m_ltchars.t_dsuspc = -1;
603 np->m_ltchars.t_flushc = -1;
604 np->m_ltchars.t_lnextc = -1;
605 #endif /* defined(TERMIO) || defined(POSIX) */
608 /* operates on display */
616 #if defined(TERMIO) || defined(POSIX)
619 D_NewMode.tio.c_cc[VINTR] = iflag ? D_OldMode.tio.c_cc[VINTR] : VDISABLE;
620 XIF{VSTART} D_NewMode.tio.c_cc[VSTART] = D_OldMode.tio.c_cc[VSTART];
621 XIF{VSTOP} D_NewMode.tio.c_cc[VSTOP] = D_OldMode.tio.c_cc[VSTOP];
622 D_NewMode.tio.c_iflag |= D_OldMode.tio.c_iflag & IXON;
626 D_NewMode.tio.c_cc[VINTR] = VDISABLE;
627 XIF{VSTART} D_NewMode.tio.c_cc[VSTART] = VDISABLE;
628 XIF{VSTOP} D_NewMode.tio.c_cc[VSTOP] = VDISABLE;
629 D_NewMode.tio.c_iflag &= ~IXON;
634 tcflow(D_userfd, TCOON);
636 if (tcsetattr(D_userfd, TCSANOW, &D_NewMode.tio))
638 if (ioctl(D_userfd, TCSETAW, (char *)&D_NewMode.tio) != 0)
640 debug1("SetFlow: ioctl errno %d\n", errno);
641 #else /* POSIX || TERMIO */
644 D_NewMode.m_tchars.t_intrc = iflag ? D_OldMode.m_tchars.t_intrc : -1;
645 D_NewMode.m_tchars.t_startc = D_OldMode.m_tchars.t_startc;
646 D_NewMode.m_tchars.t_stopc = D_OldMode.m_tchars.t_stopc;
650 D_NewMode.m_tchars.t_intrc = -1;
651 D_NewMode.m_tchars.t_startc = -1;
652 D_NewMode.m_tchars.t_stopc = -1;
654 if (ioctl(D_userfd, TIOCSETC, (char *)&D_NewMode.m_tchars) != 0)
655 debug1("SetFlow: ioctl errno %d\n", errno);
656 #endif /* POSIX || TERMIO */
660 /* parse commands from opt and modify m */
666 static const char sep[] = " \t:;,";
673 while (index(sep, *opt)) opt++;
674 if (*opt >= '0' && *opt <= '9')
676 if (SetBaud(m, atoi(opt), atoi(opt)))
679 else if (!strncmp("cs7", opt, 3))
681 #if defined(POSIX) || defined(TERMIO)
682 m->tio.c_cflag &= ~CSIZE;
683 m->tio.c_cflag |= CS7;
685 m->m_lmode &= ~LPASS8;
688 else if (!strncmp("cs8", opt, 3))
690 #if defined(POSIX) || defined(TERMIO)
691 m->tio.c_cflag &= ~CSIZE;
692 m->tio.c_cflag |= CS8;
694 m->m_lmode |= LPASS8;
697 else if (!strncmp("istrip", opt, 6))
699 #if defined(POSIX) || defined(TERMIO)
700 m->tio.c_iflag |= ISTRIP;
702 m->m_lmode &= ~LPASS8;
705 else if (!strncmp("-istrip", opt, 7))
707 #if defined(POSIX) || defined(TERMIO)
708 m->tio.c_iflag &= ~ISTRIP;
710 m->m_lmode |= LPASS8;
713 else if (!strncmp("ixon", opt, 4))
715 #if defined(POSIX) || defined(TERMIO)
716 m->tio.c_iflag |= IXON;
718 debug("SttyMode: no ixon in old bsd land.\n");
721 else if (!strncmp("-ixon", opt, 5))
723 #if defined(POSIX) || defined(TERMIO)
724 m->tio.c_iflag &= ~IXON;
726 debug("SttyMode: no -ixon in old bsd land.\n");
729 else if (!strncmp("ixoff", opt, 5))
731 #if defined(POSIX) || defined(TERMIO)
732 m->tio.c_iflag |= IXOFF;
734 m->m_ttyb.sg_flags |= TANDEM;
737 else if (!strncmp("-ixoff", opt, 6))
739 #if defined(POSIX) || defined(TERMIO)
740 m->tio.c_iflag &= ~IXOFF;
742 m->m_ttyb.sg_flags &= ~TANDEM;
745 else if (!strncmp("crtscts", opt, 7))
747 #if (defined(POSIX) || defined(TERMIO)) && defined(CRTSCTS)
748 m->tio.c_cflag |= CRTSCTS;
751 else if (!strncmp("-crtscts", opt, 8))
753 #if (defined(POSIX) || defined(TERMIO)) && defined(CRTSCTS)
754 m->tio.c_cflag &= ~CRTSCTS;
759 while (*opt && !index(sep, *opt)) opt++;
765 * Job control handling
767 * Somehow the ultrix session handling is broken, so use
768 * the bsdish variant.
776 #if defined(POSIX) && !defined(ultrix)
778 setsid(); /* will break terminal affiliation */
779 /* GNU added for Hurd systems 2001-10-10 */
780 # if defined(BSD) && defined(TIOCSCTTY) && !defined(__GNU__)
781 ioctl(fd, TIOCSCTTY, (char *)0);
782 # endif /* BSD && TIOCSCTTY */
786 setpgrp(); /* will break terminal affiliation */
791 if ((devtty = open("/dev/tty", O_RDWR | O_NONBLOCK)) >= 0)
793 if (ioctl(devtty, TIOCNOTTY, (char *)0))
794 debug2("brktty: ioctl(devtty=%d, TIOCNOTTY, 0) = %d\n", devtty, errno);
797 # endif /* BSDJOBS */
811 /* The next lines should be obsolete. Can anybody check if they
812 * are really needed on the BSD platforms?
814 * this is to avoid the message:
815 * fgtty: Not a typewriter (25)
817 # if defined(__osf__) || (BSD >= 199103) || defined(ISC)
819 setsid(); /* should be already done */
821 ioctl(fd, TIOCSCTTY, (char *)0);
827 if (tcsetpgrp(fd, mypid))
829 debug1("fgtty: tcsetpgrp: %d\n", errno);
833 if (ioctl(fd, TIOCSPGRP, (char *)&mypid) != 0)
834 debug1("fgtty: TIOSETPGRP: %d\n", errno);
835 # ifndef SYSV /* Already done in brktty():setpgrp() */
837 if (setpgrp(fd, mypid))
838 debug1("fgtty: setpgrp: %d\n", errno);
846 * The alm boards on our sparc center 1000 have a lousy driver.
847 * We cannot generate long breaks unless we use the most ugly form
860 #if defined(sun) && !defined(SVR4)
861 # define HAVE_SUPER_TCSENDBREAK
866 * 0: TIOCSBRK / TIOCCBRK
869 * n: approximate duration in 1/4 seconds.
872 DoSendBreak(fd, n, type)
877 case 2: /* tcsendbreak() =============================== */
879 # ifdef HAVE_SUPER_TCSENDBREAK
880 /* There is one rare case that I have tested, where tcsendbreak works
881 * really great: this was an alm driver that came with SunOS 4.1.3
882 * If you have this one, define the above symbol.
883 * here we can use the second parameter to specify the duration.
885 debug2("tcsendbreak(fd=%d, %d)\n", fd, n);
886 if (tcsendbreak(fd, n) < 0)
887 Msg(errno, "cannot send BREAK (tcsendbreak)");
890 * here we hope, that multiple calls to tcsendbreak() can
891 * be concatenated to form a long break, as we do not know
892 * what exact interpretation the second parameter has:
894 * - sunos 4: duration in quarter seconds
895 * - sunos 5: 0 a short break, nonzero a tcdrain()
896 * - hpux, irix: ignored
897 * - mot88: duration in milliseconds
898 * - aix: duration in milliseconds, but 0 is 25 milliseconds.
900 debug2("%d * tcsendbreak(fd=%d, 0)\n", n, fd);
906 for (i = 0; i < n; i++)
907 if (tcsendbreak(fd, 0) < 0)
909 Msg(errno, "cannot send BREAK (tcsendbreak SVR4)");
915 Msg(0, "tcsendbreak() not available, change breaktype");
919 case 1: /* TCSBRK ======================================= */
924 * Here too, we assume that short breaks can be concatenated to
925 * perform long breaks. But for SOLARIS, this is not true, of course.
927 debug2("%d * TCSBRK fd=%d\n", n, fd);
931 for (i = 0; i < n; i++)
932 if (ioctl(fd, TCSBRK, (char *)0) < 0)
934 Msg(errno, "Cannot send BREAK (TCSBRK)");
939 Msg(0, "TCSBRK not available, change breaktype");
943 case 0: /* TIOCSBRK / TIOCCBRK ========================== */
944 #if defined(TIOCSBRK) && defined(TIOCCBRK)
946 * This is very rude. Screen actively celebrates the break.
947 * But it may be the only save way to issue long breaks.
949 debug("TIOCSBRK TIOCCBRK\n");
950 if (ioctl(fd, TIOCSBRK, (char *)0) < 0)
952 Msg(errno, "Can't send BREAK
(TIOCSBRK
)");
955 sleep1000(n ? n * 250 : 250);
956 if (ioctl(fd, TIOCCBRK, (char *)0) < 0)
958 Msg(errno, "BREAK stuck
!!! -- HELP
! (TIOCCBRK
)");
961 #else /* TIOCSBRK && TIOCCBRK */
962 Msg(0, "TIOCSBRK
/CBRK not available
, change breaktype
");
963 #endif /* TIOCSBRK && TIOCCBRK */
966 default: /* unknown ========================== */
967 Msg(0, "Internal SendBreak error
: method
%d unknown
", type);
972 * Send a break for n * 0.25 seconds. Tty must be PLAIN.
973 * The longest possible break allowed here is 15 seconds.
977 SendBreak(wp, n, closeopen)
981 sigret_t (*sigalrm)__P(SIGPROTOARG);
983 #ifdef BUILTIN_TELNET
984 if (wp->w_type == W_TYPE_TELNET)
990 if (wp->w_type != W_TYPE_PLAIN)
993 debug3("break(%d
, %d
) fd
%d
\n", n, closeopen, wp->w_ptyfd);
996 (void) tcflush(wp->w_ptyfd, TCIOFLUSH);
999 (void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
1000 # endif /* TIOCFLUSH */
1006 sleep1000(n ? n * 250 : 250);
1007 if ((wp->w_ptyfd = OpenTTY(wp->w_tty, wp->w_cmdargs[1])) < 1)
1009 Msg(0, "Ouch
, cannot reopen line
%s
, please try harder
", wp->w_tty);
1012 (void) fcntl(wp->w_ptyfd, F_SETFL, FNBLOCK);
1016 sigalrm = signal(SIGALRM, SigAlrmDummy);
1019 DoSendBreak(wp->w_ptyfd, n, breaktype);
1022 signal(SIGALRM, sigalrm);
1024 debug(" broken.
\n");
1031 #if (!defined(TIOCCONS) && defined(SRIOCSREDIR)) || defined(linux)
1033 static struct event consredir_ev;
1034 static int consredirfd[2] = {-1, -1};
1037 consredir_readev_fn(ev, data)
1041 char *p, *n, buf[256];
1044 if (!console_window || (l = read(consredirfd[0], buf, sizeof(buf))) <= 0)
1046 close(consredirfd[0]);
1047 close(consredirfd[1]);
1048 consredirfd[0] = consredirfd[1] = -1;
1052 for (p = n = buf; l > 0; n++, l--)
1056 WriteString(console_window, p, n - p);
1057 WriteString(console_window, "\r\n", 2);
1061 WriteString(console_window, p, n - p);
1068 TtyGrabConsole(fd, on, rc_name)
1072 #if defined(TIOCCONS) && !defined(linux)
1078 return 0; /* pty close will ungrab */
1083 Msg(0, "I need a display
");
1086 for (d = displays; d; d = d->d_next)
1087 if (strcmp(d->d_usertty, "/dev
/console
") == 0)
1091 Msg(0, "too dangerous
- screen is running on
/dev
/console
");
1099 if ((fd = OpenPTY(&slave)) < 0)
1101 Msg(errno, "%s
: could not open detach pty master
", rc_name);
1104 if ((sfd = open(slave, O_RDWR | O_NOCTTY)) < 0)
1106 Msg(errno, "%s
: could not open detach pty slave
", rc_name);
1111 if (UserContext() == 1)
1112 UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
1115 Msg(errno, "%s
: ioctl TIOCCONS failed
", rc_name);
1124 # if defined(SRIOCSREDIR) || defined(linux)
1129 struct mode new1, new2;
1137 Msg(0, "I need a display
");
1140 for (d = displays; d; d = d->d_next)
1141 if (strcmp(d->d_usertty, "/dev
/console
") == 0)
1145 Msg(0, "too dangerous
- screen is running on
/dev
/console
");
1149 if (consredirfd[0] >= 0)
1151 evdeq(&consredir_ev);
1152 close(consredirfd[0]);
1153 close(consredirfd[1]);
1154 consredirfd[0] = consredirfd[1] = -1;
1159 if ((cfd = secopen("/dev
/console
", O_RDWR|O_NOCTTY, 0)) == -1)
1161 Msg(errno, "/dev
/console
");
1164 if (pipe(consredirfd))
1168 consredirfd[0] = consredirfd[1] = -1;
1171 if (ioctl(cfd, SRIOCSREDIR, consredirfd[1]))
1173 Msg(errno, "SRIOCSREDIR ioctl
");
1175 close(consredirfd[0]);
1176 close(consredirfd[1]);
1177 consredirfd[0] = consredirfd[1] = -1;
1182 /* special linux workaround for a too restrictive kernel */
1183 if ((consredirfd[0] = OpenPTY(&slave)) < 0)
1185 Msg(errno, "%s
: could not open detach pty master
", rc_name);
1188 if ((consredirfd[1] = open(slave, O_RDWR | O_NOCTTY)) < 0)
1190 Msg(errno, "%s
: could not open detach pty slave
", rc_name);
1191 close(consredirfd[0]);
1195 SetMode(&new1, &new2, 0, 0);
1196 SetTTY(consredirfd[1], &new2);
1197 if (UserContext() == 1)
1198 UserReturn(ioctl(consredirfd[1], TIOCCONS, (char *)&on));
1201 Msg(errno, "%s
: ioctl TIOCCONS failed
", rc_name);
1202 close(consredirfd[0]);
1203 close(consredirfd[1]);
1207 consredir_ev.fd = consredirfd[0];
1208 consredir_ev.type = EV_READ;
1209 consredir_ev.handler = consredir_readev_fn;
1210 evenq(&consredir_ev);
1214 Msg(0, "%s
: don
't know how to grab the console", rc_name);
1221 * Read modem control lines of a physical tty and write them to buf
1222 * in a readable format.
1223 * Will not write more than 256 characters to buf.
1227 TtyGetModemStatus(fd, buf)
1233 unsigned int softcar;
1235 #if defined(TIOCMGET) || defined(TIOCMODG)
1236 unsigned int mflags;
1239 /* this is yet another interface, found on hpux. grrr */
1241 IF{MDTR}# define TIOCM_DTR MDTR
1242 IF{MRTS}# define TIOCM_RTS MRTS
1243 IF{MDSR}# define TIOCM_DSR MDSR
1244 IF{MDCD}# define TIOCM_CAR MDCD
1245 IF{MRI}# define TIOCM_RNG MRI
1246 IF{MCTS}# define TIOCM_CTS MCTS
1249 #if defined(CLOCAL) || defined(CRTSCTS)
1250 struct mode mtio; /* screen.h */
1252 #if defined(CRTSCTS) || defined(TIOCM_CTS)
1257 #if defined(CLOCAL) || defined(CRTSCTS)
1262 if (mtio.tio.c_cflag & CLOCAL)
1271 if (!(mtio.tio.c_cflag & CRTSCTS))
1274 # endif /* CRTSCTS */
1276 #endif /* TIOCM_CTS */
1279 if (ioctl(fd, TIOCGSOFTCAR, (char *)&softcar) < 0)
1283 #if defined(TIOCMGET) || defined(TIOCMODG) || defined(MCGETA)
1285 if (ioctl(fd, TIOCMGET, (char *)&mflags) < 0)
1288 if (ioctl(fd, TIOCMODG, (char *)&mflags) < 0)
1290 if (ioctl(fd, MCGETA, &mflags) < 0)
1295 sprintf(p, "NO-TTY? %s", softcar ? "(CD)" : "CD");
1297 sprintf(p, "NO-TTY?");
1306 if (!(mflags & TIOCM_LE))
1307 for (s = "!LE "; *s; *p++ = *s++);
1309 # endif /* FANCY_MODEM */
1312 s = "!RTS "; if (mflags & TIOCM_RTS) s++;
1313 while (*s) *p++ = *s++;
1322 if (mflags & TIOCM_CTS) s++;
1323 while (*s) *p++ = *s++;
1327 s = "!DTR "; if (mflags & TIOCM_DTR) s++;
1328 while (*s) *p++ = *s++;
1331 s = "!DSR "; if (mflags & TIOCM_DSR) s++;
1332 while (*s) *p++ = *s++;
1334 # if defined(TIOCM_CD) || defined(TIOCM_CAR)
1336 # ifdef TIOCGSOFTCAR
1344 if (mflags & TIOCM_CD) s++;
1346 if (mflags & TIOCM_CAR) s++;
1348 while (*s) *p++ = *s++;
1350 # if defined(TIOCM_RI) || defined(TIOCM_RNG)
1352 if (mflags & TIOCM_RI)
1354 if (mflags & TIOCM_RNG)
1356 for (s = "RI "; *s; *p++ = *s++);
1360 s = "!ST "; if (mflags & TIOCM_ST) s++;
1361 while (*s) *p++ = *s++;
1364 s = "!SR "; if (mflags & TIOCM_SR) s++;
1365 while (*s) *p++ = *s++;
1367 # endif /* FANCY_MODEM */
1368 if (p > buf && p[-1] == ' ')
1373 # ifdef TIOCGSOFTCAR
1374 sprintf(p, " %s", softcar ? "(CD)", "CD");
1385 * Old bsd-ish machines may not have any of the baudrate B... symbols.
1386 * We hope to detect them here, so that the btable[] below always has
1391 # if !defined(B9600) && !defined(B2400) && !defined(B1200) && !defined(B300)
1393 IFN{B50}#define B50 1
1394 IFN{B75}#define B75 2
1395 IFN{B110}#define B110 3
1396 IFN{B134}#define B134 4
1397 IFN{B150}#define B150 5
1398 IFN{B200}#define B200 6
1399 IFN{B300}#define B300 7
1400 IFN{B600}#define B600 8
1401 IFN{B1200}#define B1200 9
1402 IFN{B1800}#define B1800 10
1403 IFN{B2400}#define B2400 11
1404 IFN{B4800}#define B4800 12
1405 IFN{B9600}#define B9600 13
1406 IFN{EXTA}#define EXTA 14
1407 IFN{EXTB}#define EXTB 15
1413 * On hpux, idx and sym will be different.
1414 * Rumor has it that, we need idx in D_dospeed to make tputs
1416 * Frequently used entries come first.
1418 static struct baud_values btable[] =
1420 IF{B9600} { 13, 9600, B9600 },
1421 IF{B19200} { 14, 19200, B19200 },
1422 IF{EXTA} { 14, 19200, EXTA },
1423 IF{B38400} { 15, 38400, B38400 },
1424 IF{EXTB} { 15, 38400, EXTB },
1425 IF{B57600} { 16, 57600, B57600 },
1426 IF{B115200} { 17, 115200, B115200 },
1427 IF{B230400} { 18, 230400, B230400 },
1428 IF{B460800} { 19, 460800, B460800 },
1429 IF{B7200} { 13, 7200, B7200 },
1430 IF{B4800} { 12, 4800, B4800 },
1431 IF{B3600} { 12, 3600, B3600 },
1432 IF{B2400} { 11, 2400, B2400 },
1433 IF{B1800} { 10, 1800, B1800 },
1434 IF{B1200} { 9, 1200, B1200 },
1435 IF{B900} { 9, 900, B900 },
1436 IF{B600} { 8, 600, B600 },
1437 IF{B300} { 7, 300, B300 },
1438 IF{B200} { 6, 200, B200 },
1439 IF{B150} { 5, 150, B150 },
1440 IF{B134} { 4, 134, B134 },
1441 IF{B110} { 3, 110, B110 },
1442 IF{B75} { 2, 75, B75 },
1443 IF{B50} { 1, 50, B50 },
1444 IF{B0} { 0, 0, B0 },
1449 * baud may either be a bits-per-second value or a symbolic
1450 * value as returned by cfget?speed()
1452 struct baud_values *
1456 struct baud_values *p;
1458 for (p = btable; p->idx >= 0; p++)
1459 if (baud == p->bps || baud == p->sym)
1465 * change the baud rate in a mode structure.
1466 * ibaud and obaud are given in bit/second, or at your option as
1467 * termio B... symbols as defined in e.g. suns sys/ttydev.h
1468 * -1 means don't change.
1471 SetBaud
(m
, ibaud
, obaud
)
1475 struct baud_values
*ip
, *op
;
1477 if ((!(ip
= lookup_baud
(ibaud
)) && ibaud
!= -1) ||
1478 (!(op
= lookup_baud
(obaud
)) && obaud
!= -1))
1482 if (ip
) cfsetispeed
(&m-
>tio
, ip-
>sym
);
1483 if (op
) cfsetospeed
(&m-
>tio
, op-
>sym
);
1489 m-
>tio.c_cflag
&= ~
(CBAUD
<< IBSHIFT);
1490 m->tio.c_cflag |= (ip->sym & CBAUD) << IBSHIFT;
1491 # else /* IBSHIFT */
1494 # endif /* IBSHIFT */
1498 m-
>tio.c_cflag
&= ~CBAUD
;
1499 m-
>tio.c_cflag |
= op-
>sym
& CBAUD
;
1502 if (ip
) m-
>m_ttyb.sg_ispeed
= ip-
>idx
;
1503 if (op
) m-
>m_ttyb.sg_ospeed
= op-
>idx
;
1504 # endif /* TERMIO */
1510 * Write out the mode struct
in a readable form
1521 debug
("struct termios tio:\n");
1522 debug1
("c_iflag = %#x\n", (unsigned int
)m-
>tio.c_iflag
);
1523 debug1
("c_oflag = %#x\n", (unsigned int
)m-
>tio.c_oflag
);
1524 debug1
("c_cflag = %#x\n", (unsigned int
)m-
>tio.c_cflag
);
1525 debug1
("c_lflag = %#x\n", (unsigned int
)m-
>tio.c_lflag
);
1526 debug1
("cfgetospeed() = %d\n", (int
)cfgetospeed
(&m-
>tio
));
1527 debug1
("cfgetispeed() = %d\n", (int
)cfgetispeed
(&m-
>tio
));
1528 for (i
= 0; i
< sizeof
(m-
>tio.c_cc
)/sizeof
(*m-
>tio.c_cc
); i
++)
1530 debug2
("c_cc[%d] = %#x\n", i
, m-
>tio.c_cc
[i
]);
1532 # ifdef HPUX_LTCHARS_HACK
1533 debug1
("suspc = %#02x\n", m-
>m_ltchars.t_suspc
);
1534 debug1
("dsuspc = %#02x\n", m-
>m_ltchars.t_dsuspc
);
1535 debug1
("rprntc = %#02x\n", m-
>m_ltchars.t_rprntc
);
1536 debug1
("flushc = %#02x\n", m-
>m_ltchars.t_flushc
);
1537 debug1
("werasc = %#02x\n", m-
>m_ltchars.t_werasc
);
1538 debug1
("lnextc = %#02x\n", m-
>m_ltchars.t_lnextc
);
1539 # endif /* HPUX_LTCHARS_HACK */
1542 debug
("struct termio tio:\n");
1543 debug1
("c_iflag = %04o\n", m-
>tio.c_iflag
);
1544 debug1
("c_oflag = %04o\n", m-
>tio.c_oflag
);
1545 debug1
("c_cflag = %04o\n", m-
>tio.c_cflag
);
1546 debug1
("c_lflag = %04o\n", m-
>tio.c_lflag
);
1547 for (i
= 0; i
< sizeof
(m-
>tio.c_cc
)/sizeof
(*m-
>tio.c_cc
); i
++)
1549 debug2
("c_cc[%d] = %04o\n", i
, m-
>tio.c_cc
[i
]);
1552 debug1
("sg_ispeed = %d\n", m-
>m_ttyb.sg_ispeed
);
1553 debug1
("sg_ospeed = %d\n", m-
>m_ttyb.sg_ospeed
);
1554 debug1
("sg_erase = %#02x\n", m-
>m_ttyb.sg_erase
);
1555 debug1
("sg_kill = %#02x\n", m-
>m_ttyb.sg_kill
);
1556 debug1
("sg_flags = %#04x\n", (unsigned short
)m-
>m_ttyb.sg_flags
);
1557 debug1
("intrc = %#02x\n", m-
>m_tchars.t_intrc
);
1558 debug1
("quitc = %#02x\n", m-
>m_tchars.t_quitc
);
1559 debug1
("startc = %#02x\n", m-
>m_tchars.t_startc
);
1560 debug1
("stopc = %#02x\n", m-
>m_tchars.t_stopc
);
1561 debug1
("eofc = %#02x\n", m-
>m_tchars.t_eofc
);
1562 debug1
("brkc = %#02x\n", m-
>m_tchars.t_brkc
);
1563 debug1
("suspc = %#02x\n", m-
>m_ltchars.t_suspc
);
1564 debug1
("dsuspc = %#02x\n", m-
>m_ltchars.t_dsuspc
);
1565 debug1
("rprntc = %#02x\n", m-
>m_ltchars.t_rprntc
);
1566 debug1
("flushc = %#02x\n", m-
>m_ltchars.t_flushc
);
1567 debug1
("werasc = %#02x\n", m-
>m_ltchars.t_werasc
);
1568 debug1
("lnextc = %#02x\n", m-
>m_ltchars.t_lnextc
);
1569 debug1
("ldisc = %d\n", m-
>m_ldisc
);
1570 debug1
("lmode = %#x\n", m-
>m_lmode
);
1571 # endif /* TERMIO */