home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 1 / RISC_DISC_1.iso / pd_share / code / unixlib / !UnixLib / src / unix / c / tty < prev    next >
Encoding:
Text File  |  1994-09-30  |  13.8 KB  |  804 lines

  1. static char sccs_id[] = "@(#) tty.c 4.0 " __DATE__ " HJR";
  2.  
  3. /* tty.c (c) Copyright 1990 H.Rogers */
  4.  
  5. /* SYS V tty device driver for RiscOS */
  6.  
  7. #include <signal.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <errno.h>
  11. #include <stdlib.h>
  12.  
  13. #include "fcntl.h"
  14. #include "termio.h"
  15.  
  16. #include "sys/types.h"
  17. #include "sys/unix.h"
  18. #include "sys/dev.h"
  19. #include "sys/tty.h"
  20. #include "sys/os.h"
  21. #include "sys/param.h"
  22.  
  23. static struct tty *__t;        /* current tty */
  24.  
  25. #define __ttyx(x)    /* increment cursor posn. by (x) */ \
  26.     (__t->sx += (x), \
  27.     __t->del[__t->cx = (__t->cx + 1) & (MAXPATHLEN - 1)] = (x))
  28.  
  29. static int __ttyicanon (void *buf, int nbyte, struct file *f);
  30. static int __ttyiraw (void *buf, int nbyte, struct file *f);
  31.  
  32. static int __ttyinput (int c, int iflag);
  33. static void __ttyecho (int c, int oflag, int lflag);
  34. static void __ttydel (int lflag);
  35. static void __ttytab (int oflag);
  36. static void __ttycr (int oflag);
  37. static void __ttynl (int oflag);
  38.  
  39. static char __ttybaud[0x10] =
  40. {0, 9, 1, 10, 11, 2, 0, 3, 12, 4, 13, 5, 6, 7, 8, 0};
  41.  
  42. /* get console window size */
  43.  
  44. static void
  45. __tty_console_gwinsz (register struct winsize *w)
  46. {
  47.   static int i[9] =
  48.   {132, 134, 135, 133, 128, 130, 129, 131, -1};
  49.   int o[8];
  50.   int r[10];
  51.  
  52.   r[0] = (int) i;
  53.   r[1] = (int) o;
  54.   os_swi (0x31, r);
  55.   w->ws_col = o[1] - o[0] + 1;
  56.   w->ws_row = o[3] - o[2] + 1;
  57.   w->ws_xpixel = o[5] - o[4] + 1;
  58.   w->ws_ypixel = o[7] - o[6] + 1;
  59. }
  60.  
  61. /* set console window size */
  62.  
  63. static void
  64. __tty_console_swinsz (register struct winsize *w)
  65. {
  66.   static int i[7] =
  67.   {132, 135, 128, 131, 4, 5, -1};
  68.   int o[6];
  69.   int r[10];
  70.   register int j;
  71.  
  72.   r[0] = (int) i;
  73.   r[1] = (int) o;
  74.   os_swi (0x31, r);
  75.   os_vdu (28);
  76.   os_vdu (o[0]);
  77.   os_vdu (o[1] + w->ws_row - 1);
  78.   os_vdu (o[0] + w->ws_col - 1);
  79.   os_vdu (o[1]);
  80.   os_vdu (24);
  81.   j = o[2];
  82.   j <<= o[4];
  83.   os_vdu (j & 0xff);
  84.   os_vdu (j >> 8);
  85.   j = o[3] - (w->ws_ypixel - 1);
  86.   j <<= o[5];
  87.   os_vdu (j & 0xff);
  88.   os_vdu (j >> 8);
  89.   j = o[2] + w->ws_xpixel - 1;
  90.   j <<= o[4];
  91.   os_vdu (j & 0xff);
  92.   os_vdu (j >> 8);
  93.   j = o[3];
  94.   j <<= o[5];
  95.   os_vdu (j & 0xff);
  96.   os_vdu (j >> 8);
  97. }
  98.  
  99. /* read console */
  100.  
  101. static void
  102. __tty_console_gterm (register struct termio *t)
  103. {
  104.   int r[3];
  105.  
  106.   os_byte (0xdc, 0, 0xff, r);
  107.   t->c_cc[VINTR] = r[1];
  108.   os_byte (0xe5, 0, 0xff, r);
  109.   if (r[1])
  110.     t->c_lflag &= ~ISIG;
  111.   else
  112.     t->c_lflag |= ISIG;
  113. }
  114.  
  115. /* set console */
  116.  
  117. static void
  118. __tty_console_sterm (register struct termio *t)
  119. {
  120.   os_byte (0xdc, t->c_cc[VINTR], 0, 0);
  121.   if (t->c_lflag & ISIG)
  122.     os_byte (0xe5, 0, 0, 0);
  123.   else
  124.     os_byte (0xe5, 0xff, 0, 0);
  125. }
  126.  
  127. /* set RS423 */
  128.  
  129. static void
  130. __tty_423_sterm (register struct termio *t)
  131. {
  132.   register int i, c;
  133.   int r[10];
  134.  
  135.   i = t->c_cflag & CIBAUD;
  136.   i = i ? (i >> IBSHIFT) : (t->c_cflag & CBAUD);
  137.   r[0] = 5;
  138.   if (r[1] = __ttybaud[i])
  139.     os_swi (0x57, r);
  140.   i = t->c_cflag & CBAUD;
  141.   r[0] = 6;
  142.   if (r[1] = __ttybaud[i])
  143.     os_swi (0x57, r);
  144.   i = t->c_cflag;
  145.   switch (i & CSIZE)
  146.     {
  147.     case CS5:
  148.       c = 3;
  149.       break;
  150.     case CS6:
  151.       c = 2;
  152.       break;
  153.     case CS7:
  154.       c = 1;
  155.       break;
  156.     case CS8:
  157.     default:
  158.       c = 0;
  159.       break;
  160.     }
  161.   if (i & CSTOPB)
  162.     c |= 0x04;
  163.   if (i & PARENB)
  164.     {
  165.       c |= 0x08;
  166.       if (!(i & PARODD))
  167.     c |= 0x10;
  168.     }
  169.   r[0] = 1;
  170.   r[1] = c;
  171.   os_swi (0x57, r);
  172. }
  173.  
  174. int
  175. __ttyopen (char *file, int mode, struct file *f)
  176. {
  177.   struct tty *_t;
  178.   int l;
  179.  
  180.   mode = mode;
  181.  
  182.   switch (*(file + 5))
  183.     {
  184.     case 'c':            /* console */
  185.       _t = __u->tty + (l = TTY_CON);
  186.       __u->flag = (__u->flag & ~__U_TTY) | (TTY_CON << __U_TTYSHIFT);
  187.       break;
  188.     case 'r':            /* rs423 */
  189.       _t = __u->tty + (l = TTY_423);
  190.       __u->flag = (__u->flag & ~__U_TTY) | (TTY_423 << __U_TTYSHIFT);
  191.       break;
  192.     case 't':            /* tty */
  193.       _t = __u->tty + (l = ((__u->flag & __U_TTY) >> __U_TTYSHIFT));
  194.       break;
  195.     default:
  196.       return (-1);
  197.       break;
  198.     }
  199.  
  200.   {
  201.     register struct termio *t = _t->t;
  202.  
  203.     t->c_iflag = BRKINT | ICRNL | IMAXBEL;
  204.     t->c_oflag = OPOST | ONLCR | XTABS;
  205.     if (l == TTY_CON)
  206.       t->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
  207.     else if (l == TTY_423)
  208.       t->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
  209.     t->c_lflag = ISIG | ICANON | ECHO;
  210.     t->c_line = 0;
  211.  
  212.     {
  213.       static char cc[NCC] =
  214.       {CINTR, CQUIT, CERASE, CKILL, CEOF, CEOL, CEOL2,
  215.        CSWTCH, CSTART, CSTOP, CSUSP, 0, CREPRINT, CDISCARD, CWERASE, CLNEXT};
  216.  
  217.       memcpy (t->c_cc, cc, NCC);
  218.     }
  219.  
  220.     if (l == TTY_CON)
  221.       __tty_console_gterm (t);    /* RS423 is set up later */
  222.   }
  223.  
  224.   {
  225.     register struct winsize *w = _t->w;
  226.  
  227.     if (l == TTY_CON)
  228.       __tty_console_gwinsz (w);
  229.     else if (l == TTY_423)
  230.       {
  231.     w->ws_col = 80;
  232.     w->ws_row = 25;
  233.     w->ws_xpixel = w->ws_ypixel = 0;
  234.       }
  235.   }
  236.  
  237.   if (l == TTY_CON)
  238.     {
  239.       _t->out = os_vdu;
  240.       _t->in = os_get;
  241.       _t->scan = os_inkey;
  242.       _t->init = os_console;
  243.       _t->flush = os_keyflush;
  244.     }
  245.   else if (l == TTY_423)
  246.     {
  247.       _t->out = os_423vdu;
  248.       _t->in = os_423get;
  249.       _t->scan = os_423inkey;
  250.       _t->init = os_423;
  251.       _t->flush = os_423flush;
  252.     }
  253.  
  254.   _t->buf = _t->ptr = 0;
  255.   _t->cnt = 0;
  256.   _t->del = 0;
  257.   _t->sx = _t->cx = 0;
  258.  
  259.   {
  260.     register int *r = f->r;
  261.  
  262.     r[0] = r[1] = r[2] = r[3] = r[4] = 0;
  263.     r[5] = 0x33;
  264.   }
  265.  
  266.   (*(_t->init)) ();
  267.  
  268.   if (l == TTY_423)
  269.     __tty_423_sterm (_t->t);
  270.  
  271.   return (l);
  272. }
  273.  
  274. int
  275. __ttyclose (int l, struct file *f)
  276. {
  277.   register struct tty *_t;
  278.  
  279.   f = f;
  280.  
  281.   _t = __u->tty + l;
  282.  
  283.   if (_t->del)
  284.     free (_t->del);
  285.   if (_t->buf)
  286.     free (_t->buf);
  287.  
  288.   _t->buf = _t->ptr = 0;
  289.   _t->cnt = 0;
  290.   _t->del = 0;
  291.   _t->sx = _t->cx = 0;
  292.  
  293.   return (0);
  294. }
  295.  
  296.  
  297. int
  298. __ttyread (int l, void *buf, int nbyte, struct file *f)
  299. {
  300.   __t = __u->tty + l;
  301.  
  302.   if (!__t->del)
  303.     if (!(__t->del = malloc (MAXPATHLEN)))
  304.       {
  305.     errno = ENOMEM;
  306.     return (-1);
  307.       }
  308.  
  309.   return ((__t->t->c_lflag & ICANON) ? \
  310.       __ttyicanon (buf, nbyte, f) : \
  311.       __ttyiraw (buf, nbyte, f));
  312. }
  313.  
  314. static int
  315. __ttyicanon (void *buf, register int nbyte, struct file *f)
  316. {
  317.   register int c, i;
  318.   register char *s;
  319.   register int nflag;
  320.   register int iflag, oflag, lflag;
  321.   register char *cc;
  322.   int ceof, ceol, ceol2;
  323.  
  324. #define F_LNEXT     000001
  325. #define F_MAX        000002
  326. #define F_NDELAY    000004
  327.  
  328.   if (!__t->buf)
  329.     {
  330.       if (!(__t->buf = malloc (MAXPATHLEN)))
  331.     {
  332.       errno = ENOMEM;
  333.       return (-1);
  334.     }
  335.       __t->cnt = 0;
  336.       __t->ptr = __t->buf;
  337.     }
  338.  
  339.   if (__t == __u->tty)
  340.     os_byte (0xe5, 0xff, 0, 0);    /* disable SIGINT */
  341.  
  342. ret:
  343.  
  344.   if (__t->cnt)
  345.     {
  346.       if (__t == __u->tty)
  347.     os_byte (0xe5, 0, 0, 0);    /* re-enable SIGINT */
  348.  
  349.       i = (nbyte > __t->cnt) ? __t->cnt : nbyte;
  350.       memcpy (buf, __t->ptr, i);
  351.       __t->cnt -= i;
  352.       __t->ptr += i;
  353.       return (i);
  354.     }
  355.  
  356.   nflag = (f->oflag & O_NDELAY) ? F_NDELAY : 0;
  357.   iflag = __t->t->c_iflag;
  358.   oflag = __t->t->c_oflag;
  359.   lflag = __t->t->c_lflag;
  360.   cc = (char *) __t->t->c_cc;
  361.  
  362.   ceof = cc[VEOF];
  363.   if (!(ceol = cc[VEOL]))
  364.     ceol--;
  365.   if (!(ceol2 = cc[VEOL2]))
  366.     ceol2--;
  367.  
  368.   s = __t->ptr = __t->buf;
  369.   __t->sx = __t->cx = 0;
  370.   i = 0;
  371.  
  372.   for (;;)
  373.     {
  374.       if (i < MAXPATHLEN)
  375.     nflag &= ~F_MAX;
  376.       else
  377.     nflag |= F_MAX;
  378.       if (nflag & F_NDELAY)
  379.     c = (*(__t->scan)) (0);
  380.       else
  381.     c = (*(__t->in)) ();
  382.       if (c < 0)
  383.     goto eol;
  384.       if (c == '\r' && iflag & IGNCR)
  385.     continue;
  386.       c = __ttyinput (c, iflag);
  387.       if (!(nflag & F_LNEXT))
  388.     {
  389.       if (c == '\n' || c == ceof || c == ceol || c == ceol2)
  390.         goto eol;
  391.       if (c == cc[VLNEXT])
  392.         {
  393.           nflag |= F_LNEXT;
  394.           continue;
  395.         }
  396.       if (c == cc[VERASE])
  397.         {
  398.           if (i)
  399.         {
  400.           __ttydel (lflag);
  401.           i--;
  402.         }
  403.           continue;
  404.         }
  405.       if (c == cc[VWERASE])
  406.         {
  407.           while (--i >= 0 && isspace (s[i]))
  408.         __ttydel (lflag);
  409.           i++;
  410.           while (--i >= 0 && !isspace (s[i]))
  411.         __ttydel (lflag);
  412.           i++;
  413.           continue;
  414.         }
  415.       if (c == cc[VKILL])
  416.         {
  417.           while (--i >= 0)
  418.         __ttydel (lflag);
  419.           i++;
  420.           if (lflag & ECHOK)
  421.         __ttynl (oflag);
  422.           continue;
  423.         }
  424.       if (c == cc[VREPRINT])
  425.         {
  426.           register int j;
  427.           __ttyecho (c, oflag, lflag);
  428.           __ttynl (oflag);
  429.           if (!(oflag & ONLRET))
  430.         __ttycr (oflag);
  431.           for (j = 0; j < i; j++)
  432.         __ttyecho (s[j], oflag, lflag);
  433.           continue;
  434.         }
  435.       if (lflag & ISIG)
  436.         {
  437.           if (c == cc[VINTR])
  438.         {
  439.           raise (SIGINT);
  440.           continue;
  441.         }
  442.           if (c == cc[VQUIT])
  443.         {
  444.           raise (SIGQUIT);
  445.           continue;
  446.         }
  447.         }
  448.     }
  449.       else
  450.     nflag &= ~F_LNEXT;
  451.       if (nflag & F_MAX)
  452.     {
  453.       if (iflag & IMAXBEL)
  454.         (*(__t->out)) ('\007');
  455.     }
  456.       else
  457.     {
  458.       __ttyecho (c, oflag, lflag);
  459.       s[i++] = c;
  460.     }
  461.     }
  462.  
  463. eol:
  464.  
  465.   if (c != cc[VEOF] && c >= 0)
  466.     {
  467.       if (!(nflag & F_MAX))
  468.     {
  469.       __ttyecho (c, oflag, lflag);
  470.       s[i++] = c;
  471.     }
  472.     }
  473.  
  474.   if (__t->cnt = i)
  475.     goto ret;
  476.   else
  477.     {
  478.       if (__t == __u->tty)
  479.     os_byte (0xe5, 0, 0, 0);    /* re-enable SIGINT */
  480.  
  481.       return (0);
  482.     }
  483.  
  484. #undef F_LNEXT
  485. #undef F_MAX
  486. #undef F_NDELAY
  487. }
  488.  
  489. static int
  490. __ttyiraw (void *buf, register int nbyte, struct file *f)
  491. {
  492.   register int c, i;
  493.   register char *s;
  494.   register int nflag;
  495.   register int iflag, oflag, lflag;
  496.   register char *cc;
  497.   register unsigned int vm, vt;
  498.  
  499. #define F_NSCAN     000001
  500.  
  501.   nflag = 0;
  502.   iflag = __t->t->c_iflag;
  503.   oflag = __t->t->c_oflag;
  504.   lflag = __t->t->c_lflag;
  505.   cc = (char *) __t->t->c_cc;
  506.  
  507.   if (f->oflag & O_NDELAY)
  508.     vm = vt = 0;
  509.   else
  510.     {
  511.       vm = (cc[VMIN] && cc[VTIME]) ? 1 : cc[VMIN];
  512.       vt = cc[VTIME] * 10;
  513.     }
  514.   if (cc[VMIN] && !cc[VTIME])
  515.     nbyte = vm, nflag |= F_NSCAN;
  516.  
  517.   s = buf;
  518.   i = 0;
  519.  
  520.   while (i < nbyte)
  521.     {
  522.       if (nflag & F_NSCAN)
  523.     c = (*(__t->in)) ();
  524.       else
  525.     c = (*(__t->scan)) (vt);
  526.       if (c < 0)
  527.     {
  528.       if (i >= vm)
  529.         return (i);
  530.       else
  531.         continue;
  532.     }
  533.       if (c == '\r' && iflag & IGNCR)
  534.     continue;
  535.       c = __ttyinput (c, iflag);
  536.       if (lflag & ISIG)
  537.     {
  538.       if (c == cc[VINTR] && __t != __u->tty)
  539.         {
  540.           raise (SIGINT);
  541.           continue;
  542.         }
  543.       if (c == cc[VQUIT])
  544.         {
  545.           raise (SIGQUIT);
  546.           continue;
  547.         }
  548.     }
  549.       __ttyecho (c, oflag, lflag);
  550.       s[i++] = c;
  551.     }
  552.  
  553.   return (i);
  554.  
  555. #undef F_NSCAN
  556. }
  557.  
  558.  
  559. int
  560. __ttywrite (int l, void *buf, int nbyte, struct file *f)
  561. {
  562.   register int i, c;
  563.   register char *s;
  564.   register int oflag, lflag;
  565.   register char *cc;
  566.   register int (*out) (int);
  567.  
  568.   f = f;
  569.  
  570.   __t = __u->tty + l;
  571.  
  572.   if (!__t->del)
  573.     if (!(__t->del = malloc (MAXPATHLEN)))
  574.       {
  575.     errno = ENOMEM;
  576.     return (-1);
  577.       }
  578.  
  579.   oflag = __t->t->c_oflag;
  580.   lflag = __t->t->c_lflag;
  581.   cc = (char *) __t->t->c_cc;
  582.   out = __t->out;
  583.  
  584.   s = buf;
  585.   i = 0;
  586.  
  587.   while (i < nbyte)
  588.     {
  589.       c = s[i++];
  590.       if ((oflag & (OPOST | OLCUC)) == (OPOST | OLCUC))
  591.     if (isupper (c))
  592.       c = _tolower (c);
  593.       if (c == cc[VERASE])
  594.     __ttydel (lflag);
  595.       else if (c == '\t')
  596.     __ttytab (oflag);
  597.       else if (c == '\n')
  598.     __ttynl (oflag);
  599.       else if (c == '\r')
  600.     __ttycr (oflag);
  601.       else
  602.     {
  603.       __ttyx (1);
  604.       (*out) (c);
  605.     }
  606.     }
  607.  
  608.   return (nbyte);
  609. }
  610.  
  611.  
  612. static int
  613. __ttyinput (register int c, register int iflag)
  614. {
  615.   if (iflag & ISTRIP)
  616.     c &= 0x7f;
  617.   if (iflag & IUCLC)
  618.     if (isupper (c))
  619.       c += ('a' - 'A');
  620.   if (iflag & INLCR)
  621.     if (c == '\n')
  622.       c = '\r';
  623.   if (iflag & ICRNL)
  624.     if (c == '\r')
  625.       c = '\n';
  626.   return (c);
  627. }
  628.  
  629. static void
  630. __ttyecho (register int c, register int oflag, register int lflag)
  631. {
  632.   if (!((lflag & ECHO) || ((c == '\n') && (lflag & ECHONL))))
  633.     return;
  634.  
  635.   if (c == '\t')
  636.     __ttytab (oflag);
  637.   else if (c == '\n')
  638.     __ttynl (oflag);
  639.   else if (c == '\r')
  640.     __ttycr (oflag);
  641.   else if (iscntrl (c))
  642.     {
  643.       __ttyx (2);
  644.       (*(__t->out)) ('^');
  645.       (*(__t->out)) ((c == 0x7f) ? '?' : (c + '@'));
  646.     }
  647.   else
  648.     {
  649.       __ttyx (1);
  650.       (*(__t->out)) (c);
  651.     }
  652. }
  653.  
  654. static void
  655. __ttydel (register int lflag)
  656. {
  657.   register int x;
  658.  
  659.   if (__t->sx)
  660.     {
  661.       x = __t->del[__t->cx];
  662.       __t->cx = (__t->cx - 1) & (MAXPATHLEN - 1);
  663.     }
  664.   else
  665.     x = 1;
  666.  
  667.   __t->sx = (__t->sx > x) ? (__t->sx - x) : 0;
  668.  
  669.   if (lflag & ECHO)
  670.     {
  671.       if (lflag & ECHOE)
  672.     while (x--)
  673.       {
  674.         (*(__t->out)) ('\b');
  675.         (*(__t->out)) (' ');
  676.         (*(__t->out)) ('\b');
  677.       }
  678.       else
  679.     while (x--)
  680.       (*(__t->out)) ('\177');
  681.     }
  682. }
  683.  
  684. static void
  685. __ttytab (register int oflag)
  686. {
  687.   if ((oflag & (OPOST | XTABS)) == (OPOST | XTABS))
  688.     {
  689.       register int x;
  690.  
  691.       x = (8 - (__t->sx & 0x7));
  692.       __ttyx (x);
  693.       while (x--)
  694.     (*(__t->out)) (' ');
  695.     }
  696.   else
  697.     {
  698.       __ttyx (1);
  699.       (*(__t->out)) ('\t');
  700.     }
  701. }
  702.  
  703. static void
  704. __ttycr (register int oflag)
  705. {
  706.   __t->sx = 0;
  707.   if ((oflag & (OPOST | OCRNL)) == (OPOST | OCRNL))
  708.     (*(__t->out)) ('\n');
  709.   else if ((oflag & (OPOST | ONOCR)) != (OPOST | ONOCR))
  710.     (*(__t->out)) ('\r');
  711. }
  712.  
  713. static void
  714. __ttynl (register int oflag)
  715. {
  716.   if (oflag & OPOST)
  717.     {
  718.       if (oflag & ONLCR)
  719.     if (__t->sx || !(oflag & ONOCR))
  720.       (*(__t->out)) ('\r');
  721.       if (oflag & (ONLCR | ONLRET))
  722.     __t->sx = 0;
  723.     }
  724.   (*(__t->out)) ('\n');
  725. }
  726.  
  727.  
  728. long
  729. __ttylseek (int l, long lpos, int whence, struct file *f)
  730. {
  731.   l = l;
  732.   lpos = lpos;
  733.   whence = whence;
  734.   f = f;
  735.   errno = ESPIPE;
  736.   return (-1);
  737. }
  738.  
  739.  
  740. int
  741. __ttyioctl (int l, int request, void *arg, struct file *f)
  742. {
  743.   register struct tty *_t = __u->tty + l;
  744.  
  745.   f = f;
  746.  
  747.   if (request == TIOCGWINSZ || request == TIOCSWINSZ)
  748.     {
  749.       register struct winsize *w = _t->w;
  750.  
  751.       if (request == TIOCGWINSZ)
  752.     {
  753.       if (l == TTY_CON)
  754.         __tty_console_gwinsz (w);
  755.       memcpy (arg, w, sizeof (struct winsize));
  756.     }
  757.       else
  758.     {
  759.       memcpy (w, arg, sizeof (struct winsize));
  760.       if (l == TTY_CON)
  761.         __tty_console_swinsz (w);
  762.     }
  763.     }
  764.   else
  765.     {
  766.       register struct termio *t = _t->t;
  767.  
  768.       if (request & TCDRAIN)
  769.     {
  770.       _t->ptr = _t->buf;
  771.       _t->cnt = 0;
  772.       (*(_t->flush)) ();
  773.     }
  774.  
  775.       switch (request & ~TCDRAIN)
  776.     {
  777.     case TCGETA:
  778.       if (l == TTY_CON)
  779.         __tty_console_gterm (t);
  780.       memcpy (arg, t, sizeof (struct termio));
  781.       break;
  782.     case TCSETA:
  783.       memcpy (t, arg, sizeof (struct termio));
  784.       if (l == TTY_CON)
  785.         __tty_console_sterm (t);
  786.       else if (l == TTY_423)
  787.         __tty_423_sterm (t);
  788.       break;
  789.     case TCSBRK:
  790.       if (l == TTY_423 && !arg)
  791.         os_423break (25);
  792.       break;
  793.     case 0:
  794.       break;
  795.     default:
  796.       errno = EINVAL;
  797.       return (-1);
  798.       break;
  799.     }
  800.     }
  801.  
  802.   return (0);
  803. }
  804.