home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / screen-3.5.1 / part03 / tty.sh < prev    next >
Linux/UNIX/POSIX Shell Script  |  1993-08-08  |  20KB  |  787 lines

  1. #!/bin/sh
  2. # sh tty.sh tty.c
  3. # This inserts all the needed #ifdefs for IF{} statements
  4. # and generates tty.c
  5.  
  6. rm -f $1
  7. sed -e '1,17d' \
  8. -e 's%^IF{\(.*\)}\(.*\)%#if defined(\1)\
  9.   \2\
  10. #endif /* \1 */%' \
  11. -e 's%^XIF{\(.*\)}\(.*\)%#if defined(\1) \&\& \1 < MAXCC\
  12.   \2\
  13. #endif /* \1 */%' \
  14.  < $0 > $1
  15. chmod -w $1
  16. exit 0
  17.  
  18. /* Copyright (c) 1993
  19.  *      Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  20.  *      Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  21.  * Copyright (c) 1987 Oliver Laumann
  22.  *
  23.  * This program is free software; you can redistribute it and/or modify
  24.  * it under the terms of the GNU General Public License as published by
  25.  * the Free Software Foundation; either version 2, or (at your option)
  26.  * any later version.
  27.  *  
  28.  * This program is distributed in the hope that it will be useful,
  29.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  30.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  31.  * GNU General Public License for more details.
  32.  *
  33.  * You should have received a copy of the GNU General Public License
  34.  * along with this program (see the file COPYING); if not, write to the
  35.  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  36.  *
  37.  ****************************************************************
  38.  */
  39.  
  40. /*
  41.  * NOTICE: tty.c is automatically generated from tty.sh
  42.  * Do not change anything here. If you then change tty.sh.
  43.  */
  44.  
  45. #include "rcs.h"
  46. RCS_ID("$Id: tty.sh,v 1.7 1993/08/05 14:24:09 mlschroe Exp $ FAU")
  47.  
  48. #include <stdio.h>
  49. #include <sys/types.h>
  50. #include <signal.h>
  51. #include <fcntl.h>
  52. #if !defined(sun) || defined(SUNOS3)
  53. # include <sys/ioctl.h> /* collosions with termios.h */
  54. #else
  55. # ifndef TIOCEXCL
  56. #  include <sys/ttold.h>    /* needed for TIOCEXCL */
  57. # endif
  58. #endif
  59.  
  60. #ifdef ISC
  61. # include <sys/tty.h>
  62. # include <sys/sioctl.h>
  63. # include <sys/pty.h>
  64. #endif
  65.  
  66. #include "config.h"
  67. #include "screen.h"
  68. #include "extern.h"
  69.  
  70. extern struct display *display, *displays;
  71. extern int iflag;
  72.  
  73.  
  74. static sig_t
  75. SigAlrmDummy(SIGDEFARG)
  76. {
  77.   debug("SigAlrmDummy()\n");
  78. #ifndef SIGVOID
  79.   return (sig_t)0;
  80. #endif
  81. }
  82.  
  83. /*
  84.  *  Carefully open a charcter device. Not used to open ttys.
  85.  */
  86.  
  87. int
  88. OpenTTY(line)
  89. char *line;
  90. {
  91.   int f;
  92.   sig_t (*sigalrm)__P(SIGPROTOARG);
  93.  
  94.   sigalrm = signal(SIGALRM, SigAlrmDummy);
  95.   alarm(2);
  96.   /* this open only succeeds, if real uid is allowed */
  97.   if ((f = secopen(line, O_RDWR | O_NDELAY, 0)) == -1)
  98.     {
  99.       Msg(errno, "Cannot open line '%s' for R/W", line);
  100.       alarm(0);
  101.       signal(SIGALRM, sigalrm);
  102.       return -1;
  103.     }
  104. #ifdef I_POP
  105.   debug("OpenTTY I_POP\n");
  106.   while (ioctl(f, I_POP, (char *)0) >= 0)
  107.     ;
  108. #endif
  109.   /*
  110.    * We come here exclusively. This is to stop all kermit and cu type things
  111.    * accessing the same tty line.
  112.    * Perhaps we should better create a lock in some /usr/spool/locks directory?
  113.    */
  114. #ifdef TIOCEXCL
  115.  errno = 0;
  116.  ioctl(f, TIOCEXCL, (char *) 0);
  117.  debug3("%d %d %d\n", getuid(), geteuid(), getpid());
  118.  debug2("%s TIOCEXCL errno %d\n", line, errno);
  119. #endif  /* TIOCEXCL */
  120.   /*
  121.    * We create a sane tty mode. We do not copy things from the display tty
  122.    */
  123. #if WE_REALLY_WANT_TO_COPY_THE_TTY_MODE
  124.   if (display)
  125.     {
  126.       debug1("OpenTTY: using mode of display for %s\n", line);
  127.       SetTTY(f, &d_NewMode);
  128. #ifdef DEBUG
  129.       DebugTTY(&d_NewMode);
  130. #endif
  131.     }
  132.   else
  133. #endif 
  134.     {
  135.       struct mode Mode;
  136.  
  137.       InitTTY(&Mode, TTY_FLAG_PLAIN);
  138. #ifdef DEBUG
  139.       DebugTTY(&Mode);
  140. #endif
  141.       SetTTY(f, &Mode);
  142.     }
  143.   brktty(f);
  144.   alarm(0);
  145.   signal(SIGALRM, sigalrm);
  146.   debug2("'%s' CONNECT fd=%d.\n", line, f);
  147.   return f;
  148. }
  149.  
  150.  
  151. /*
  152.  *  Tty mode handling
  153.  */
  154.  
  155. #if defined(TERMIO) || defined(POSIX)
  156. int intrc, origintrc = VDISABLE;        /* display? */
  157. #else
  158. int intrc, origintrc = -1;        /* display? */
  159. #endif
  160. static startc, stopc;                   /* display? */
  161.  
  162.  
  163. void
  164. InitTTY(m, ttyflag)
  165. struct mode *m;
  166. int ttyflag;
  167. {
  168.   bzero((char *)m, sizeof(*m));
  169. #ifdef POSIX
  170.   /* struct termios tio 
  171.    * defaults, as seen on SunOS 4.1.3
  172.    */
  173.   debug1("InitTTY: POSIX: termios defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
  174. IF{BRKINT}    m->tio.c_iflag |= BRKINT;
  175. IF{IGNPAR}    m->tio.c_iflag |= IGNPAR;
  176. IF{ISTRIP}    m->tio.c_iflag |= ISTRIP;
  177. IF{IXON}    m->tio.c_iflag |= IXON;
  178. IF{IMAXBEL}    m->tio.c_iflag |= IMAXBEL; 
  179.  
  180.   if (!ttyflag)    /* may not even be good for ptys.. */
  181.     {
  182. IF{ICRNL}    m->tio.c_iflag |= ICRNL;
  183. IF{ONLCR}    m->tio.c_oflag |= ONLCR; 
  184. IF{TAB3}    m->tio.c_oflag |= TAB3; 
  185. IF{PARENB}    m->tio.c_cflag |= PARENB;
  186.     }
  187.  
  188. IF{OPOST}    m->tio.c_oflag |= OPOST;
  189.  
  190. IF{B9600}    m->tio.c_cflag |= B9600;
  191. IF{CS8}     m->tio.c_cflag |= CS8;
  192. IF{CREAD}    m->tio.c_cflag |= CREAD;
  193. IF{IBSHIFT) && defined(B9600}    m->tio.c_cflag |= B9600 << IBSHIFT;
  194. /* IF{CLOCAL}    m->tio.c_cflag |= CLOCAL; */
  195.  
  196. IF{ECHOCTL}    m->tio.c_lflag |= ECHOCTL;
  197. IF{ECHOKE}    m->tio.c_lflag |= ECHOKE;
  198.  
  199.   if (!ttyflag)
  200.     {
  201. IF{ISIG}    m->tio.c_lflag |= ISIG;
  202. IF{ICANON}    m->tio.c_lflag |= ICANON;
  203. IF{ECHO}    m->tio.c_lflag |= ECHO;
  204.     }
  205. IF{ECHOE}    m->tio.c_lflag |= ECHOE;
  206. IF{ECHOK}    m->tio.c_lflag |= ECHOK;
  207. IF{IEXTEN}    m->tio.c_lflag |= IEXTEN;
  208.  
  209. XIF{VINTR}    m->tio.c_cc[VINTR]    = Ctrl('C');
  210. XIF{VQUIT}    m->tio.c_cc[VQUIT]    = Ctrl('\\');
  211. XIF{VERASE}    m->tio.c_cc[VERASE]   = 0x7f; /* DEL */
  212. XIF{VKILL}    m->tio.c_cc[VKILL]    = Ctrl('H');
  213. XIF{VEOF}    m->tio.c_cc[VEOF]     = Ctrl('D');
  214. XIF{VEOL}    m->tio.c_cc[VEOL]     = 0000;
  215. XIF{VEOL2}    m->tio.c_cc[VEOL2]    = 0000;
  216. XIF{VSWTCH}    m->tio.c_cc[VSWTCH]   = 0000;
  217. XIF{VSTART}    m->tio.c_cc[VSTART]   = Ctrl('Q');
  218. XIF{VSTOP}    m->tio.c_cc[VSTOP]    = Ctrl('S');
  219. XIF{VSUSP}    m->tio.c_cc[VSUSP]    = Ctrl('Z');
  220. XIF{VDSUSP}    m->tio.c_cc[VDSUSP]   = Ctrl('Y');
  221. XIF{VREPRINT}    m->tio.c_cc[VREPRINT] = Ctrl('R');
  222. XIF{VDISCARD}    m->tio.c_cc[VDISCARD] = Ctrl('O');
  223. XIF{VWERASE}    m->tio.c_cc[VWERASE]  = Ctrl('W');
  224. XIF{VLNEXT}    m->tio.c_cc[VLNEXT]   = Ctrl('V');
  225. XIF{VSTATUS}    m->tio.c_cc[VSTATUS]  = Ctrl('T');
  226.  
  227. # ifdef hpux
  228.   m->m_ltchars.t_suspc =  Ctrl('Z');
  229.   m->m_ltchars.t_dsuspc = Ctrl('Y');
  230.   m->m_ltchars.t_rprntc = Ctrl('R');
  231.   m->m_ltchars.t_flushc = Ctrl('O');
  232.   m->m_ltchars.t_werasc = Ctrl('W');
  233.   m->m_ltchars.t_lnextc = Ctrl('V');
  234. # endif /* hpux */
  235.  
  236. #else /* POSIX */
  237.  
  238. # ifdef TERMIO
  239.   debug1("InitTTY: nonPOSIX, struct termio a la Motorola SYSV68 (%d)\n", ttyflag);
  240.   /* struct termio tio 
  241.    * defaults, as seen on Mototola SYSV68:
  242.    * input: 7bit, CR->NL, ^S/^Q flow control 
  243.    * output: POSTprocessing: NL->NL-CR, Tabs to spaces
  244.    * control: 9600baud, 8bit CSIZE, enable input
  245.    * local: enable signals, erase/kill processing, echo on.
  246.    */
  247. IF{ISTRIP}    m->tio.c_iflag |= ISTRIP;
  248. IF{IXON}    m->tio.c_iflag |= IXON;
  249.  
  250. IF{OPOST}    m->tio.c_oflag |= OPOST;
  251.  
  252.   if (!ttyflag)    /* may not even be good for ptys.. */
  253.     {
  254. IF{ICRNL}    m->tio.c_iflag |= ICRNL;
  255. IF{ONLCR}    m->tio.c_oflag |= ONLCR;
  256. IF{TAB3}    m->tio.c_oflag |= TAB3;
  257.     }
  258.  
  259. IF{B9600}    m->tio.c_cflag  = B9600;
  260. IF{CS8}     m->tio.c_cflag |= CS8;
  261. IF{CREAD}    m->tio.c_cflag |= CREAD;
  262.  
  263.   if (!ttyflag)
  264.     {
  265. IF{ISIG}    m->tio.c_lflag |= ISIG;
  266. IF{ICANON}    m->tio.c_lflag |= ICANON;
  267. IF{ECHO}    m->tio.c_lflag |= ECHO;
  268.     }
  269. IF{ECHOE}    m->tio.c_lflag |= ECHOE;
  270. IF{ECHOK}    m->tio.c_lflag |= ECHOK;
  271.  
  272. XIF{VINTR}    m->tio.c_cc[VINTR]  = Ctrl('C');
  273. XIF{VQUIT}    m->tio.c_cc[VQUIT]  = Ctrl('\\');
  274. XIF{VERASE}    m->tio.c_cc[VERASE] = 0177; /* DEL */
  275. XIF{VKILL}    m->tio.c_cc[VKILL]  = Ctrl('H');
  276. XIF{VEOF}    m->tio.c_cc[VEOF]   = Ctrl('D');
  277. XIF{VEOL}    m->tio.c_cc[VEOL]   = 0377;
  278. XIF{VEOL2}    m->tio.c_cc[VEOL2]  = 0377;
  279. XIF{VSWTCH}    m->tio.c_cc[VSWTCH] = 0000;
  280. # else /* TERMIO */
  281.   debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
  282.   m->m_ttyb.sg_ispeed = B9600;
  283.   m->m_ttyb.sg_ospeed = B9600;
  284.   m->m_ttyb.sg_erase  = 0177; /*DEL */
  285.   m->m_ttyb.sg_kill   = Ctrl('H');
  286.   if (!ttyflag)
  287.     m->m_ttyb.sg_flags = CRMOD | ECHO
  288. IF{ANYP}    | ANYP
  289.     ;
  290.   else
  291.     m->m_ttyb.sg_flags = CBREAK
  292. IF{ANYP}    | ANYP
  293.     ;
  294.  
  295.   m->m_tchars.t_intrc   = Ctrl('C');
  296.   m->m_tchars.t_quitc   = Ctrl('\\');
  297.   m->m_tchars.t_startc  = Ctrl('Q');
  298.   m->m_tchars.t_stopc   = Ctrl('S');
  299.   m->m_tchars.t_eofc    = Ctrl('D');
  300.   m->m_tchars.t_brkc    = -1;
  301.  
  302.   m->m_ltchars.t_suspc  = Ctrl('Z');
  303.   m->m_ltchars.t_dsuspc = Ctrl('Y');
  304.   m->m_ltchars.t_rprntc = Ctrl('R');
  305.   m->m_ltchars.t_flushc = Ctrl('O');
  306.   m->m_ltchars.t_werasc = Ctrl('W');
  307.   m->m_ltchars.t_lnextc = Ctrl('V');
  308.  
  309. IF{NTTYDISC}    m->m_ldisc = NTTYDISC;
  310.  
  311.   m->m_lmode = 0
  312. IF{LDECCTQ}    | LDECCTQ
  313. IF{LCTLECH}    | LCTLECH
  314. IF{LPASS8}    | LPASS8
  315. IF{LCRTKIL}    | LCRTKIL
  316. IF{LCRTERA}    | LCRTERA
  317. IF{LCRTBS}    | LCRTBS
  318. ;
  319. # endif /* TERMIO */
  320. #endif /* POSIX */
  321. }
  322.  
  323. void 
  324. SetTTY(fd, mp)
  325. int fd;
  326. struct mode *mp;
  327. {
  328.   errno = 0;
  329. #ifdef POSIX
  330.   tcsetattr(fd, TCSADRAIN, &mp->tio);
  331. # ifdef hpux
  332.   ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars);
  333. # endif
  334. #else
  335. # ifdef TERMIO
  336.   ioctl(fd, TCSETAW, (char *)&mp->tio);
  337. # else
  338.   /* ioctl(fd, TIOCSETP, (char *)&mp->m_ttyb); */
  339.   ioctl(fd, TIOCSETC, (char *)&mp->m_tchars);
  340.   ioctl(fd, TIOCLSET, (char *)&mp->m_lmode);
  341.   ioctl(fd, TIOCSETD, (char *)&mp->m_ldisc);
  342.   ioctl(fd, TIOCSETP, (char *)&mp->m_ttyb);
  343.   ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars); /* moved here for apollo. jw */
  344. # endif
  345. #endif
  346.   if (errno)
  347.     Msg(errno, "SetTTY (fd %d): ioctl failed", fd);
  348. }
  349.  
  350. void
  351. GetTTY(fd, mp)
  352. int fd;
  353. struct mode *mp;
  354. {
  355.   errno = 0;
  356. #ifdef POSIX
  357.   tcgetattr(fd, &mp->tio);
  358. # ifdef hpux
  359.   ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
  360. # endif
  361. #else
  362. # ifdef TERMIO
  363.   ioctl(fd, TCGETA, (char *)&mp->tio);
  364. # else
  365.   ioctl(fd, TIOCGETP, (char *)&mp->m_ttyb);
  366.   ioctl(fd, TIOCGETC, (char *)&mp->m_tchars);
  367.   ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
  368.   ioctl(fd, TIOCLGET, (char *)&mp->m_lmode);
  369.   ioctl(fd, TIOCGETD, (char *)&mp->m_ldisc);
  370. # endif
  371. #endif
  372.   if (errno)
  373.     Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
  374. }
  375.  
  376. void
  377. SetMode(op, np)
  378. struct mode *op, *np;
  379. {
  380.   *np = *op;
  381.  
  382. #if defined(TERMIO) || defined(POSIX)
  383.   np->tio.c_iflag &= ~ICRNL;
  384. # ifdef ONLCR
  385.   np->tio.c_oflag &= ~ONLCR;
  386. # endif
  387.   np->tio.c_lflag &= ~(ICANON | ECHO);
  388. #ifdef OSF1
  389.   /*
  390.    * From Andrew Myers (andru@tonic.lcs.mit.edu)
  391.    */
  392.   np->tio.c_lflag &= ~IEXTEN;
  393. #endif
  394.  
  395.   /*
  396.    * Unfortunately, the master process never will get SIGINT if the real
  397.    * terminal is different from the one on which it was originaly started
  398.    * (process group membership has not been restored or the new tty could not
  399.    * be made controlling again). In my solution, it is the attacher who
  400.    * receives SIGINT (because it is always correctly associated with the real
  401.    * tty) and forwards it to the master [kill(MasterPid, SIGINT)]. 
  402.    * Marc Boucher (marc@CAM.ORG)
  403.    */
  404.   if (iflag)
  405.     np->tio.c_lflag |= ISIG;
  406.   else
  407.     np->tio.c_lflag &= ~ISIG;
  408.   /* 
  409.    * careful, careful catche monkey..
  410.    * never set VMIN and VTIME to zero, if you want blocking io.
  411.    */
  412.   np->tio.c_cc[VMIN] = 1;
  413.   np->tio.c_cc[VTIME] = 0;
  414.   startc = op->tio.c_cc[VSTART];
  415.   stopc = op->tio.c_cc[VSTOP];
  416.   if (iflag)
  417.     origintrc = intrc = op->tio.c_cc[VINTR];
  418.   else
  419.     {
  420.       origintrc = op->tio.c_cc[VINTR];
  421.       intrc = np->tio.c_cc[VINTR] = VDISABLE;
  422.     }
  423.   np->tio.c_cc[VQUIT] = VDISABLE;
  424.   if (d_flow == 0)
  425.     {
  426.       np->tio.c_cc[VINTR] = VDISABLE;
  427.       np->tio.c_cc[VSTART] = VDISABLE;
  428.       np->tio.c_cc[VSTOP] = VDISABLE;
  429.       np->tio.c_iflag &= ~IXON;
  430.     }
  431. XIF{VDISCARD}    np->tio.c_cc[VDISCARD] = VDISABLE;
  432. XIF{VSUSP}    np->tio.c_cc[VSUSP] = VDISABLE;
  433. # ifdef hpux
  434.   np->m_ltchars.t_suspc  = VDISABLE;
  435.   np->m_ltchars.t_dsuspc = VDISABLE;
  436.   np->m_ltchars.t_rprntc = VDISABLE;
  437.   np->m_ltchars.t_flushc = VDISABLE;
  438.   np->m_ltchars.t_werasc = VDISABLE;
  439.   np->m_ltchars.t_lnextc = VDISABLE;
  440. # else /* hpux */
  441. XIF{VDSUSP}    np->tio.c_cc[VDSUSP] = VDISABLE;
  442. # endif /* hpux */
  443. #else /* TERMIO || POSIX */
  444.   startc = op->m_tchars.t_startc;
  445.   stopc = op->m_tchars.t_stopc;
  446.   if (iflag)
  447.     origintrc = intrc = op->m_tchars.t_intrc;
  448.   else
  449.     {
  450.       origintrc = op->m_tchars.t_intrc;
  451.       intrc = np->m_tchars.t_intrc = -1;
  452.     }
  453.   np->m_ttyb.sg_flags &= ~(CRMOD | ECHO);
  454.   np->m_ttyb.sg_flags |= CBREAK;
  455.   np->m_tchars.t_quitc = -1;
  456.   if (d_flow == 0)
  457.     {
  458.       np->m_tchars.t_intrc = -1;
  459.       np->m_tchars.t_startc = -1;
  460.       np->m_tchars.t_stopc = -1;
  461.     }
  462.   np->m_ltchars.t_suspc = -1;
  463.   np->m_ltchars.t_dsuspc = -1;
  464.   np->m_ltchars.t_flushc = -1;
  465.   np->m_ltchars.t_lnextc = -1;
  466. #endif /* defined(TERMIO) || defined(POSIX) */
  467. }
  468.  
  469. void
  470. SetFlow(on)
  471. int on;
  472. {
  473.   ASSERT(display);
  474.   if (d_flow == on)
  475.     return;
  476. #if defined(TERMIO) || defined(POSIX)
  477.   if (on)
  478.     {
  479.       d_NewMode.tio.c_cc[VINTR] = intrc;
  480.       d_NewMode.tio.c_cc[VSTART] = startc;
  481.       d_NewMode.tio.c_cc[VSTOP] = stopc;
  482.       d_NewMode.tio.c_iflag |= IXON;
  483.     }
  484.   else
  485.     {
  486.       d_NewMode.tio.c_cc[VINTR] = VDISABLE;
  487.       d_NewMode.tio.c_cc[VSTART] = VDISABLE;
  488.       d_NewMode.tio.c_cc[VSTOP] = VDISABLE;
  489.       d_NewMode.tio.c_iflag &= ~IXON;
  490.     }
  491. # ifdef POSIX
  492.   if (tcsetattr(d_userfd, TCSANOW, &d_NewMode.tio))
  493. # else
  494.   if (ioctl(d_userfd, TCSETAW, (char *)&d_NewMode.tio) != 0)
  495. # endif
  496.     debug1("SetFlow: ioctl errno %d\n", errno);
  497. #else /* POSIX || TERMIO */
  498.   if (on)
  499.     {
  500.       d_NewMode.m_tchars.t_intrc = intrc;
  501.       d_NewMode.m_tchars.t_startc = startc;
  502.       d_NewMode.m_tchars.t_stopc = stopc;
  503.     }
  504.   else
  505.     {
  506.       d_NewMode.m_tchars.t_intrc = -1;
  507.       d_NewMode.m_tchars.t_startc = -1;
  508.       d_NewMode.m_tchars.t_stopc = -1;
  509.     }
  510.   if (ioctl(d_userfd, TIOCSETC, (char *)&d_NewMode.m_tchars) != 0)
  511.     debug1("SetFlow: ioctl errno %d\n", errno);
  512. #endif /* POSIX || TERMIO */
  513.   d_flow = on;
  514. }
  515.  
  516.  
  517. /*
  518.  *  Job control handling
  519.  */
  520.  
  521. /*ARGSUSED*/
  522. void
  523. brktty(fd)
  524. int fd;
  525. {
  526. #ifdef POSIX
  527.   setsid();        /* will break terminal affiliation */
  528. # ifdef BSD
  529.   ioctl(fd, TIOCSCTTY, (char *)0);
  530. # endif /* BSD */
  531. #else /* POSIX */
  532. # ifdef SYSV
  533.   setpgrp();        /* will break terminal affiliation */
  534. # else /* SYSV */
  535. #  ifdef BSDJOBS
  536.   int devtty;
  537.  
  538.   if ((devtty = open("/dev/tty", O_RDWR | O_NDELAY)) >= 0)
  539.     {
  540.       if (ioctl(devtty, TIOCNOTTY, (char *)0))
  541.         debug2("brktty: ioctl(devtty=%d, TIOCNOTTY, 0) = %d\n", devtty, errno);
  542.       close(devtty);
  543.     }
  544. #  endif /* BSDJOBS */
  545. # endif /* SYSV */
  546. #endif /* POSIX */
  547. }
  548.  
  549. int
  550. fgtty(fd)
  551. int fd;
  552. {
  553. #ifdef BSDJOBS
  554.   int mypid;
  555.  
  556.   mypid = getpid();
  557.  
  558. # if defined(BSDI) || defined(__386BSD__) || defined(__osf__)
  559.   setsid();    /* should be already done */
  560.   ioctl(fd, TIOCSCTTY, (char *)0);
  561. # endif /* BSDI || __386BSD__ */
  562.  
  563. # ifdef POSIX
  564.   if (tcsetpgrp(fd, mypid))
  565.     {
  566.       debug1("fgtty: tcsetpgrp: %d\n", errno);
  567.       return -1;
  568.     }
  569. # else /* POSIX */
  570.   if (ioctl(fd, TIOCSPGRP, (char *)&mypid) != 0)
  571.     debug1("fgtty: TIOSETPGRP: %d\n", errno);
  572. #  ifndef SYSV    /* Already done in brktty():setpgrp() */
  573.   if (setpgrp(fd, mypid))
  574.     debug1("fgtty: setpgrp: %d\n", errno);
  575. #  endif
  576. # endif /* POSIX */
  577. #endif /* BSDJOBS */
  578.   return 0;
  579. }
  580.  
  581.  
  582. /* 
  583.  * Send a break for n * 0.25 seconds. Tty must be PLAIN.
  584.  */
  585.  
  586. void SendBreak(wp, n, closeopen)
  587. struct win *wp;
  588. int n, closeopen;
  589. {
  590.   if ((wp->w_t.flags & TTY_FLAG_PLAIN) == 0)
  591.     return;
  592.  
  593.   debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
  594. #ifdef POSIX
  595.   (void) tcflush(wp->w_ptyfd, TCIOFLUSH);
  596. #else
  597. # ifdef TIOCFLUSH
  598.   (void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
  599. # endif /* TIOCFLUSH */
  600. #endif /* POSIX */
  601.   if (closeopen)
  602.     {
  603.       close(wp->w_ptyfd);
  604.       sleep((n + 3) / 4);
  605.       if ((wp->w_ptyfd = OpenTTY(wp->w_tty)) < 1)
  606.     {
  607.       Msg(0, "Ouch, cannot reopen line %s, please try harder", wp->w_tty);
  608.       return;
  609.     }
  610.       (void) fcntl(wp->w_ptyfd, F_SETFL, FNDELAY);
  611.     }
  612.   else
  613.     {
  614. #ifdef POSIX 
  615.       debug("tcsendbreak\n");
  616.       if (tcsendbreak(wp->w_ptyfd, n) < 0)
  617.     {
  618.       Msg(errno, "cannot send BREAK");
  619.       return;
  620.     }
  621. #else
  622.       if (!n)
  623.     n++;
  624. # ifdef TCSBRK
  625.       debug("TCSBRK\n");
  626.     {
  627.       int i;
  628.       for (i = 0; i < n; i++)
  629.         if (ioctl(wp->w_ptyfd, TCSBRK, (char *)0) < 0)
  630.           {
  631.         Msg(errno, "Cannot send BREAK");
  632.         return;
  633.           }
  634.     }
  635. # else /* TCSBRK */
  636. #  if defined(TIOCSBRK) && defined(TIOCCBRK)
  637.       debug("TIOCSBRK TIOCCBRK\n");
  638.       if (ioctl(wp->w_ptyfd, TIOCSBRK, (char *)0) < 0)
  639.     {
  640.       Msg(errno, "Can't send BREAK");
  641.       return;
  642.     }
  643.       sleep((n + 3) / 4);
  644.       if (ioctl(wp->w_ptyfd, TIOCCBRK, (char *)0) < 0)
  645.     {
  646.       Msg(errno, "BREAK stuck!!! -- HELP!");
  647.       return;
  648.     }
  649. #  else /* TIOCSBRK && TIOCCBRK */
  650.       Msg(0, "Break not simulated yet"); 
  651.       return;
  652. #  endif /* TIOCSBRK && TIOCCBRK */
  653. # endif /* TCSBRK */
  654. #endif /* POSIX */
  655.       debug("            broken\n");
  656.     }
  657. }
  658.  
  659.  
  660. /*
  661.  *  Console grabbing
  662.  */
  663.  
  664. /*ARGSUSED*/
  665. int
  666. TtyGrabConsole(fd, on, rc_name)
  667. int fd, on;
  668. char *rc_name;
  669. {
  670. #ifdef TIOCCONS
  671.   char *slave;
  672.   int sfd = -1, ret = 0;
  673.   struct display *d;
  674.  
  675.   if (!on)
  676.     {
  677.       if ((fd = OpenPTY(&slave)) < 0)
  678.     {
  679.       Msg(errno, "%s: could not open detach pty master", rc_name);
  680.       return -1;
  681.     }
  682.       if ((sfd = open(slave, O_RDWR)) < 0)
  683.     {
  684.       Msg(errno, "%s: could not open detach pty slave", rc_name);
  685.       close(fd);
  686.       return -1;
  687.     }
  688.     }
  689.   else
  690.     {
  691.       if (displays == 0)
  692.     {
  693.       Msg(0, "I need a display");
  694.       return -1;
  695.     }
  696.       for (d = displays; d; d = d->_d_next)
  697.     if (strcmp(d->_d_usertty, "/dev/console") == 0)
  698.       break;
  699.       if (d)
  700.     {
  701.       Msg(0, "too dangerous - screen is running on /dev/console");
  702.       return -1;
  703.     }
  704.     }
  705.   if (UserContext() == 1)
  706.     UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
  707.   ret = UserStatus();
  708.   if (ret)
  709.     Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
  710.   if (!on)
  711.     {
  712.       close(sfd);
  713.       close(fd);
  714.     }
  715.   return ret;
  716. #else /* TIOCCONS */
  717.   Msg(0, "%s: no TIOCCONS on this machine", rc_name);
  718.   return -1;
  719. #endif /* TIOCCONS */
  720. }
  721.  
  722.  
  723. /*
  724.  *  Write out the mode struct in a readable form
  725.  */
  726.  
  727. #ifdef DEBUG
  728. void
  729. DebugTTY(m)
  730. struct mode *m;
  731. {
  732.   int i;
  733.  
  734. #ifdef POSIX
  735.   debug("struct termios tio:\n");
  736.   debug1("c_iflag = %#x\n", m->tio.c_iflag);
  737.   debug1("c_oflag = %#x\n", m->tio.c_oflag);
  738.   debug1("c_cflag = %#x\n", m->tio.c_cflag);
  739.   debug1("c_lflag = %#x\n", m->tio.c_lflag);
  740.   for (i = 0; i < sizeof(m->tio.c_cc)/sizeof(*m->tio.c_cc); i++)
  741.     {
  742.       debug2("c_cc[%d] = %#x\n", i, m->tio.c_cc[i]);
  743.     }
  744. # ifdef hpux
  745.   debug1("suspc     = %#02x\n", m->m_ltchars.t_suspc);
  746.   debug1("dsuspc    = %#02x\n", m->m_ltchars.t_dsuspc);
  747.   debug1("rprntc    = %#02x\n", m->m_ltchars.t_rprntc);
  748.   debug1("flushc    = %#02x\n", m->m_ltchars.t_flushc);
  749.   debug1("werasc    = %#02x\n", m->m_ltchars.t_werasc);
  750.   debug1("lnextc    = %#02x\n", m->m_ltchars.t_lnextc);
  751. # endif /* hpux */
  752. #else /* POSIX */
  753. # ifdef TERMIO
  754.   debug("struct termio tio:\n");
  755.   debug1("c_iflag = %04o\n", m->tio.c_iflag);
  756.   debug1("c_oflag = %04o\n", m->tio.c_oflag);
  757.   debug1("c_cflag = %04o\n", m->tio.c_cflag);
  758.   debug1("c_lflag = %04o\n", m->tio.c_lflag);
  759.   for (i = 0; i < sizeof(m->tio.c_cc)/sizeof(*m->tio.c_cc); i++)
  760.     {
  761.       debug2("c_cc[%d] = %04o\n", i, m->tio.c_cc[i]);
  762.     }
  763. # else /* TERMIO */
  764.   debug1("sg_ispeed = %d\n",    m->m_ttyb.sg_ispeed);
  765.   debug1("sg_ospeed = %d\n",    m->m_ttyb.sg_ospeed);
  766.   debug1("sg_erase  = %#02x\n", m->m_ttyb.sg_erase);
  767.   debug1("sg_kill   = %#02x\n", m->m_ttyb.sg_kill);
  768.   debug1("sg_flags  = %#04x\n", (unsigned short)m->m_ttyb.sg_flags);
  769.   debug1("intrc     = %#02x\n", m->m_tchars.t_intrc);
  770.   debug1("quitc     = %#02x\n", m->m_tchars.t_quitc);
  771.   debug1("startc    = %#02x\n", m->m_tchars.t_startc);
  772.   debug1("stopc     = %#02x\n", m->m_tchars.t_stopc);
  773.   debug1("eofc      = %#02x\n", m->m_tchars.t_eofc);
  774.   debug1("brkc      = %#02x\n", m->m_tchars.t_brkc);
  775.   debug1("suspc     = %#02x\n", m->m_ltchars.t_suspc);
  776.   debug1("dsuspc    = %#02x\n", m->m_ltchars.t_dsuspc);
  777.   debug1("rprntc    = %#02x\n", m->m_ltchars.t_rprntc);
  778.   debug1("flushc    = %#02x\n", m->m_ltchars.t_flushc);
  779.   debug1("werasc    = %#02x\n", m->m_ltchars.t_werasc);
  780.   debug1("lnextc    = %#02x\n", m->m_ltchars.t_lnextc);
  781.   debug1("ldisc     = %d\n",    m->m_ldisc);
  782.   debug1("lmode     = %#x\n",   m->m_lmode);
  783. # endif /* TERMIO */
  784. #endif /* POSIX */
  785. }
  786. #endif /* DEBUG */
  787.