Change how the screen objects are pushed/popped
[screen-lua.git] / src / tty.sh
blob11cbd743fa4865bb26bac622992ea2093dbe4fd8
1 #! /bin/sh
2 # sh tty.sh tty.c
3 # This inserts all the needed #ifdefs for IF{} statements
4 # and generates tty.c
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)
10 rm -f $1
11 sed -e '1,26d' \
12 -e 's%^IF{\([^}]*\)}\(.*\)%#if defined(\1)\
13 \2\
14 #endif /* \1 */%' \
15 -e 's%^IFN{\([^}]*\)}\(.*\)%#if !defined(\1)\
16 \2\
17 #endif /* \1 */%' \
18 -e 's%^XIF{\([^}]*\)}\(.*\)%#if defined(\1)\
19 #if (\1 < MAXCC)\
20 \2\
21 #endif \
22 #endif /* \1 */%' \
23 < $0 > $1
24 chmod -w $1
25 exit 0
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)
35 * any later version.
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>
56 #include <signal.h>
57 #include <fcntl.h>
58 #ifndef sgi
59 # include <sys/file.h>
60 #endif
61 #if !defined(sun) || defined(SUNOS3)
62 # include <sys/ioctl.h> /* collosions with termios.h */
63 #else
64 # ifndef TIOCEXCL
65 # include <sys/ttold.h> /* needed for TIOCEXCL */
66 # endif
67 #endif
68 #ifdef __hpux
69 # include <sys/modem.h>
70 #endif
72 #ifdef ISC
73 # include <sys/tty.h>
74 # include <sys/sioctl.h>
75 # include <sys/pty.h>
76 #endif
78 #include "config.h"
79 #ifdef SVR4
80 #include <sys/stropts.h> /* for I_POP */
81 #endif
83 #include "screen.h"
84 #include "extern.h"
86 #if !defined(TIOCCONS) && defined(sun) && defined(SVR4)
87 # include <sys/strredir.h>
88 #endif
90 extern struct display *display, *displays;
91 extern int iflag;
92 #if (!defined(TIOCCONS) && defined(SRIOCSREDIR)) || defined(linux)
93 extern struct win *console_window;
94 static void consredir_readev_fn __P((struct event *, char *));
95 #endif
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
109 #endif
110 #if !defined(VSTOP) && defined(_VSTOP)
111 #define VSTOP _VSTOP
112 #endif
114 #ifndef O_NOCTTY
115 # define O_NOCTTY 0
116 #endif
118 #ifndef TTYVMIN
119 # define TTYVMIN 1
120 #endif
121 #ifndef TTYVTIME
122 #define TTYVTIME 0
123 #endif
126 static sigret_t
127 SigAlrmDummy SIGDEFARG
129 debug("SigAlrmDummy()\n");
130 SIGRETURN;
134 * Carefully open a charcter device. Not used to open display ttys.
135 * The second parameter is parsed for a few stty style options.
139 OpenTTY(line, opt)
140 char *line, *opt;
142 int f;
143 struct mode Mode;
144 sigret_t (*sigalrm)__P(SIGPROTOARG);
146 sigalrm = signal(SIGALRM, SigAlrmDummy);
147 alarm(2);
149 /* this open only succeeds, if real uid is allowed */
150 if ((f = secopen(line, O_RDWR | O_NONBLOCK | O_NOCTTY, 0)) == -1)
152 if (errno == EINTR)
153 Msg(0, "Cannot open line '%s' for R/W: open() blocked, aborted.", line);
154 else
155 Msg(errno, "Cannot open line '%s' for R/W", line);
156 alarm(0);
157 signal(SIGALRM, sigalrm);
158 return -1;
160 if (!isatty(f))
162 Msg(0, "'%s' is not a tty", line);
163 alarm(0);
164 signal(SIGALRM, sigalrm);
165 close(f);
166 return -1;
168 #if defined(I_POP) && defined(POP_TTYMODULES)
169 debug("OpenTTY I_POP\n");
170 while (ioctl(f, I_POP, (char *)0) >= 0)
172 #endif
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?
178 #ifdef TIOCEXCL
179 errno = 0;
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
189 if (display)
191 debug1("OpenTTY: using mode of display for %s\n", line);
192 Mode = D_NewMode;
194 else
195 #endif
196 InitTTY(&Mode, W_TYPE_PLAIN);
198 SttyMode(&Mode, opt);
199 #ifdef DEBUG
200 DebugTTY(&Mode);
201 #endif
202 SetTTY(f, &Mode);
204 #if defined(linux) && defined(TIOCMSET)
206 int mcs = 0;
207 ioctl(f, TIOCMGET, &mcs);
208 mcs |= TIOCM_RTS;
209 ioctl(f, TIOCMSET, &mcs);
211 #endif
213 brktty(f);
214 alarm(0);
215 signal(SIGALRM, sigalrm);
216 debug2("'%s' CONNECT fd=%d.\n", line, f);
217 return f;
222 * Tty mode handling
225 void
226 InitTTY(m, ttyflag)
227 struct mode *m;
228 int ttyflag;
230 bzero((char *)m, sizeof(*m));
231 #ifdef POSIX
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;
273 if (!ttyflag)
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');
301 if (ttyflag)
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 */
316 #else /* POSIX */
318 # ifdef TERMIO
319 debug1("InitTTY: nonPOSIX, struct termio a la Motorola SYSV68 (%d)\n", ttyflag);
320 /* struct termio tio
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;
338 #ifdef __bsdi__
339 )-: cannot handle BSDI without POSIX
340 #else
341 IF{B9600} m->tio.c_cflag = B9600;
342 #endif
343 IF{CS8} m->tio.c_cflag |= CS8;
344 IF{CREAD} m->tio.c_cflag |= CREAD;
346 if (!ttyflag)
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;
364 if (ttyflag)
366 m->tio.c_cc[VMIN] = TTYVMIN;
367 m->tio.c_cc[VTIME] = TTYVTIME;
370 # else /* TERMIO */
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');
376 if (!ttyflag)
377 m->m_ttyb.sg_flags = CRMOD | ECHO
378 IF{ANYP} | ANYP
380 else
381 m->m_ttyb.sg_flags = CBREAK
382 IF{ANYP} | ANYP
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;
401 m->m_lmode = 0
402 IF{LDECCTQ} | LDECCTQ
403 IF{LCTLECH} | LCTLECH
404 IF{LPASS8} | LPASS8
405 IF{LCRTKIL} | LCRTKIL
406 IF{LCRTERA} | LCRTERA
407 IF{LCRTBS} | LCRTBS
409 # endif /* TERMIO */
410 #endif /* POSIX */
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;
416 #endif
419 void
420 SetTTY(fd, mp)
421 int fd;
422 struct mode *mp;
424 errno = 0;
425 #ifdef POSIX
426 tcsetattr(fd, TCSADRAIN, &mp->tio);
427 # ifdef HPUX_LTCHARS_HACK
428 ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars);
429 # endif
430 #else
431 # ifdef TERMIO
432 ioctl(fd, TCSETAW, (char *)&mp->tio);
433 # ifdef CYTERMIO
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);
440 # endif
441 # else
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 */
448 # endif
449 #endif
450 #if defined(ENCODINGS) && defined(TIOCKSET)
451 ioctl(fd, TIOCKSETC, &mp->m_jtchars);
452 ioctl(fd, TIOCKSET, &mp->m_knjmode);
453 #endif
454 if (errno)
455 Msg(errno, "SetTTY (fd %d): ioctl failed", fd);
458 void
459 GetTTY(fd, mp)
460 int fd;
461 struct mode *mp;
463 errno = 0;
464 #ifdef POSIX
465 tcgetattr(fd, &mp->tio);
466 # ifdef HPUX_LTCHARS_HACK
467 ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
468 # endif
469 #else
470 # ifdef TERMIO
471 ioctl(fd, TCGETA, (char *)&mp->tio);
472 # ifdef CYTERMIO
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);
479 else
481 mp->m_mapkey = NOMAPKEY;
482 mp->m_mapscreen = NOMAPSCREEN;
483 mp->m_backspace = '\b';
485 # endif
486 # else
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);
492 # endif
493 #endif
494 #if defined(ENCODINGS) && defined(TIOCKSET)
495 ioctl(fd, TIOCKGETC, &mp->m_jtchars);
496 ioctl(fd, TIOCKGET, &mp->m_knjmode);
497 #endif
498 if (errno)
499 Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
503 * needs interrupt = iflag and flow = d->d_flow
505 void
506 SetMode(op, np, flow, interrupt)
507 struct mode *op, *np;
508 int flow, interrupt;
510 *np = *op;
512 ASSERT(display);
513 #if defined(TERMIO) || defined(POSIX)
514 # ifdef CYTERMIO
515 np->m_mapkey = NOMAPKEY;
516 np->m_mapscreen = NOMAPSCREEN;
517 np->tio.c_line = 0;
518 # endif
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)
538 if (interrupt)
539 np->tio.c_lflag |= ISIG;
540 else
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;
555 if (flow == 0)
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 XIF{VERASE} np->tio.c_cc[VERASE] = VDISABLE;
566 XIF{VKILL} np->tio.c_cc[VKILL] = VDISABLE;
567 # ifdef HPUX_LTCHARS_HACK
568 np->m_ltchars.t_suspc = VDISABLE;
569 np->m_ltchars.t_dsuspc = VDISABLE;
570 np->m_ltchars.t_rprntc = VDISABLE;
571 np->m_ltchars.t_flushc = VDISABLE;
572 np->m_ltchars.t_werasc = VDISABLE;
573 np->m_ltchars.t_lnextc = VDISABLE;
574 # else /* HPUX_LTCHARS_HACK */
575 XIF{VDSUSP} np->tio.c_cc[VDSUSP] = VDISABLE;
576 XIF{VREPRINT} np->tio.c_cc[VREPRINT] = VDISABLE;
577 XIF{VWERASE} np->tio.c_cc[VWERASE] = VDISABLE;
578 # endif /* HPUX_LTCHARS_HACK */
579 #else /* TERMIO || POSIX */
580 if (!interrupt || !flow)
581 np->m_tchars.t_intrc = -1;
582 np->m_ttyb.sg_flags &= ~(CRMOD | ECHO);
583 np->m_ttyb.sg_flags |= CBREAK;
584 # if defined(CYRILL) && defined(CSTYLE) && defined(CS_8BITS)
585 np->m_ttyb.sg_flags &= ~CSTYLE;
586 np->m_ttyb.sg_flags |= CS_8BITS;
587 # endif
588 np->m_tchars.t_quitc = -1;
589 if (flow == 0)
591 np->m_tchars.t_startc = -1;
592 np->m_tchars.t_stopc = -1;
594 np->m_ltchars.t_suspc = -1;
595 np->m_ltchars.t_dsuspc = -1;
596 np->m_ltchars.t_flushc = -1;
597 np->m_ltchars.t_lnextc = -1;
598 #endif /* defined(TERMIO) || defined(POSIX) */
601 /* operates on display */
602 void
603 SetFlow(on)
604 int on;
606 ASSERT(display);
607 if (D_flow == on)
608 return;
609 #if defined(TERMIO) || defined(POSIX)
610 if (on)
612 D_NewMode.tio.c_cc[VINTR] = iflag ? D_OldMode.tio.c_cc[VINTR] : VDISABLE;
613 XIF{VSTART} D_NewMode.tio.c_cc[VSTART] = D_OldMode.tio.c_cc[VSTART];
614 XIF{VSTOP} D_NewMode.tio.c_cc[VSTOP] = D_OldMode.tio.c_cc[VSTOP];
615 D_NewMode.tio.c_iflag |= D_OldMode.tio.c_iflag & IXON;
617 else
619 D_NewMode.tio.c_cc[VINTR] = VDISABLE;
620 XIF{VSTART} D_NewMode.tio.c_cc[VSTART] = VDISABLE;
621 XIF{VSTOP} D_NewMode.tio.c_cc[VSTOP] = VDISABLE;
622 D_NewMode.tio.c_iflag &= ~IXON;
624 # ifdef POSIX
625 # ifdef TCOON
626 if (!on)
627 tcflow(D_userfd, TCOON);
628 # endif
629 if (tcsetattr(D_userfd, TCSANOW, &D_NewMode.tio))
630 # else
631 if (ioctl(D_userfd, TCSETAW, (char *)&D_NewMode.tio) != 0)
632 # endif
633 debug1("SetFlow: ioctl errno %d\n", errno);
634 #else /* POSIX || TERMIO */
635 if (on)
637 D_NewMode.m_tchars.t_intrc = iflag ? D_OldMode.m_tchars.t_intrc : -1;
638 D_NewMode.m_tchars.t_startc = D_OldMode.m_tchars.t_startc;
639 D_NewMode.m_tchars.t_stopc = D_OldMode.m_tchars.t_stopc;
641 else
643 D_NewMode.m_tchars.t_intrc = -1;
644 D_NewMode.m_tchars.t_startc = -1;
645 D_NewMode.m_tchars.t_stopc = -1;
647 if (ioctl(D_userfd, TIOCSETC, (char *)&D_NewMode.m_tchars) != 0)
648 debug1("SetFlow: ioctl errno %d\n", errno);
649 #endif /* POSIX || TERMIO */
650 D_flow = on;
653 /* parse commands from opt and modify m */
655 SttyMode(m, opt)
656 struct mode *m;
657 char *opt;
659 static const char sep[] = " \t:;,";
661 if (!opt)
662 return 0;
664 while (*opt)
666 while (index(sep, *opt)) opt++;
667 if (*opt >= '0' && *opt <= '9')
669 if (SetBaud(m, atoi(opt), atoi(opt)))
670 return -1;
672 else if (!strncmp("cs7", opt, 3))
674 #if defined(POSIX) || defined(TERMIO)
675 m->tio.c_cflag &= ~CSIZE;
676 m->tio.c_cflag |= CS7;
677 #else
678 m->m_lmode &= ~LPASS8;
679 #endif
681 else if (!strncmp("cs8", opt, 3))
683 #if defined(POSIX) || defined(TERMIO)
684 m->tio.c_cflag &= ~CSIZE;
685 m->tio.c_cflag |= CS8;
686 #else
687 m->m_lmode |= LPASS8;
688 #endif
690 else if (!strncmp("istrip", opt, 6))
692 #if defined(POSIX) || defined(TERMIO)
693 m->tio.c_iflag |= ISTRIP;
694 #else
695 m->m_lmode &= ~LPASS8;
696 #endif
698 else if (!strncmp("-istrip", opt, 7))
700 #if defined(POSIX) || defined(TERMIO)
701 m->tio.c_iflag &= ~ISTRIP;
702 #else
703 m->m_lmode |= LPASS8;
704 #endif
706 else if (!strncmp("ixon", opt, 4))
708 #if defined(POSIX) || defined(TERMIO)
709 m->tio.c_iflag |= IXON;
710 #else
711 debug("SttyMode: no ixon in old bsd land.\n");
712 #endif
714 else if (!strncmp("-ixon", opt, 5))
716 #if defined(POSIX) || defined(TERMIO)
717 m->tio.c_iflag &= ~IXON;
718 #else
719 debug("SttyMode: no -ixon in old bsd land.\n");
720 #endif
722 else if (!strncmp("ixoff", opt, 5))
724 #if defined(POSIX) || defined(TERMIO)
725 m->tio.c_iflag |= IXOFF;
726 #else
727 m->m_ttyb.sg_flags |= TANDEM;
728 #endif
730 else if (!strncmp("-ixoff", opt, 6))
732 #if defined(POSIX) || defined(TERMIO)
733 m->tio.c_iflag &= ~IXOFF;
734 #else
735 m->m_ttyb.sg_flags &= ~TANDEM;
736 #endif
738 else if (!strncmp("crtscts", opt, 7))
740 #if (defined(POSIX) || defined(TERMIO)) && defined(CRTSCTS)
741 m->tio.c_cflag |= CRTSCTS;
742 #endif
744 else if (!strncmp("-crtscts", opt, 8))
746 #if (defined(POSIX) || defined(TERMIO)) && defined(CRTSCTS)
747 m->tio.c_cflag &= ~CRTSCTS;
748 #endif
750 else
751 return -1;
752 while (*opt && !index(sep, *opt)) opt++;
754 return 0;
758 * Job control handling
760 * Somehow the ultrix session handling is broken, so use
761 * the bsdish variant.
764 /*ARGSUSED*/
765 void
766 brktty(fd)
767 int fd;
769 #if defined(POSIX) && !defined(ultrix)
770 if (separate_sids)
771 setsid(); /* will break terminal affiliation */
772 /* GNU added for Hurd systems 2001-10-10 */
773 # if defined(BSD) && defined(TIOCSCTTY) && !defined(__GNU__)
774 ioctl(fd, TIOCSCTTY, (char *)0);
775 # endif /* BSD && TIOCSCTTY */
776 #else /* POSIX */
777 # ifdef SYSV
778 if (separate_sids)
779 setpgrp(); /* will break terminal affiliation */
780 # else /* SYSV */
781 # ifdef BSDJOBS
782 int devtty;
784 if ((devtty = open("/dev/tty", O_RDWR | O_NONBLOCK)) >= 0)
786 if (ioctl(devtty, TIOCNOTTY, (char *)0))
787 debug2("brktty: ioctl(devtty=%d, TIOCNOTTY, 0) = %d\n", devtty, errno);
788 close(devtty);
790 # endif /* BSDJOBS */
791 # endif /* SYSV */
792 #endif /* POSIX */
796 fgtty(fd)
797 int fd;
799 #ifdef BSDJOBS
800 int mypid;
802 mypid = getpid();
804 /* The next lines should be obsolete. Can anybody check if they
805 * are really needed on the BSD platforms?
807 * this is to avoid the message:
808 * fgtty: Not a typewriter (25)
810 # if defined(__osf__) || (BSD >= 199103) || defined(ISC)
811 if (separate_sids)
812 setsid(); /* should be already done */
813 # ifdef TIOCSCTTY
814 ioctl(fd, TIOCSCTTY, (char *)0);
815 # endif
816 # endif
818 # ifdef POSIX
819 if (separate_sids)
820 if (tcsetpgrp(fd, mypid))
822 debug1("fgtty: tcsetpgrp: %d\n", errno);
823 return -1;
825 # else /* POSIX */
826 if (ioctl(fd, TIOCSPGRP, (char *)&mypid) != 0)
827 debug1("fgtty: TIOSETPGRP: %d\n", errno);
828 # ifndef SYSV /* Already done in brktty():setpgrp() */
829 if (separate_sids)
830 if (setpgrp(fd, mypid))
831 debug1("fgtty: setpgrp: %d\n", errno);
832 # endif
833 # endif /* POSIX */
834 #endif /* BSDJOBS */
835 return 0;
839 * The alm boards on our sparc center 1000 have a lousy driver.
840 * We cannot generate long breaks unless we use the most ugly form
841 * of ioctls. jw.
843 #ifdef POSIX
844 int breaktype = 2;
845 #else /* POSIX */
846 # ifdef TCSBRK
847 int breaktype = 1;
848 # else
849 int breaktype = 0;
850 # endif
851 #endif /* POSIX */
853 #if defined(sun) && !defined(SVR4)
854 # define HAVE_SUPER_TCSENDBREAK
855 #endif
858 * type:
859 * 0: TIOCSBRK / TIOCCBRK
860 * 1: TCSBRK
861 * 2: tcsendbreak()
862 * n: approximate duration in 1/4 seconds.
864 static void
865 DoSendBreak(fd, n, type)
866 int fd, n, type;
868 switch (type)
870 case 2: /* tcsendbreak() =============================== */
871 #ifdef POSIX
872 # ifdef HAVE_SUPER_TCSENDBREAK
873 /* There is one rare case that I have tested, where tcsendbreak works
874 * really great: this was an alm driver that came with SunOS 4.1.3
875 * If you have this one, define the above symbol.
876 * here we can use the second parameter to specify the duration.
878 debug2("tcsendbreak(fd=%d, %d)\n", fd, n);
879 if (tcsendbreak(fd, n) < 0)
880 Msg(errno, "cannot send BREAK (tcsendbreak)");
881 # else
883 * here we hope, that multiple calls to tcsendbreak() can
884 * be concatenated to form a long break, as we do not know
885 * what exact interpretation the second parameter has:
887 * - sunos 4: duration in quarter seconds
888 * - sunos 5: 0 a short break, nonzero a tcdrain()
889 * - hpux, irix: ignored
890 * - mot88: duration in milliseconds
891 * - aix: duration in milliseconds, but 0 is 25 milliseconds.
893 debug2("%d * tcsendbreak(fd=%d, 0)\n", n, fd);
895 int i;
897 if (!n)
898 n++;
899 for (i = 0; i < n; i++)
900 if (tcsendbreak(fd, 0) < 0)
902 Msg(errno, "cannot send BREAK (tcsendbreak SVR4)");
903 return;
906 # endif
907 #else /* POSIX */
908 Msg(0, "tcsendbreak() not available, change breaktype");
909 #endif /* POSIX */
910 break;
912 case 1: /* TCSBRK ======================================= */
913 #ifdef TCSBRK
914 if (!n)
915 n++;
917 * Here too, we assume that short breaks can be concatenated to
918 * perform long breaks. But for SOLARIS, this is not true, of course.
920 debug2("%d * TCSBRK fd=%d\n", n, fd);
922 int i;
924 for (i = 0; i < n; i++)
925 if (ioctl(fd, TCSBRK, (char *)0) < 0)
927 Msg(errno, "Cannot send BREAK (TCSBRK)");
928 return;
931 #else /* TCSBRK */
932 Msg(0, "TCSBRK not available, change breaktype");
933 #endif /* TCSBRK */
934 break;
936 case 0: /* TIOCSBRK / TIOCCBRK ========================== */
937 #if defined(TIOCSBRK) && defined(TIOCCBRK)
939 * This is very rude. Screen actively celebrates the break.
940 * But it may be the only save way to issue long breaks.
942 debug("TIOCSBRK TIOCCBRK\n");
943 if (ioctl(fd, TIOCSBRK, (char *)0) < 0)
945 Msg(errno, "Can't send BREAK (TIOCSBRK)");
946 return;
948 sleep1000(n ? n * 250 : 250);
949 if (ioctl(fd, TIOCCBRK, (char *)0) < 0)
951 Msg(errno, "BREAK stuck!!! -- HELP! (TIOCCBRK)");
952 return;
954 #else /* TIOCSBRK && TIOCCBRK */
955 Msg(0, "TIOCSBRK/CBRK not available, change breaktype");
956 #endif /* TIOCSBRK && TIOCCBRK */
957 break;
959 default: /* unknown ========================== */
960 Msg(0, "Internal SendBreak error: method %d unknown", type);
965 * Send a break for n * 0.25 seconds. Tty must be PLAIN.
966 * The longest possible break allowed here is 15 seconds.
969 void
970 SendBreak(wp, n, closeopen)
971 struct win *wp;
972 int n, closeopen;
974 sigret_t (*sigalrm)__P(SIGPROTOARG);
976 #ifdef BUILTIN_TELNET
977 if (wp->w_type == W_TYPE_TELNET)
979 TelBreak(wp);
980 return;
982 #endif
983 if (wp->w_type != W_TYPE_PLAIN)
984 return;
986 debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
988 #ifdef POSIX
989 (void) tcflush(wp->w_ptyfd, TCIOFLUSH);
990 #else
991 # ifdef TIOCFLUSH
992 (void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
993 # endif /* TIOCFLUSH */
994 #endif /* POSIX */
996 if (closeopen)
998 close(wp->w_ptyfd);
999 sleep1000(n ? n * 250 : 250);
1000 if ((wp->w_ptyfd = OpenTTY(wp->w_tty, wp->w_cmdargs[1])) < 1)
1002 Msg(0, "Ouch, cannot reopen line %s, please try harder", wp->w_tty);
1003 return;
1005 (void) fcntl(wp->w_ptyfd, F_SETFL, FNBLOCK);
1007 else
1009 sigalrm = signal(SIGALRM, SigAlrmDummy);
1010 alarm(15);
1012 DoSendBreak(wp->w_ptyfd, n, breaktype);
1014 alarm(0);
1015 signal(SIGALRM, sigalrm);
1017 debug(" broken.\n");
1021 * Console grabbing
1024 #if (!defined(TIOCCONS) && defined(SRIOCSREDIR)) || defined(linux)
1026 static struct event consredir_ev;
1027 static int consredirfd[2] = {-1, -1};
1029 static void
1030 consredir_readev_fn(ev, data)
1031 struct event *ev;
1032 char *data;
1034 char *p, *n, buf[256];
1035 int l;
1037 if (!console_window || (l = read(consredirfd[0], buf, sizeof(buf))) <= 0)
1039 close(consredirfd[0]);
1040 close(consredirfd[1]);
1041 consredirfd[0] = consredirfd[1] = -1;
1042 evdeq(ev);
1043 return;
1045 for (p = n = buf; l > 0; n++, l--)
1046 if (*n == '\n')
1048 if (n > p)
1049 WriteString(console_window, p, n - p);
1050 WriteString(console_window, "\r\n", 2);
1051 p = n + 1;
1053 if (n > p)
1054 WriteString(console_window, p, n - p);
1057 #endif
1059 /*ARGSUSED*/
1061 TtyGrabConsole(fd, on, rc_name)
1062 int fd, on;
1063 char *rc_name;
1065 #if defined(TIOCCONS) && !defined(linux)
1066 struct display *d;
1067 int ret = 0;
1068 int sfd = -1;
1070 if (on < 0)
1071 return 0; /* pty close will ungrab */
1072 if (on)
1074 if (displays == 0)
1076 Msg(0, "I need a display");
1077 return -1;
1079 for (d = displays; d; d = d->d_next)
1080 if (strcmp(d->d_usertty, "/dev/console") == 0)
1081 break;
1082 if (d)
1084 Msg(0, "too dangerous - screen is running on /dev/console");
1085 return -1;
1089 if (!on)
1091 char *slave;
1092 if ((fd = OpenPTY(&slave)) < 0)
1094 Msg(errno, "%s: could not open detach pty master", rc_name);
1095 return -1;
1097 if ((sfd = open(slave, O_RDWR | O_NOCTTY)) < 0)
1099 Msg(errno, "%s: could not open detach pty slave", rc_name);
1100 close(fd);
1101 return -1;
1104 if (UserContext() == 1)
1105 UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
1106 ret = UserStatus();
1107 if (ret)
1108 Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
1109 if (!on)
1111 close(sfd);
1112 close(fd);
1114 return ret;
1116 #else
1117 # if defined(SRIOCSREDIR) || defined(linux)
1118 struct display *d;
1119 # ifdef SRIOCSREDIR
1120 int cfd;
1121 # else
1122 struct mode new1, new2;
1123 char *slave;
1124 # endif
1126 if (on > 0)
1128 if (displays == 0)
1130 Msg(0, "I need a display");
1131 return -1;
1133 for (d = displays; d; d = d->d_next)
1134 if (strcmp(d->d_usertty, "/dev/console") == 0)
1135 break;
1136 if (d)
1138 Msg(0, "too dangerous - screen is running on /dev/console");
1139 return -1;
1142 if (consredirfd[0] >= 0)
1144 evdeq(&consredir_ev);
1145 close(consredirfd[0]);
1146 close(consredirfd[1]);
1147 consredirfd[0] = consredirfd[1] = -1;
1149 if (on <= 0)
1150 return 0;
1151 # ifdef SRIOCSREDIR
1152 if ((cfd = secopen("/dev/console", O_RDWR|O_NOCTTY, 0)) == -1)
1154 Msg(errno, "/dev/console");
1155 return -1;
1157 if (pipe(consredirfd))
1159 Msg(errno, "pipe");
1160 close(cfd);
1161 consredirfd[0] = consredirfd[1] = -1;
1162 return -1;
1164 if (ioctl(cfd, SRIOCSREDIR, consredirfd[1]))
1166 Msg(errno, "SRIOCSREDIR ioctl");
1167 close(cfd);
1168 close(consredirfd[0]);
1169 close(consredirfd[1]);
1170 consredirfd[0] = consredirfd[1] = -1;
1171 return -1;
1173 close(cfd);
1174 # else
1175 /* special linux workaround for a too restrictive kernel */
1176 if ((consredirfd[0] = OpenPTY(&slave)) < 0)
1178 Msg(errno, "%s: could not open detach pty master", rc_name);
1179 return -1;
1181 if ((consredirfd[1] = open(slave, O_RDWR | O_NOCTTY)) < 0)
1183 Msg(errno, "%s: could not open detach pty slave", rc_name);
1184 close(consredirfd[0]);
1185 return -1;
1187 InitTTY(&new1, 0);
1188 SetMode(&new1, &new2, 0, 0);
1189 SetTTY(consredirfd[1], &new2);
1190 if (UserContext() == 1)
1191 UserReturn(ioctl(consredirfd[1], TIOCCONS, (char *)&on));
1192 if (UserStatus())
1194 Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
1195 close(consredirfd[0]);
1196 close(consredirfd[1]);
1197 return -1;
1199 # endif
1200 consredir_ev.fd = consredirfd[0];
1201 consredir_ev.type = EV_READ;
1202 consredir_ev.handler = consredir_readev_fn;
1203 evenq(&consredir_ev);
1204 return 0;
1205 # else
1206 if (on > 0)
1207 Msg(0, "%s: don't know how to grab the console", rc_name);
1208 return -1;
1209 # endif
1210 #endif
1214 * Read modem control lines of a physical tty and write them to buf
1215 * in a readable format.
1216 * Will not write more than 256 characters to buf.
1217 * Returns buf;
1219 char *
1220 TtyGetModemStatus(fd, buf)
1221 int fd;
1222 char *buf;
1224 char *p = buf;
1225 #ifdef TIOCGSOFTCAR
1226 unsigned int softcar;
1227 #endif
1228 #if defined(TIOCMGET) || defined(TIOCMODG)
1229 unsigned int mflags;
1230 #else
1231 # ifdef MCGETA
1232 /* this is yet another interface, found on hpux. grrr */
1233 mflag mflags;
1234 IF{MDTR}# define TIOCM_DTR MDTR
1235 IF{MRTS}# define TIOCM_RTS MRTS
1236 IF{MDSR}# define TIOCM_DSR MDSR
1237 IF{MDCD}# define TIOCM_CAR MDCD
1238 IF{MRI}# define TIOCM_RNG MRI
1239 IF{MCTS}# define TIOCM_CTS MCTS
1240 # endif
1241 #endif
1242 #if defined(CLOCAL) || defined(CRTSCTS)
1243 struct mode mtio; /* screen.h */
1244 #endif
1245 #if defined(CRTSCTS) || defined(TIOCM_CTS)
1246 int rtscts;
1247 #endif
1248 int clocal;
1250 #if defined(CLOCAL) || defined(CRTSCTS)
1251 GetTTY(fd, &mtio);
1252 #endif
1253 clocal = 0;
1254 #ifdef CLOCAL
1255 if (mtio.tio.c_cflag & CLOCAL)
1257 clocal = 1;
1258 *p++ = '{';
1260 #endif
1262 #ifdef TIOCM_CTS
1263 # ifdef CRTSCTS
1264 if (!(mtio.tio.c_cflag & CRTSCTS))
1265 rtscts = 0;
1266 else
1267 # endif /* CRTSCTS */
1268 rtscts = 1;
1269 #endif /* TIOCM_CTS */
1271 #ifdef TIOCGSOFTCAR
1272 if (ioctl(fd, TIOCGSOFTCAR, (char *)&softcar) < 0)
1273 softcar = 0;
1274 #endif
1276 #if defined(TIOCMGET) || defined(TIOCMODG) || defined(MCGETA)
1277 # ifdef TIOCMGET
1278 if (ioctl(fd, TIOCMGET, (char *)&mflags) < 0)
1279 # else
1280 # ifdef TIOCMODG
1281 if (ioctl(fd, TIOCMODG, (char *)&mflags) < 0)
1282 # else
1283 if (ioctl(fd, MCGETA, &mflags) < 0)
1284 # endif
1285 # endif
1287 #ifdef TIOCGSOFTCAR
1288 sprintf(p, "NO-TTY? %s", softcar ? "(CD)" : "CD");
1289 #else
1290 sprintf(p, "NO-TTY?");
1291 #endif
1292 p += strlen(p);
1294 else
1296 char *s;
1297 # ifdef FANCY_MODEM
1298 # ifdef TIOCM_LE
1299 if (!(mflags & TIOCM_LE))
1300 for (s = "!LE "; *s; *p++ = *s++);
1301 # endif
1302 # endif /* FANCY_MODEM */
1304 # ifdef TIOCM_RTS
1305 s = "!RTS "; if (mflags & TIOCM_RTS) s++;
1306 while (*s) *p++ = *s++;
1307 # endif
1308 # ifdef TIOCM_CTS
1309 s = "!CTS ";
1310 if (!rtscts)
1312 *p++ = '(';
1313 s = "!CTS) ";
1315 if (mflags & TIOCM_CTS) s++;
1316 while (*s) *p++ = *s++;
1317 # endif
1319 # ifdef TIOCM_DTR
1320 s = "!DTR "; if (mflags & TIOCM_DTR) s++;
1321 while (*s) *p++ = *s++;
1322 # endif
1323 # ifdef TIOCM_DSR
1324 s = "!DSR "; if (mflags & TIOCM_DSR) s++;
1325 while (*s) *p++ = *s++;
1326 # endif
1327 # if defined(TIOCM_CD) || defined(TIOCM_CAR)
1328 s = "!CD ";
1329 # ifdef TIOCGSOFTCAR
1330 if (softcar)
1332 *p++ = '(';
1333 s = "!CD) ";
1335 # endif
1336 # ifdef TIOCM_CD
1337 if (mflags & TIOCM_CD) s++;
1338 # else
1339 if (mflags & TIOCM_CAR) s++;
1340 # endif
1341 while (*s) *p++ = *s++;
1342 # endif
1343 # if defined(TIOCM_RI) || defined(TIOCM_RNG)
1344 # ifdef TIOCM_RI
1345 if (mflags & TIOCM_RI)
1346 # else
1347 if (mflags & TIOCM_RNG)
1348 # endif
1349 for (s = "RI "; *s; *p++ = *s++);
1350 # endif
1351 # ifdef FANCY_MODEM
1352 # ifdef TIOCM_ST
1353 s = "!ST "; if (mflags & TIOCM_ST) s++;
1354 while (*s) *p++ = *s++;
1355 # endif
1356 # ifdef TIOCM_SR
1357 s = "!SR "; if (mflags & TIOCM_SR) s++;
1358 while (*s) *p++ = *s++;
1359 # endif
1360 # endif /* FANCY_MODEM */
1361 if (p > buf && p[-1] == ' ')
1362 p--;
1363 *p = '\0';
1365 #else
1366 # ifdef TIOCGSOFTCAR
1367 sprintf(p, " %s", softcar ? "(CD)", "CD");
1368 p += strlen(p);
1369 # endif
1370 #endif
1371 if (clocal)
1372 *p++ = '}';
1373 *p = '\0';
1374 return buf;
1378 * Old bsd-ish machines may not have any of the baudrate B... symbols.
1379 * We hope to detect them here, so that the btable[] below always has
1380 * many entries.
1382 #ifndef POSIX
1383 # ifndef TERMIO
1384 # if !defined(B9600) && !defined(B2400) && !defined(B1200) && !defined(B300)
1385 IFN{B0}#define B0 0
1386 IFN{B50}#define B50 1
1387 IFN{B75}#define B75 2
1388 IFN{B110}#define B110 3
1389 IFN{B134}#define B134 4
1390 IFN{B150}#define B150 5
1391 IFN{B200}#define B200 6
1392 IFN{B300}#define B300 7
1393 IFN{B600}#define B600 8
1394 IFN{B1200}#define B1200 9
1395 IFN{B1800}#define B1800 10
1396 IFN{B2400}#define B2400 11
1397 IFN{B4800}#define B4800 12
1398 IFN{B9600}#define B9600 13
1399 IFN{EXTA}#define EXTA 14
1400 IFN{EXTB}#define EXTB 15
1401 # endif
1402 # endif
1403 #endif
1406 * On hpux, idx and sym will be different.
1407 * Rumor has it that, we need idx in D_dospeed to make tputs
1408 * padding correct.
1409 * Frequently used entries come first.
1411 static struct baud_values btable[] =
1413 IF{B9600} { 13, 9600, B9600 },
1414 IF{B19200} { 14, 19200, B19200 },
1415 IF{EXTA} { 14, 19200, EXTA },
1416 IF{B38400} { 15, 38400, B38400 },
1417 IF{EXTB} { 15, 38400, EXTB },
1418 IF{B57600} { 16, 57600, B57600 },
1419 IF{B115200} { 17, 115200, B115200 },
1420 IF{B230400} { 18, 230400, B230400 },
1421 IF{B460800} { 19, 460800, B460800 },
1422 IF{B7200} { 13, 7200, B7200 },
1423 IF{B4800} { 12, 4800, B4800 },
1424 IF{B3600} { 12, 3600, B3600 },
1425 IF{B2400} { 11, 2400, B2400 },
1426 IF{B1800} { 10, 1800, B1800 },
1427 IF{B1200} { 9, 1200, B1200 },
1428 IF{B900} { 9, 900, B900 },
1429 IF{B600} { 8, 600, B600 },
1430 IF{B300} { 7, 300, B300 },
1431 IF{B200} { 6, 200, B200 },
1432 IF{B150} { 5, 150, B150 },
1433 IF{B134} { 4, 134, B134 },
1434 IF{B110} { 3, 110, B110 },
1435 IF{B75} { 2, 75, B75 },
1436 IF{B50} { 1, 50, B50 },
1437 IF{B0} { 0, 0, B0 },
1438 { -1, -1, -1 }
1442 * baud may either be a bits-per-second value or a symbolic
1443 * value as returned by cfget?speed()
1445 struct baud_values *
1446 lookup_baud(baud)
1447 int baud;
1449 struct baud_values *p;
1451 for (p = btable; p->idx >= 0; p++)
1452 if (baud == p->bps || baud == p->sym)
1453 return p;
1454 return NULL;
1458 * change the baud rate in a mode structure.
1459 * ibaud and obaud are given in bit/second, or at your option as
1460 * termio B... symbols as defined in e.g. suns sys/ttydev.h
1461 * -1 means don't change.
1464 SetBaud(m, ibaud, obaud)
1465 struct mode *m;
1466 int ibaud, obaud;
1468 struct baud_values *ip, *op;
1470 if ((!(ip = lookup_baud(ibaud)) && ibaud != -1) ||
1471 (!(op = lookup_baud(obaud)) && obaud != -1))
1472 return -1;
1474 #ifdef POSIX
1475 if (ip) cfsetispeed(&m->tio, ip->sym);
1476 if (op) cfsetospeed(&m->tio, op->sym);
1477 #else /* POSIX */
1478 # ifdef TERMIO
1479 if (ip)
1481 # ifdef IBSHIFT
1482 m->tio.c_cflag &= ~(CBAUD << IBSHIFT);
1483 m->tio.c_cflag |= (ip->sym & CBAUD) << IBSHIFT;
1484 # else /* IBSHIFT */
1485 if (ibaud != obaud)
1486 return -1;
1487 # endif /* IBSHIFT */
1489 if (op)
1491 m->tio.c_cflag &= ~CBAUD;
1492 m->tio.c_cflag |= op->sym & CBAUD;
1494 # else /* TERMIO */
1495 if (ip) m->m_ttyb.sg_ispeed = ip->idx;
1496 if (op) m->m_ttyb.sg_ospeed = op->idx;
1497 # endif /* TERMIO */
1498 #endif /* POSIX */
1499 return 0;
1503 * Write out the mode struct in a readable form
1506 #ifdef DEBUG
1507 void
1508 DebugTTY(m)
1509 struct mode *m;
1511 int i;
1513 #ifdef POSIX
1514 debug("struct termios tio:\n");
1515 debug1("c_iflag = %#x\n", (unsigned int)m->tio.c_iflag);
1516 debug1("c_oflag = %#x\n", (unsigned int)m->tio.c_oflag);
1517 debug1("c_cflag = %#x\n", (unsigned int)m->tio.c_cflag);
1518 debug1("c_lflag = %#x\n", (unsigned int)m->tio.c_lflag);
1519 debug1("cfgetospeed() = %d\n", (int)cfgetospeed(&m->tio));
1520 debug1("cfgetispeed() = %d\n", (int)cfgetispeed(&m->tio));
1521 for (i = 0; i < sizeof(m->tio.c_cc)/sizeof(*m->tio.c_cc); i++)
1523 debug2("c_cc[%d] = %#x\n", i, m->tio.c_cc[i]);
1525 # ifdef HPUX_LTCHARS_HACK
1526 debug1("suspc = %#02x\n", m->m_ltchars.t_suspc);
1527 debug1("dsuspc = %#02x\n", m->m_ltchars.t_dsuspc);
1528 debug1("rprntc = %#02x\n", m->m_ltchars.t_rprntc);
1529 debug1("flushc = %#02x\n", m->m_ltchars.t_flushc);
1530 debug1("werasc = %#02x\n", m->m_ltchars.t_werasc);
1531 debug1("lnextc = %#02x\n", m->m_ltchars.t_lnextc);
1532 # endif /* HPUX_LTCHARS_HACK */
1533 #else /* POSIX */
1534 # ifdef TERMIO
1535 debug("struct termio tio:\n");
1536 debug1("c_iflag = %04o\n", m->tio.c_iflag);
1537 debug1("c_oflag = %04o\n", m->tio.c_oflag);
1538 debug1("c_cflag = %04o\n", m->tio.c_cflag);
1539 debug1("c_lflag = %04o\n", m->tio.c_lflag);
1540 for (i = 0; i < sizeof(m->tio.c_cc)/sizeof(*m->tio.c_cc); i++)
1542 debug2("c_cc[%d] = %04o\n", i, m->tio.c_cc[i]);
1544 # else /* TERMIO */
1545 debug1("sg_ispeed = %d\n", m->m_ttyb.sg_ispeed);
1546 debug1("sg_ospeed = %d\n", m->m_ttyb.sg_ospeed);
1547 debug1("sg_erase = %#02x\n", m->m_ttyb.sg_erase);
1548 debug1("sg_kill = %#02x\n", m->m_ttyb.sg_kill);
1549 debug1("sg_flags = %#04x\n", (unsigned short)m->m_ttyb.sg_flags);
1550 debug1("intrc = %#02x\n", m->m_tchars.t_intrc);
1551 debug1("quitc = %#02x\n", m->m_tchars.t_quitc);
1552 debug1("startc = %#02x\n", m->m_tchars.t_startc);
1553 debug1("stopc = %#02x\n", m->m_tchars.t_stopc);
1554 debug1("eofc = %#02x\n", m->m_tchars.t_eofc);
1555 debug1("brkc = %#02x\n", m->m_tchars.t_brkc);
1556 debug1("suspc = %#02x\n", m->m_ltchars.t_suspc);
1557 debug1("dsuspc = %#02x\n", m->m_ltchars.t_dsuspc);
1558 debug1("rprntc = %#02x\n", m->m_ltchars.t_rprntc);
1559 debug1("flushc = %#02x\n", m->m_ltchars.t_flushc);
1560 debug1("werasc = %#02x\n", m->m_ltchars.t_werasc);
1561 debug1("lnextc = %#02x\n", m->m_ltchars.t_lnextc);
1562 debug1("ldisc = %d\n", m->m_ldisc);
1563 debug1("lmode = %#x\n", m->m_lmode);
1564 # endif /* TERMIO */
1565 #endif /* POSIX */
1567 #endif /* DEBUG */