Remove screen.info from tracking.
[screen-lua.git] / src / tty.sh
blob374bb979bfdc66421d339bacfb7109dc5c4df646
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 HAVE_STROPTS_H
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 /* 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;
589 # endif
590 np->m_tchars.t_quitc = -1;
591 if (flow == 0)
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 */
604 void
605 SetFlow(on)
606 int on;
608 ASSERT(display);
609 if (D_flow == on)
610 return;
611 #if defined(TERMIO) || defined(POSIX)
612 if (on)
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;
619 else
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;
626 # ifdef POSIX
627 # ifdef TCOON
628 if (!on)
629 tcflow(D_userfd, TCOON);
630 # endif
631 if (tcsetattr(D_userfd, TCSANOW, &D_NewMode.tio))
632 # else
633 if (ioctl(D_userfd, TCSETAW, (char *)&D_NewMode.tio) != 0)
634 # endif
635 debug1("SetFlow: ioctl errno %d\n", errno);
636 #else /* POSIX || TERMIO */
637 if (on)
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;
643 else
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 */
652 D_flow = on;
655 /* parse commands from opt and modify m */
657 SttyMode(m, opt)
658 struct mode *m;
659 char *opt;
661 static const char sep[] = " \t:;,";
663 if (!opt)
664 return 0;
666 while (*opt)
668 while (index(sep, *opt)) opt++;
669 if (*opt >= '0' && *opt <= '9')
671 if (SetBaud(m, atoi(opt), atoi(opt)))
672 return -1;
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;
679 #else
680 m->m_lmode &= ~LPASS8;
681 #endif
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;
688 #else
689 m->m_lmode |= LPASS8;
690 #endif
692 else if (!strncmp("istrip", opt, 6))
694 #if defined(POSIX) || defined(TERMIO)
695 m->tio.c_iflag |= ISTRIP;
696 #else
697 m->m_lmode &= ~LPASS8;
698 #endif
700 else if (!strncmp("-istrip", opt, 7))
702 #if defined(POSIX) || defined(TERMIO)
703 m->tio.c_iflag &= ~ISTRIP;
704 #else
705 m->m_lmode |= LPASS8;
706 #endif
708 else if (!strncmp("ixon", opt, 4))
710 #if defined(POSIX) || defined(TERMIO)
711 m->tio.c_iflag |= IXON;
712 #else
713 debug("SttyMode: no ixon in old bsd land.\n");
714 #endif
716 else if (!strncmp("-ixon", opt, 5))
718 #if defined(POSIX) || defined(TERMIO)
719 m->tio.c_iflag &= ~IXON;
720 #else
721 debug("SttyMode: no -ixon in old bsd land.\n");
722 #endif
724 else if (!strncmp("ixoff", opt, 5))
726 #if defined(POSIX) || defined(TERMIO)
727 m->tio.c_iflag |= IXOFF;
728 #else
729 m->m_ttyb.sg_flags |= TANDEM;
730 #endif
732 else if (!strncmp("-ixoff", opt, 6))
734 #if defined(POSIX) || defined(TERMIO)
735 m->tio.c_iflag &= ~IXOFF;
736 #else
737 m->m_ttyb.sg_flags &= ~TANDEM;
738 #endif
740 else if (!strncmp("crtscts", opt, 7))
742 #if (defined(POSIX) || defined(TERMIO)) && defined(CRTSCTS)
743 m->tio.c_cflag |= CRTSCTS;
744 #endif
746 else if (!strncmp("-crtscts", opt, 8))
748 #if (defined(POSIX) || defined(TERMIO)) && defined(CRTSCTS)
749 m->tio.c_cflag &= ~CRTSCTS;
750 #endif
752 else
753 return -1;
754 while (*opt && !index(sep, *opt)) opt++;
756 return 0;
760 * Job control handling
762 * Somehow the ultrix session handling is broken, so use
763 * the bsdish variant.
766 /*ARGSUSED*/
767 void
768 brktty(fd)
769 int fd;
771 #if defined(POSIX) && !defined(ultrix)
772 if (separate_sids)
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 */
778 #else /* POSIX */
779 # ifdef SYSV
780 if (separate_sids)
781 setpgrp(); /* will break terminal affiliation */
782 # else /* SYSV */
783 # ifdef BSDJOBS
784 int devtty;
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);
790 close(devtty);
792 # endif /* BSDJOBS */
793 # endif /* SYSV */
794 #endif /* POSIX */
798 fgtty(fd)
799 int fd;
801 #ifdef BSDJOBS
802 int mypid;
804 mypid = getpid();
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)
813 if (separate_sids)
814 setsid(); /* should be already done */
815 # ifdef TIOCSCTTY
816 ioctl(fd, TIOCSCTTY, (char *)0);
817 # endif
818 # endif
820 # ifdef POSIX
821 if (separate_sids)
822 if (tcsetpgrp(fd, mypid))
824 debug1("fgtty: tcsetpgrp: %d\n", errno);
825 return -1;
827 # else /* POSIX */
828 if (ioctl(fd, TIOCSPGRP, (char *)&mypid) != 0)
829 debug1("fgtty: TIOSETPGRP: %d\n", errno);
830 # ifndef SYSV /* Already done in brktty():setpgrp() */
831 if (separate_sids)
832 if (setpgrp(fd, mypid))
833 debug1("fgtty: setpgrp: %d\n", errno);
834 # endif
835 # endif /* POSIX */
836 #endif /* BSDJOBS */
837 return 0;
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
843 * of ioctls. jw.
845 #ifdef POSIX
846 int breaktype = 2;
847 #else /* POSIX */
848 # ifdef TCSBRK
849 int breaktype = 1;
850 # else
851 int breaktype = 0;
852 # endif
853 #endif /* POSIX */
855 #if defined(sun) && !defined(SVR4)
856 # define HAVE_SUPER_TCSENDBREAK
857 #endif
860 * type:
861 * 0: TIOCSBRK / TIOCCBRK
862 * 1: TCSBRK
863 * 2: tcsendbreak()
864 * n: approximate duration in 1/4 seconds.
866 static void
867 DoSendBreak(fd, n, type)
868 int fd, n, type;
870 switch (type)
872 case 2: /* tcsendbreak() =============================== */
873 #ifdef POSIX
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)");
883 # else
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);
897 int i;
899 if (!n)
900 n++;
901 for (i = 0; i < n; i++)
902 if (tcsendbreak(fd, 0) < 0)
904 Msg(errno, "cannot send BREAK (tcsendbreak SVR4)");
905 return;
908 # endif
909 #else /* POSIX */
910 Msg(0, "tcsendbreak() not available, change breaktype");
911 #endif /* POSIX */
912 break;
914 case 1: /* TCSBRK ======================================= */
915 #ifdef TCSBRK
916 if (!n)
917 n++;
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);
924 int i;
926 for (i = 0; i < n; i++)
927 if (ioctl(fd, TCSBRK, (char *)0) < 0)
929 Msg(errno, "Cannot send BREAK (TCSBRK)");
930 return;
933 #else /* TCSBRK */
934 Msg(0, "TCSBRK not available, change breaktype");
935 #endif /* TCSBRK */
936 break;
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)");
948 return;
950 sleep1000(n ? n * 250 : 250);
951 if (ioctl(fd, TIOCCBRK, (char *)0) < 0)
953 Msg(errno, "BREAK stuck!!! -- HELP! (TIOCCBRK)");
954 return;
956 #else /* TIOCSBRK && TIOCCBRK */
957 Msg(0, "TIOCSBRK/CBRK not available, change breaktype");
958 #endif /* TIOCSBRK && TIOCCBRK */
959 break;
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.
971 void
972 SendBreak(wp, n, closeopen)
973 struct win *wp;
974 int n, closeopen;
976 sigret_t (*sigalrm)__P(SIGPROTOARG);
978 #ifdef BUILTIN_TELNET
979 if (wp->w_type == W_TYPE_TELNET)
981 TelBreak(wp);
982 return;
984 #endif
985 if (wp->w_type != W_TYPE_PLAIN)
986 return;
988 debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
990 #ifdef POSIX
991 (void) tcflush(wp->w_ptyfd, TCIOFLUSH);
992 #else
993 # ifdef TIOCFLUSH
994 (void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
995 # endif /* TIOCFLUSH */
996 #endif /* POSIX */
998 if (closeopen)
1000 close(wp->w_ptyfd);
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);
1005 return;
1007 (void) fcntl(wp->w_ptyfd, F_SETFL, FNBLOCK);
1009 else
1011 sigalrm = signal(SIGALRM, SigAlrmDummy);
1012 alarm(15);
1014 DoSendBreak(wp->w_ptyfd, n, breaktype);
1016 alarm(0);
1017 signal(SIGALRM, sigalrm);
1019 debug(" broken.\n");
1023 * Console grabbing
1026 #if (!defined(TIOCCONS) && defined(SRIOCSREDIR)) || defined(linux)
1028 static struct event consredir_ev;
1029 static int consredirfd[2] = {-1, -1};
1031 static void
1032 consredir_readev_fn(ev, data)
1033 struct event *ev;
1034 char *data;
1036 char *p, *n, buf[256];
1037 int l;
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;
1044 evdeq(ev);
1045 return;
1047 for (p = n = buf; l > 0; n++, l--)
1048 if (*n == '\n')
1050 if (n > p)
1051 WriteString(console_window, p, n - p);
1052 WriteString(console_window, "\r\n", 2);
1053 p = n + 1;
1055 if (n > p)
1056 WriteString(console_window, p, n - p);
1059 #endif
1061 /*ARGSUSED*/
1063 TtyGrabConsole(fd, on, rc_name)
1064 int fd, on;
1065 char *rc_name;
1067 #if defined(TIOCCONS) && !defined(linux)
1068 struct display *d;
1069 int ret = 0;
1070 int sfd = -1;
1072 if (on < 0)
1073 return 0; /* pty close will ungrab */
1074 if (on)
1076 if (displays == 0)
1078 Msg(0, "I need a display");
1079 return -1;
1081 for (d = displays; d; d = d->d_next)
1082 if (strcmp(d->d_usertty, "/dev/console") == 0)
1083 break;
1084 if (d)
1086 Msg(0, "too dangerous - screen is running on /dev/console");
1087 return -1;
1091 if (!on)
1093 char *slave;
1094 if ((fd = OpenPTY(&slave)) < 0)
1096 Msg(errno, "%s: could not open detach pty master", rc_name);
1097 return -1;
1099 if ((sfd = open(slave, O_RDWR | O_NOCTTY)) < 0)
1101 Msg(errno, "%s: could not open detach pty slave", rc_name);
1102 close(fd);
1103 return -1;
1106 if (UserContext() == 1)
1107 UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
1108 ret = UserStatus();
1109 if (ret)
1110 Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
1111 if (!on)
1113 close(sfd);
1114 close(fd);
1116 return ret;
1118 #else
1119 # if defined(SRIOCSREDIR) || defined(linux)
1120 struct display *d;
1121 # ifdef SRIOCSREDIR
1122 int cfd;
1123 # else
1124 struct mode new1, new2;
1125 char *slave;
1126 # endif
1128 if (on > 0)
1130 if (displays == 0)
1132 Msg(0, "I need a display");
1133 return -1;
1135 for (d = displays; d; d = d->d_next)
1136 if (strcmp(d->d_usertty, "/dev/console") == 0)
1137 break;
1138 if (d)
1140 Msg(0, "too dangerous - screen is running on /dev/console");
1141 return -1;
1144 if (consredirfd[0] >= 0)
1146 evdeq(&consredir_ev);
1147 close(consredirfd[0]);
1148 close(consredirfd[1]);
1149 consredirfd[0] = consredirfd[1] = -1;
1151 if (on <= 0)
1152 return 0;
1153 # ifdef SRIOCSREDIR
1154 if ((cfd = secopen("/dev/console", O_RDWR|O_NOCTTY, 0)) == -1)
1156 Msg(errno, "/dev/console");
1157 return -1;
1159 if (pipe(consredirfd))
1161 Msg(errno, "pipe");
1162 close(cfd);
1163 consredirfd[0] = consredirfd[1] = -1;
1164 return -1;
1166 if (ioctl(cfd, SRIOCSREDIR, consredirfd[1]))
1168 Msg(errno, "SRIOCSREDIR ioctl");
1169 close(cfd);
1170 close(consredirfd[0]);
1171 close(consredirfd[1]);
1172 consredirfd[0] = consredirfd[1] = -1;
1173 return -1;
1175 close(cfd);
1176 # else
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);
1181 return -1;
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]);
1187 return -1;
1189 InitTTY(&new1, 0);
1190 SetMode(&new1, &new2, 0, 0);
1191 SetTTY(consredirfd[1], &new2);
1192 if (UserContext() == 1)
1193 UserReturn(ioctl(consredirfd[1], TIOCCONS, (char *)&on));
1194 if (UserStatus())
1196 Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
1197 close(consredirfd[0]);
1198 close(consredirfd[1]);
1199 return -1;
1201 # endif
1202 consredir_ev.fd = consredirfd[0];
1203 consredir_ev.type = EV_READ;
1204 consredir_ev.handler = consredir_readev_fn;
1205 evenq(&consredir_ev);
1206 return 0;
1207 # else
1208 if (on > 0)
1209 Msg(0, "%s: don't know how to grab the console", rc_name);
1210 return -1;
1211 # endif
1212 #endif
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.
1219 * Returns buf;
1221 char *
1222 TtyGetModemStatus(fd, buf)
1223 int fd;
1224 char *buf;
1226 char *p = buf;
1227 #ifdef TIOCGSOFTCAR
1228 unsigned int softcar;
1229 #endif
1230 #if defined(TIOCMGET) || defined(TIOCMODG)
1231 unsigned int mflags;
1232 #else
1233 # ifdef MCGETA
1234 /* this is yet another interface, found on hpux. grrr */
1235 mflag mflags;
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
1242 # endif
1243 #endif
1244 #if defined(CLOCAL) || defined(CRTSCTS)
1245 struct mode mtio; /* screen.h */
1246 #endif
1247 #if defined(CRTSCTS) || defined(TIOCM_CTS)
1248 int rtscts;
1249 #endif
1250 int clocal;
1252 #if defined(CLOCAL) || defined(CRTSCTS)
1253 GetTTY(fd, &mtio);
1254 #endif
1255 clocal = 0;
1256 #ifdef CLOCAL
1257 if (mtio.tio.c_cflag & CLOCAL)
1259 clocal = 1;
1260 *p++ = '{';
1262 #endif
1264 #ifdef TIOCM_CTS
1265 # ifdef CRTSCTS
1266 if (!(mtio.tio.c_cflag & CRTSCTS))
1267 rtscts = 0;
1268 else
1269 # endif /* CRTSCTS */
1270 rtscts = 1;
1271 #endif /* TIOCM_CTS */
1273 #ifdef TIOCGSOFTCAR
1274 if (ioctl(fd, TIOCGSOFTCAR, (char *)&softcar) < 0)
1275 softcar = 0;
1276 #endif
1278 #if defined(TIOCMGET) || defined(TIOCMODG) || defined(MCGETA)
1279 # ifdef TIOCMGET
1280 if (ioctl(fd, TIOCMGET, (char *)&mflags) < 0)
1281 # else
1282 # ifdef TIOCMODG
1283 if (ioctl(fd, TIOCMODG, (char *)&mflags) < 0)
1284 # else
1285 if (ioctl(fd, MCGETA, &mflags) < 0)
1286 # endif
1287 # endif
1289 #ifdef TIOCGSOFTCAR
1290 sprintf(p, "NO-TTY? %s", softcar ? "(CD)" : "CD");
1291 #else
1292 sprintf(p, "NO-TTY?");
1293 #endif
1294 p += strlen(p);
1296 else
1298 char *s;
1299 # ifdef FANCY_MODEM
1300 # ifdef TIOCM_LE
1301 if (!(mflags & TIOCM_LE))
1302 for (s = "!LE "; *s; *p++ = *s++);
1303 # endif
1304 # endif /* FANCY_MODEM */
1306 # ifdef TIOCM_RTS
1307 s = "!RTS "; if (mflags & TIOCM_RTS) s++;
1308 while (*s) *p++ = *s++;
1309 # endif
1310 # ifdef TIOCM_CTS
1311 s = "!CTS ";
1312 if (!rtscts)
1314 *p++ = '(';
1315 s = "!CTS) ";
1317 if (mflags & TIOCM_CTS) s++;
1318 while (*s) *p++ = *s++;
1319 # endif
1321 # ifdef TIOCM_DTR
1322 s = "!DTR "; if (mflags & TIOCM_DTR) s++;
1323 while (*s) *p++ = *s++;
1324 # endif
1325 # ifdef TIOCM_DSR
1326 s = "!DSR "; if (mflags & TIOCM_DSR) s++;
1327 while (*s) *p++ = *s++;
1328 # endif
1329 # if defined(TIOCM_CD) || defined(TIOCM_CAR)
1330 s = "!CD ";
1331 # ifdef TIOCGSOFTCAR
1332 if (softcar)
1334 *p++ = '(';
1335 s = "!CD) ";
1337 # endif
1338 # ifdef TIOCM_CD
1339 if (mflags & TIOCM_CD) s++;
1340 # else
1341 if (mflags & TIOCM_CAR) s++;
1342 # endif
1343 while (*s) *p++ = *s++;
1344 # endif
1345 # if defined(TIOCM_RI) || defined(TIOCM_RNG)
1346 # ifdef TIOCM_RI
1347 if (mflags & TIOCM_RI)
1348 # else
1349 if (mflags & TIOCM_RNG)
1350 # endif
1351 for (s = "RI "; *s; *p++ = *s++);
1352 # endif
1353 # ifdef FANCY_MODEM
1354 # ifdef TIOCM_ST
1355 s = "!ST "; if (mflags & TIOCM_ST) s++;
1356 while (*s) *p++ = *s++;
1357 # endif
1358 # ifdef TIOCM_SR
1359 s = "!SR "; if (mflags & TIOCM_SR) s++;
1360 while (*s) *p++ = *s++;
1361 # endif
1362 # endif /* FANCY_MODEM */
1363 if (p > buf && p[-1] == ' ')
1364 p--;
1365 *p = '\0';
1367 #else
1368 # ifdef TIOCGSOFTCAR
1369 sprintf(p, " %s", softcar ? "(CD)", "CD");
1370 p += strlen(p);
1371 # endif
1372 #endif
1373 if (clocal)
1374 *p++ = '}';
1375 *p = '\0';
1376 return buf;
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
1382 * many entries.
1384 #ifndef POSIX
1385 # ifndef TERMIO
1386 # if !defined(B9600) && !defined(B2400) && !defined(B1200) && !defined(B300)
1387 IFN{B0}#define B0 0
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
1403 # endif
1404 # endif
1405 #endif
1408 * On hpux, idx and sym will be different.
1409 * Rumor has it that, we need idx in D_dospeed to make tputs
1410 * padding correct.
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 },
1440 { -1, -1, -1 }
1444 * baud may either be a bits-per-second value or a symbolic
1445 * value as returned by cfget?speed()
1447 struct baud_values *
1448 lookup_baud(baud)
1449 int baud;
1451 struct baud_values *p;
1453 for (p = btable; p->idx >= 0; p++)
1454 if (baud == p->bps || baud == p->sym)
1455 return p;
1456 return NULL;
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)
1467 struct mode *m;
1468 int ibaud, obaud;
1470 struct baud_values *ip, *op;
1472 if ((!(ip = lookup_baud(ibaud)) && ibaud != -1) ||
1473 (!(op = lookup_baud(obaud)) && obaud != -1))
1474 return -1;
1476 #ifdef POSIX
1477 if (ip) cfsetispeed(&m->tio, ip->sym);
1478 if (op) cfsetospeed(&m->tio, op->sym);
1479 #else /* POSIX */
1480 # ifdef TERMIO
1481 if (ip)
1483 # ifdef IBSHIFT
1484 m->tio.c_cflag &= ~(CBAUD << IBSHIFT);
1485 m->tio.c_cflag |= (ip->sym & CBAUD) << IBSHIFT;
1486 # else /* IBSHIFT */
1487 if (ibaud != obaud)
1488 return -1;
1489 # endif /* IBSHIFT */
1491 if (op)
1493 m->tio.c_cflag &= ~CBAUD;
1494 m->tio.c_cflag |= op->sym & CBAUD;
1496 # else /* TERMIO */
1497 if (ip) m->m_ttyb.sg_ispeed = ip->idx;
1498 if (op) m->m_ttyb.sg_ospeed = op->idx;
1499 # endif /* TERMIO */
1500 #endif /* POSIX */
1501 return 0;
1505 * Write out the mode struct in a readable form
1508 #ifdef DEBUG
1509 void
1510 DebugTTY(m)
1511 struct mode *m;
1513 int i;
1515 #ifdef POSIX
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 */
1535 #else /* POSIX */
1536 # ifdef TERMIO
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]);
1546 # else /* TERMIO */
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 */
1567 #endif /* POSIX */
1569 #endif /* DEBUG */