home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / microcode / uxterm.c < prev    next >
C/C++ Source or Header  |  2000-12-05  |  22KB  |  881 lines

  1. /* -*-C-*-
  2.  
  3. $Id: uxterm.c,v 1.28 2000/12/05 21:23:49 cph Exp $
  4.  
  5. Copyright (c) 1990-2000 Massachusetts Institute of Technology
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include "ux.h"
  23. #include "uxterm.h"
  24. #include "uxio.h"
  25. #include "ospty.h"
  26. #include "prims.h"
  27.  
  28. extern long EXFUN (arg_nonnegative_integer, (int));
  29. extern long EXFUN (arg_index_integer, (int, long));
  30.  
  31. #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
  32. #  ifndef ISTRIP
  33. #    define ISTRIP 0
  34. #  endif
  35. #  ifndef CS8
  36. #    define CS8 0
  37. #  endif
  38. #  ifndef PARENB
  39. #    define PARENB 0
  40. #  endif
  41. #  define TIO(s) (& ((s) -> tio))
  42. #else
  43. #  ifdef HAVE_SGTTY_H
  44. /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits.  */
  45. #    ifndef LPASS8
  46. #      define LPASS8 0
  47. #    endif
  48. #  endif /* HAVE_SGTTY_H */
  49. #endif /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
  50.  
  51. struct terminal_state
  52. {
  53.   int buffer;
  54.   Ttty_state state;
  55. };
  56.  
  57. static struct terminal_state * terminal_table;
  58. #define TERMINAL_BUFFER(channel) ((terminal_table[(channel)]) . buffer)
  59. #define TERMINAL_ORIGINAL_STATE(channel) ((terminal_table[(channel)]) . state)
  60.  
  61. void
  62. DEFUN_VOID (UX_initialize_terminals)
  63. {
  64.   terminal_table =
  65.     (UX_malloc (OS_channel_table_size * (sizeof (struct terminal_state))));
  66.   if (terminal_table == 0)
  67.     {
  68.       fprintf (stderr, "\nUnable to allocate terminal table.\n");
  69.       fflush (stderr);
  70.       termination_init_error ();
  71.     }
  72. }
  73.  
  74. void
  75. DEFUN_VOID (UX_reset_terminals)
  76. {
  77.   UX_free (terminal_table);
  78.   terminal_table = 0;
  79. }
  80.  
  81. /* This is called from the file-opening code. */
  82. void
  83. DEFUN (terminal_open, (channel), Tchannel channel)
  84. {
  85.   (TERMINAL_BUFFER (channel)) = (-1);
  86.   get_terminal_state (channel, (& (TERMINAL_ORIGINAL_STATE (channel))));
  87. }
  88.  
  89. void
  90. DEFUN (get_terminal_state, (channel, s), Tchannel channel AND Ttty_state * s)
  91. {
  92.   STD_VOID_SYSTEM_CALL
  93.     (syscall_terminal_get_state,
  94.      (UX_terminal_get_state ((CHANNEL_DESCRIPTOR (channel)), s)));
  95. }
  96.  
  97. void
  98. DEFUN (set_terminal_state, (channel, s), Tchannel channel AND Ttty_state * s)
  99. {
  100.   extern int EXFUN (UX_terminal_control_ok, (int fd));
  101.   if (UX_terminal_control_ok (CHANNEL_DESCRIPTOR (channel)))
  102.     STD_VOID_SYSTEM_CALL
  103.       (syscall_terminal_set_state,
  104.        (UX_terminal_set_state ((CHANNEL_DESCRIPTOR (channel)), s)));
  105. }
  106.  
  107. unsigned int
  108. DEFUN (terminal_state_get_ospeed, (s), Ttty_state * s)
  109. {
  110. #ifdef HAVE_TERMIOS_H
  111.   return (cfgetospeed (TIO (s)));
  112. #else
  113. #ifdef HAVE_TERMIO_H
  114.   return (((TIO (s)) -> c_cflag) & CBAUD);
  115. #else
  116. #ifdef HAVE_SGTTY_H
  117.   return (s -> sg . sg_ospeed);
  118. #endif /* HAVE_SGTTY_H */
  119. #endif /* not HAVE_TERMIO_H */
  120. #endif /* not HAVE_TERMIOS_H */
  121. }
  122.  
  123. unsigned int
  124. DEFUN (terminal_state_get_ispeed, (s), Ttty_state * s)
  125. {
  126. #ifdef HAVE_TERMIOS_H
  127.   return (cfgetispeed (TIO (s)));
  128. #else
  129. #ifdef HAVE_TERMIO_H
  130.   return (((TIO (s)) -> c_cflag) & CBAUD);
  131. #else
  132. #ifdef HAVE_SGTTY_H
  133.   return (s -> sg . sg_ispeed);
  134. #endif /* HAVE_SGTTY_H */
  135. #endif /* not HAVE_TERMIO_H */
  136. #endif /* not HAVE_TERMIOS_H */
  137. }
  138.  
  139. void
  140. DEFUN (terminal_state_set_ospeed, (s, b),
  141.        Ttty_state * s AND
  142.        unsigned int b)
  143. {
  144. #ifdef HAVE_TERMIOS_H
  145.   cfsetospeed ((TIO (s)), b);
  146. #else
  147. #ifdef HAVE_TERMIO_H
  148.   ((TIO (s)) -> c_cflag) = ((((TIO (s)) -> c_cflag) &~ CBAUD) | b);
  149. #else
  150. #ifdef HAVE_SGTTY_H
  151.   (s -> sg . sg_ospeed) = b;
  152. #endif /* HAVE_SGTTY_H */
  153. #endif /* not HAVE_TERMIO_H */
  154. #endif /* not HAVE_TERMIOS_H */
  155. }
  156.  
  157. void
  158. DEFUN (terminal_state_set_ispeed, (s, b),
  159.        Ttty_state * s AND
  160.        unsigned int b)
  161. {
  162. #ifdef HAVE_TERMIOS_H
  163.   cfsetispeed ((TIO (s)), b);
  164. #else
  165. #ifdef HAVE_TERMIO_H
  166.   ((TIO (s)) -> c_cflag) =
  167.     ((((TIO (s)) -> c_cflag) &~ CIBAUD) | (b << IBSHIFT));
  168. #else
  169. #ifdef HAVE_SGTTY_H
  170.   (s -> sg . sg_ispeed) = b;
  171. #endif /* HAVE_SGTTY_H */
  172. #endif /* not HAVE_TERMIO_H */
  173. #endif /* not HAVE_TERMIOS_H */
  174. }
  175.  
  176. int
  177. DEFUN (terminal_state_cooked_output_p, (s), Ttty_state * s)
  178. {
  179. #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
  180.   return ((((TIO (s)) -> c_oflag) & OPOST) != 0);
  181. #else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
  182. #ifdef HAVE_SGTTY_H
  183.   return (((s -> sg . sg_flags) & LLITOUT) == 0);
  184. #endif /* HAVE_SGTTY_H */
  185. #endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
  186. }
  187.  
  188. void
  189. DEFUN (terminal_state_raw_output, (s), Ttty_state * s)
  190. {
  191. #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
  192.   ((TIO (s)) -> c_oflag) &=~ OPOST;
  193. #else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
  194. #ifdef HAVE_SGTTY_H
  195.   (s -> sg . sg_flags) &=~ ALLDELAY;
  196.   (s -> lmode) |= LLITOUT;
  197. #endif /* HAVE_SGTTY_H */
  198. #endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
  199. }
  200.  
  201. void
  202. DEFUN (terminal_state_cooked_output, (s, channel),
  203.        Ttty_state * s AND Tchannel channel)
  204. {
  205.   Ttty_state * os = (& (TERMINAL_ORIGINAL_STATE (channel)));
  206. #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
  207.   ((TIO (s)) -> c_oflag) |= (((TIO (os)) -> c_oflag) & OPOST);
  208. #else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
  209. #ifdef HAVE_SGTTY_H
  210.   (s -> sg . sg_flags) =
  211.     (((s -> sg . sg_flags) &~ ALLDELAY) | ((os -> sg . sg_flags) & ALLDELAY));
  212.   (s -> lmode) &=~ ((os -> lmode) & LLITOUT);
  213. #endif /* HAVE_SGTTY_H */
  214. #endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
  215. }
  216.  
  217. int
  218. DEFUN (terminal_state_buffered_p, (s), Ttty_state * s)
  219. {
  220. #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
  221.   return ((((TIO (s)) -> c_lflag) & ICANON) != 0);
  222. #else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
  223. #ifdef HAVE_SGTTY_H
  224.   return (((s -> sg . sg_flags) & (CBREAK | RAW)) == 0);
  225. #endif /* HAVE_SGTTY_H */
  226. #endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
  227. }
  228.  
  229. void
  230. DEFUN (terminal_state_nonbuffered, (s, fd, polling),
  231.        Ttty_state * s AND
  232.        int fd AND
  233.        int polling)
  234. {
  235. #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
  236.  
  237.   ((TIO (s)) -> c_lflag) &=~ (ICANON | ECHO);
  238. #ifdef IEXTEN
  239.   ((TIO (s)) -> c_lflag) &=~ IEXTEN;
  240. #endif
  241.   ((TIO (s)) -> c_lflag) |= ISIG;
  242.   ((TIO (s)) -> c_iflag) |= IGNBRK;
  243.   ((TIO (s)) -> c_iflag) &=~ (ICRNL | IXON | ISTRIP);
  244.   ((TIO (s)) -> c_cflag) |= CS8;
  245.   ((TIO (s)) -> c_cflag) &=~ PARENB;
  246.   (((TIO (s)) -> c_cc) [VMIN]) = (polling ? 0 : 1);
  247.   (((TIO (s)) -> c_cc) [VTIME]) = 0;
  248. #ifdef HAVE_TERMIOS_H
  249.   {
  250.     cc_t disable = (UX_PC_VDISABLE (fd));
  251.     (((TIO (s)) -> c_cc) [VSTOP]) = disable;
  252.     (((TIO (s)) -> c_cc) [VSTART]) = disable;
  253.   }
  254. #endif
  255.  
  256. #else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
  257. #ifdef HAVE_SGTTY_H
  258.  
  259.   (s -> sg . sg_flags) &=~ (ECHO | CRMOD);
  260.   (s -> sg . sg_flags) |= (ANYP | CBREAK);
  261.   (s -> lmode) |= (LPASS8 | LNOFLSH);
  262.   (s -> tc . t_startc) = (-1);
  263.   (s -> tc . t_stopc) = (-1);
  264.   (s -> tc . t_eofc) = (-1);
  265.   (s -> tc . t_brkc) = (-1);
  266. #ifdef HAVE_STRUCT_LTCHARS
  267.   (s -> ltc . t_rprntc) = (-1);
  268.   (s -> ltc . t_flushc) = (-1);
  269.   (s -> ltc . t_werasc) = (-1);
  270.   (s -> ltc . t_lnextc) = (-1);
  271. #endif /* HAVE_STRUCT_LTCHARS */
  272.  
  273. #endif /* HAVE_SGTTY_H */
  274. #endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
  275. }
  276.  
  277. void
  278. DEFUN (terminal_state_raw, (s, fd), Ttty_state * s AND int fd)
  279. {
  280.   terminal_state_nonbuffered (s, fd, 0);
  281.  
  282. #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
  283.  
  284.   ((TIO (s)) -> c_lflag) &=~ ISIG;
  285.  
  286. #else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
  287. #ifdef HAVE_SGTTY_H
  288.  
  289.   (s -> sg . sg_flags) &=~ CBREAK;
  290.   (s -> sg . sg_flags) |= RAW;
  291.   (s -> tc . t_intrc) = (-1);
  292.   (s -> tc . t_quitc) = (-1);
  293. #ifdef HAVE_STRUCT_LTCHARS
  294.   (s -> ltc . t_suspc) = (-1);
  295.   (s -> ltc . t_dsuspc) = (-1);
  296. #endif /* HAVE_STRUCT_LTCHARS */
  297.  
  298. #endif /* HAVE_SGTTY_H */
  299. #endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
  300. }
  301.  
  302. void
  303. DEFUN (terminal_state_buffered, (s, channel),
  304.        Ttty_state * s AND
  305.        Tchannel channel)
  306. {
  307.   Ttty_state * os = (& (TERMINAL_ORIGINAL_STATE (channel)));
  308.  
  309. #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
  310.  
  311.   ((TIO (s)) -> c_lflag) |= (ICANON | ISIG);
  312.   ((TIO (s)) -> c_lflag) |= (((TIO (os)) -> c_lflag) & ECHO);
  313. #ifdef IEXTEN
  314.   ((TIO (s)) -> c_lflag) |= (((TIO (os)) -> c_lflag) & IEXTEN);
  315. #endif
  316.   ((TIO (s)) -> c_iflag) = ((TIO (os)) -> c_iflag);
  317.   ((TIO (s)) -> c_cflag) |= CS8;
  318.   ((TIO (s)) -> c_cflag) &=~ PARENB;
  319.   (((TIO (s)) -> c_cc) [VMIN]) = (((TIO (os)) -> c_cc) [VMIN]);
  320.   (((TIO (s)) -> c_cc) [VTIME]) = (((TIO (os)) -> c_cc) [VTIME]);
  321. #ifdef HAVE_TERMIOS_H
  322.   (((TIO (s)) -> c_cc) [VSTOP]) = (((TIO (os)) -> c_cc) [VSTOP]);
  323.   (((TIO (s)) -> c_cc) [VSTART]) = (((TIO (os)) -> c_cc) [VSTART]);
  324. #endif
  325.  
  326. #else /* not HAVE_TERMIOS_H nor HAVE_TERMIO_H */
  327. #ifdef HAVE_SGTTY_H
  328.  
  329.   (s -> sg . sg_flags) &=~ (CBREAK | RAW);
  330.   (s -> sg . sg_flags) |= ANYP;
  331.   (s -> sg . sg_flags) |= ((os -> sg . sg_flags) & (ECHO | CRMOD));
  332.   (s -> lmode) &=~ LNOFLSH;
  333.   (s -> lmode) |= LPASS8;
  334.   (s -> tc . t_intrc) = (os -> tc . t_intrc);
  335.   (s -> tc . t_quitc) = (os -> tc . t_quitc);
  336.   (s -> tc . t_startc) = (os -> tc . t_startc);
  337.   (s -> tc . t_stopc) = (os -> tc . t_stopc);
  338.   (s -> tc . t_eofc) = (os -> tc . t_eofc);
  339.   (s -> tc . t_brkc) = (os -> tc . t_brkc);
  340. #ifdef HAVE_STRUCT_LTCHARS
  341.   (s -> ltc . t_suspc) = (os -> ltc . t_suspc);
  342.   (s -> ltc . t_dsuspc) = (os -> ltc . t_dsuspc);
  343.   (s -> ltc . t_rprntc) = (os -> ltc . t_rprntc);
  344.   (s -> ltc . t_flushc) = (os -> ltc . t_flushc);
  345.   (s -> ltc . t_werasc) = (os -> ltc . t_werasc);
  346.   (s -> ltc . t_lnextc) = (os -> ltc . t_lnextc);
  347. #endif /* HAVE_STRUCT_LTCHARS */
  348.  
  349. #endif /* HAVE_SGTTY_H */
  350. #endif /* HAVE_TERMIOS_H or HAVE_TERMIO_H */
  351. }
  352.  
  353. unsigned int
  354. DEFUN (OS_terminal_get_ispeed, (channel), Tchannel channel)
  355. {
  356.   Ttty_state s;
  357.   get_terminal_state (channel, (&s));
  358.   return (terminal_state_get_ispeed (&s));
  359. }
  360.  
  361. unsigned int
  362. DEFUN (OS_terminal_get_ospeed, (channel), Tchannel channel)
  363. {
  364.   Ttty_state s;
  365.   get_terminal_state (channel, (&s));
  366.   return (terminal_state_get_ospeed (&s));
  367. }
  368.  
  369. void
  370. DEFUN (OS_terminal_set_ispeed, (channel, baud),
  371.        Tchannel channel AND
  372.        unsigned int baud)
  373. {
  374.   Ttty_state s;
  375.   get_terminal_state (channel, (&s));
  376.   terminal_state_set_ispeed ((&s), baud);
  377.   set_terminal_state (channel, (&s));
  378. }
  379.  
  380. void
  381. DEFUN (OS_terminal_set_ospeed, (channel, baud),
  382.        Tchannel channel AND
  383.        unsigned int baud)
  384. {
  385.   Ttty_state s;
  386.   get_terminal_state (channel, (&s));
  387.   terminal_state_set_ospeed ((&s), baud);
  388.   set_terminal_state (channel, (&s));
  389. }
  390.  
  391. unsigned int
  392. DEFUN (arg_baud_index, (argument), unsigned int argument)
  393. {
  394.   unsigned long index = (arg_nonnegative_integer (argument));
  395.   switch (index)
  396.     {
  397.     case B0:
  398.     case B50:
  399.     case B75:
  400.     case B110:
  401.     case B134:
  402.     case B150:
  403.     case B200:
  404.     case B300:
  405.     case B600:
  406.     case B1200:
  407.     case B1800:
  408.     case B2400:
  409.     case B4800:
  410.     case B9600:
  411.     case B19200:
  412.     case B38400:
  413. #ifdef B57600
  414.     case B57600:
  415. #endif
  416. #ifdef B115200
  417.     case B115200:
  418. #endif
  419. #ifdef B230400
  420.     case B230400:
  421. #endif
  422. #ifdef B460800
  423.     case B460800:
  424. #endif
  425. #ifdef B500000
  426.     case B500000:
  427. #endif
  428. #ifdef B576000
  429.     case B576000:
  430. #endif
  431. #ifdef B921600
  432.     case B921600:
  433. #endif
  434. #ifdef B1000000
  435.     case B1000000:
  436. #endif
  437. #ifdef B1152000
  438.     case B1152000:
  439. #endif
  440. #ifdef B1500000
  441.     case B1500000:
  442. #endif
  443. #ifdef B2000000
  444.     case B2000000:
  445. #endif
  446. #ifdef B2500000
  447.     case B2500000:
  448. #endif
  449. #ifdef B3000000
  450.     case B3000000:
  451. #endif
  452. #ifdef B3500000
  453.     case B3500000:
  454. #endif
  455. #ifdef B4000000
  456.     case B4000000:
  457. #endif
  458.       break;
  459.     default:
  460.       error_bad_range_arg (argument);
  461.     }
  462.   return (index);
  463. }
  464.  
  465. unsigned int
  466. DEFUN (OS_baud_index_to_rate, (index), unsigned int index)
  467. {
  468.   switch (index)
  469.     {
  470.     case B0:        return (0);
  471.     case B50:        return (50);
  472.     case B75:        return (75);
  473.     case B110:        return (110);
  474.     case B134:        return (134);
  475.     case B150:        return (150);
  476.     case B200:        return (200);
  477.     case B300:        return (300);
  478.     case B600:        return (600);
  479.     case B1200:        return (1200);
  480.     case B1800:        return (1800);
  481.     case B2400:        return (2400);
  482.     case B4800:        return (4800);
  483.     case B9600:        return (9600);
  484.     case B19200:    return (19200);
  485.     case B38400:    return (38400);
  486. #ifdef B57600
  487.     case B57600:    return (57600);
  488. #endif
  489. #ifdef B115200
  490.     case B115200:    return (115200);
  491. #endif
  492. #ifdef B230400
  493.     case B230400:    return (230400);
  494. #endif
  495. #ifdef B460800
  496.     case B460800:    return (460800);
  497. #endif
  498. #ifdef B500000
  499.     case B500000:    return (500000);
  500. #endif
  501. #ifdef B576000
  502.     case B576000:    return (576000);
  503. #endif
  504. #ifdef B921600
  505.     case B921600:    return (921600);
  506. #endif
  507. #ifdef B1000000
  508.     case B1000000:    return (1000000);
  509. #endif
  510. #ifdef B1152000
  511.     case B1152000:    return (1152000);
  512. #endif
  513. #ifdef B1500000
  514.     case B1500000:    return (1500000);
  515. #endif
  516. #ifdef B2000000
  517.     case B2000000:    return (2000000);
  518. #endif
  519. #ifdef B2500000
  520.     case B2500000:    return (2500000);
  521. #endif
  522. #ifdef B3000000
  523.     case B3000000:    return (3000000);
  524. #endif
  525. #ifdef B3500000
  526.     case B3500000:    return (3500000);
  527. #endif
  528. #ifdef B4000000
  529.     case B4000000:    return (4000000);
  530. #endif
  531.     default:        abort (); return (0);
  532.     }
  533. }
  534.  
  535. int
  536. DEFUN (OS_baud_rate_to_index, (rate), unsigned int rate)
  537. {
  538.   switch (rate)
  539.     {
  540.     case 0:        return (B0);
  541.     case 50:        return (B50);
  542.     case 75:        return (B75);
  543.     case 110:        return (B110);
  544.     case 134:        return (B134);
  545.     case 150:        return (B150);
  546.     case 200:        return (B200);
  547.     case 300:        return (B300);
  548.     case 600:        return (B600);
  549.     case 1200:        return (B1200);
  550.     case 1800:        return (B1800);
  551.     case 2400:        return (B2400);
  552.     case 4800:        return (B4800);
  553.     case 9600:        return (B9600);
  554.     case 19200:        return (B19200);
  555.     case 38400:        return (B38400);
  556. #ifdef B57600
  557.     case 57600:        return (B57600);
  558. #endif
  559. #ifdef B115200
  560.     case 115200:    return (B115200);
  561. #endif
  562. #ifdef B230400
  563.     case 230400:    return (B230400);
  564. #endif
  565. #ifdef B460800
  566.     case 460800:    return (B460800);
  567. #endif
  568. #ifdef B500000
  569.     case 500000:    return (B500000);
  570. #endif
  571. #ifdef B576000
  572.     case 576000:    return (B576000);
  573. #endif
  574. #ifdef B921600
  575.     case 921600:    return (B921600);
  576. #endif
  577. #ifdef B1000000
  578.     case 1000000:    return (B1000000);
  579. #endif
  580. #ifdef B1152000
  581.     case 1152000:    return (B1152000);
  582. #endif
  583. #ifdef B1500000
  584.     case 1500000:    return (B1500000);
  585. #endif
  586. #ifdef B2000000
  587.     case 2000000:    return (B2000000);
  588. #endif
  589. #ifdef B2500000
  590.     case 2500000:    return (B2500000);
  591. #endif
  592. #ifdef B3000000
  593.     case 3000000:    return (B3000000);
  594. #endif
  595. #ifdef B3500000
  596.     case 3500000:    return (B3500000);
  597. #endif
  598. #ifdef B4000000
  599.     case 4000000:    return (B4000000);
  600. #endif
  601.     default:        return (-1);
  602.     }
  603. }
  604.  
  605. unsigned int
  606. DEFUN_VOID (OS_terminal_state_size)
  607. {
  608.   return (sizeof (Ttty_state));
  609. }
  610.  
  611. void
  612. DEFUN (OS_terminal_get_state, (channel, statep),
  613.        Tchannel channel AND
  614.        PTR statep)
  615. {
  616.   get_terminal_state (channel, statep);
  617. }
  618.  
  619. void
  620. DEFUN (OS_terminal_set_state, (channel, statep),
  621.        Tchannel channel AND
  622.        PTR statep)
  623. {
  624.   set_terminal_state (channel, statep);
  625. }
  626.  
  627. int
  628. DEFUN (OS_terminal_cooked_output_p, (channel), Tchannel channel)
  629. {
  630.   Ttty_state s;
  631.   get_terminal_state (channel, (&s));
  632.   return (terminal_state_cooked_output_p (&s));
  633. }
  634.  
  635. void
  636. DEFUN (OS_terminal_raw_output, (channel), Tchannel channel)
  637. {
  638.   Ttty_state s;
  639.   get_terminal_state (channel, (&s));
  640.   terminal_state_raw_output (&s);
  641.   set_terminal_state (channel, (&s));
  642. }
  643.  
  644. void
  645. DEFUN (OS_terminal_cooked_output, (channel), Tchannel channel)
  646. {
  647.   Ttty_state s;
  648.   get_terminal_state (channel, (&s));
  649.   terminal_state_cooked_output ((&s), channel);
  650.   set_terminal_state (channel, (&s));
  651. }
  652.  
  653. int
  654. DEFUN (OS_terminal_buffered_p, (channel), Tchannel channel)
  655. {
  656.   Ttty_state s;
  657.   get_terminal_state (channel, (&s));
  658.   return (terminal_state_buffered_p (&s));
  659. }
  660.  
  661. void
  662. DEFUN (OS_terminal_buffered, (channel), Tchannel channel)
  663. {
  664.   Ttty_state s;
  665.   get_terminal_state (channel, (&s));
  666.   terminal_state_buffered ((&s), channel);
  667.   set_terminal_state (channel, (&s));
  668. }
  669.  
  670. void
  671. DEFUN (OS_terminal_nonbuffered, (channel), Tchannel channel)
  672. {
  673.   Ttty_state s;
  674.   get_terminal_state (channel, (&s));
  675.   terminal_state_nonbuffered ((&s), (CHANNEL_DESCRIPTOR (channel)), 0);
  676.   set_terminal_state (channel, (&s));
  677. }
  678.  
  679. void
  680. DEFUN (OS_terminal_flush_input, (channel), Tchannel channel)
  681. {
  682.   STD_VOID_SYSTEM_CALL
  683.     (syscall_tcflush, (UX_tcflush ((CHANNEL_DESCRIPTOR (channel)), TCIFLUSH)));
  684. }
  685.  
  686. void
  687. DEFUN (OS_terminal_flush_output, (channel), Tchannel channel)
  688. {
  689.   STD_VOID_SYSTEM_CALL
  690.     (syscall_tcflush, (UX_tcflush ((CHANNEL_DESCRIPTOR (channel)), TCOFLUSH)));
  691. }
  692.  
  693. void
  694. DEFUN (OS_terminal_drain_output, (channel), Tchannel channel)
  695. {
  696.   STD_VOID_SYSTEM_CALL
  697.     (syscall_tcdrain, (UX_tcdrain (CHANNEL_DESCRIPTOR (channel))));
  698. }
  699.  
  700. int
  701. DEFUN_VOID (OS_job_control_p)
  702. {
  703.   return (UX_SC_JOB_CONTROL ());
  704. }
  705.  
  706. int
  707. DEFUN_VOID (OS_have_ptys_p)
  708. {
  709. #ifdef HAVE_GRANTPT
  710.   return (1);
  711. #else
  712.   static int result = 0;
  713.   static int result_valid = 0;
  714.   const char * p1;
  715.   if (result_valid)
  716.     return (result);
  717.   for (p1 = "pqrstuvwxyzPQRST"; ((*p1) != 0); p1 += 1)
  718.     {
  719.       char master_name [24];
  720.       struct stat s;
  721.       sprintf (master_name, "/dev/pty%c0", (*p1));
  722.     retry_stat:
  723.       if ((UX_stat (master_name, (&s))) < 0)
  724.     {
  725.       if (errno == EINTR)
  726.         goto retry_stat;
  727.       continue;
  728.     }
  729.       result = 1;
  730.       result_valid = 1;
  731.       return (result);
  732.     }
  733.   result = 0;
  734.   result_valid = 1;
  735.   return (result);
  736. #endif
  737. }
  738.  
  739. static CONST char *
  740. DEFUN (open_pty_master_bsd, (master_fd, master_fname),
  741.        Tchannel * master_fd AND
  742.        CONST char ** master_fname)
  743. {
  744.   static char master_name [24];
  745.   static char slave_name [24];
  746.   const char * p1;
  747.   const char * p2;
  748.   int fd;
  749.  
  750.   for (p1 = "pqrstuvwxyzPQRST"; ((*p1) != 0); p1 += 1)
  751.     for (p2 = "0123456789abcdef"; ((*p2) != 0); p2 += 1)
  752.       {
  753.     sprintf (master_name, "/dev/pty%c%c", (*p1), (*p2));
  754.     sprintf (slave_name, "/dev/tty%c%c", (*p1), (*p2));
  755.       retry_open:
  756.     fd = (UX_open (master_name, O_RDWR, 0));
  757.     if (fd < 0)
  758.       {
  759.         if (errno == ENOENT)
  760.           return (0);
  761.         if (errno != EINTR)
  762.           continue;
  763.         deliver_pending_interrupts ();
  764.         goto retry_open;
  765.       }
  766.     if ((UX_access (slave_name, (R_OK | W_OK))) < 0)
  767.       {
  768.         UX_close (fd);
  769.         continue;
  770.       }
  771.     MAKE_CHANNEL (fd, channel_type_unix_pty_master, (*master_fd) =);
  772.     (*master_fname) = master_name;
  773.     return (slave_name);
  774.       }
  775.   return (0);
  776. }
  777.  
  778. /* Open an available pty, putting channel in (*ptyv),
  779.    and return the file name of the pty.
  780.    Signal error if none available.  */
  781.  
  782. CONST char *
  783. DEFUN (OS_open_pty_master, (master_fd, master_fname),
  784.        Tchannel * master_fd AND
  785.        CONST char ** master_fname)
  786. {
  787. #ifdef HAVE_GRANTPT
  788.   while (1)
  789.     {
  790.       static char slave_name [24];
  791.       int fd = (UX_open ("/dev/ptmx", O_RDWR, 0));
  792.       if (fd < 0)
  793.     {
  794.       if (errno == EINTR)
  795.         {
  796.           deliver_pending_interrupts ();
  797.           continue;
  798.         }
  799.       /* Try BSD open.  This is needed for Linux which might have
  800.          Unix98 support in the library but not the kernel.  */
  801.       return (open_pty_master_bsd (master_fd, master_fname));
  802.     }
  803. #ifdef sonyrisc
  804.       sony_block_sigchld ();
  805. #endif
  806.       grantpt (fd);
  807.       unlockpt (fd);
  808.       strcpy (slave_name, (ptsname (fd)));
  809. #ifdef sonyrisc
  810.       sony_unblock_sigchld ();
  811. #endif
  812.       MAKE_CHANNEL (fd, channel_type_unix_pty_master, (*master_fd) =);
  813.       (*master_fname) = "/dev/ptmx";
  814.       return (slave_name);
  815.     }
  816.  
  817. #else /* not HAVE_GRANTPT */
  818.  
  819.   if (!OS_have_ptys_p ())
  820.     error_unimplemented_primitive ();
  821.   return (open_pty_master_bsd (master_fd, master_fname));
  822.  
  823. #endif /* not HAVE_GRANTPT */
  824. }
  825.  
  826. void
  827. DEFUN (OS_pty_master_send_signal, (channel, sig), Tchannel channel AND int sig)
  828. {
  829. #ifdef TIOCSIGSEND
  830.   STD_VOID_SYSTEM_CALL
  831.     (syscall_ioctl_TIOCSIGSEND,
  832.      (UX_ioctl ((CHANNEL_DESCRIPTOR (channel)), TIOCSIGSEND, sig)));
  833. #else
  834.   int gid = (UX_tcgetpgrp (CHANNEL_DESCRIPTOR (channel)));
  835.   if (gid < 0)
  836.     {
  837.       if (errno == ENOSYS)
  838.     error_unimplemented_primitive ();
  839.       else
  840.     error_system_call (errno, syscall_tcgetpgrp);
  841.     }
  842.   STD_VOID_SYSTEM_CALL (syscall_kill, (UX_kill ((-gid), sig)));
  843. #endif
  844. }
  845.  
  846. void
  847. DEFUN (OS_pty_master_kill, (channel), Tchannel channel)
  848. {
  849.   OS_pty_master_send_signal (channel, SIGKILL);
  850. }
  851.  
  852. void
  853. DEFUN (OS_pty_master_stop, (channel), Tchannel channel)
  854. {
  855.   OS_pty_master_send_signal (channel, SIGTSTP);
  856. }
  857.  
  858. void
  859. DEFUN (OS_pty_master_continue, (channel), Tchannel channel)
  860. {
  861.   OS_pty_master_send_signal (channel, SIGCONT);
  862. }
  863.  
  864. void
  865. DEFUN (OS_pty_master_interrupt, (channel), Tchannel channel)
  866. {
  867.   OS_pty_master_send_signal (channel, SIGINT);
  868. }
  869.  
  870. void
  871. DEFUN (OS_pty_master_quit, (channel), Tchannel channel)
  872. {
  873.   OS_pty_master_send_signal (channel, SIGQUIT);
  874. }
  875.  
  876. void
  877. DEFUN (OS_pty_master_hangup, (channel), Tchannel channel)
  878. {
  879.   OS_pty_master_send_signal (channel, SIGHUP);
  880. }
  881.