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 / ntio.c < prev    next >
C/C++ Source or Header  |  2001-05-21  |  18KB  |  683 lines

  1. /* -*-C-*-
  2.  
  3. $Id: ntio.c,v 1.24 2001/05/22 02:46:47 cph Exp $
  4.  
  5. Copyright (c) 1992-2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  20. USA.
  21. */
  22.  
  23. #include "scheme.h"
  24. #include "prims.h"
  25. #include "nt.h"
  26. #include "ntio.h"
  27. #include "osterm.h"
  28. #include "osfile.h"
  29. #include "outf.h"
  30. #include "ossig.h"
  31. #include "intrpt.h"
  32. #include "ntscreen.h"
  33.  
  34. #undef TRACE_NTIO
  35. #ifdef TRACE_NTIO
  36. extern FILE * trace_file;
  37. #endif
  38.  
  39. extern HANDLE master_tty_window;
  40.  
  41. channel_class_t * NT_channel_class_generic;
  42. channel_class_t * NT_channel_class_file;
  43. channel_class_t * NT_channel_class_screen;
  44. channel_class_t * NT_channel_class_anonymous_pipe;
  45. channel_class_t * NT_channel_class_named_pipe;
  46.  
  47. static Tchannel channel_allocate (void);
  48. static long cooked_channel_write (Tchannel, const void *, unsigned long) ;
  49.  
  50. #ifndef NT_DEFAULT_CHANNEL_TABLE_SIZE
  51. #define NT_DEFAULT_CHANNEL_TABLE_SIZE 1024
  52. #endif
  53.  
  54. size_t OS_channel_table_size;
  55. struct channel * NT_channel_table;
  56.  
  57. Tchannel
  58. NT_make_channel (HANDLE handle, channel_class_t * class)
  59. {
  60.   Tchannel channel;
  61.   transaction_begin ();
  62.   NT_handle_close_on_abort (handle);
  63.   channel = (channel_allocate ());
  64.   (CHANNEL_CLASS (channel)) = class;
  65.   (CHANNEL_HANDLE (channel)) = handle;
  66.   (CHANNEL_INTERNAL (channel)) = 0;
  67.   (CHANNEL_NONBLOCKING (channel)) = 0;
  68.   (CHANNEL_BUFFERED (channel)) = 1;
  69.   (CHANNEL_COOKED (channel)) = 0;
  70.   transaction_commit ();
  71.   return (channel);
  72. }
  73.  
  74. channel_class_t *
  75. NT_handle_channel_class (HANDLE handle)
  76. {
  77.   if (Screen_IsScreenHandle (handle))
  78.     return (NT_channel_class_screen);
  79.   /* If GetFileType returns FILE_TYPE_PIPE, assume that it is a named
  80.      pipe.  This procedure won't be called with an anonymous-pipe
  81.      handle.  */
  82.   switch (GetFileType (handle))
  83.     {
  84.     case FILE_TYPE_DISK: return (NT_channel_class_file);
  85.     case FILE_TYPE_CHAR: return (NT_channel_class_generic);
  86.     case FILE_TYPE_PIPE: return (NT_channel_class_named_pipe);
  87.     default: return (NT_channel_class_generic);
  88.     }
  89. }
  90.  
  91. Tchannel
  92. NT_open_handle (HANDLE handle)
  93. {
  94.   Tchannel channel
  95.     = (NT_make_channel (handle, (NT_handle_channel_class (handle))));
  96.   /* Like Unix, all terminals initialize to cooked mode.  */
  97.   if ((CHANNEL_TYPE (channel)) == channel_type_terminal)
  98.     (CHANNEL_COOKED (channel)) = 1;
  99.   return (channel);
  100. }
  101.  
  102. long
  103. OS_channel_read (Tchannel channel, void * buffer, size_t n_bytes)
  104. {
  105.   return
  106.     ((n_bytes == 0)
  107.      ? 0
  108.      : ((* (CHANNEL_CLASS_OP_READ (CHANNEL_CLASS (channel))))
  109.     (channel, buffer, n_bytes)));
  110. }
  111.  
  112. long
  113. OS_channel_write (Tchannel channel, const void * buffer, size_t n_bytes)
  114. {
  115.   return
  116.     ((n_bytes == 0)
  117.      ? 0
  118.      : (CHANNEL_COOKED (channel))
  119.      ? (cooked_channel_write (channel, buffer, n_bytes))
  120.      : ((* (CHANNEL_CLASS_OP_WRITE (CHANNEL_CLASS (channel))))
  121.     (channel, buffer, n_bytes)));
  122. }
  123.  
  124. void
  125. OS_channel_close (Tchannel channel)
  126. {
  127.   if (! ((CHANNEL_CLOSED_P (channel)) || (CHANNEL_INTERNAL (channel))))
  128.     {
  129.       (* (CHANNEL_CLASS_OP_CLOSE (CHANNEL_CLASS (channel)))) (channel, 1);
  130.       MARK_CHANNEL_CLOSED (channel);
  131.     }
  132. }
  133.  
  134. void
  135. OS_channel_close_noerror (Tchannel channel)
  136. {
  137.   if (! ((CHANNEL_CLOSED_P (channel)) || (CHANNEL_INTERNAL (channel))))
  138.     {
  139.       (* (CHANNEL_CLASS_OP_CLOSE (CHANNEL_CLASS (channel)))) (channel, 0);
  140.       MARK_CHANNEL_CLOSED (channel);
  141.     }
  142. }
  143.  
  144. long
  145. NT_channel_n_read (Tchannel channel)
  146. {
  147.   if (CHANNEL_CLOSED_P (channel))
  148.     return (0);
  149.   return ((* (CHANNEL_CLASS_OP_N_READ (CHANNEL_CLASS (channel)))) (channel));
  150. }
  151.  
  152. static void
  153. NT_channel_close_all (void)
  154. {
  155.   Tchannel channel;
  156.   for (channel = 0; (channel < OS_channel_table_size); channel += 1)
  157.     if (CHANNEL_OPEN_P (channel))
  158.       OS_channel_close_noerror (channel);
  159. }
  160.  
  161. static Tchannel
  162. channel_allocate (void)
  163. {
  164.   Tchannel channel = 0;
  165.   while (1)
  166.   {
  167.     if (channel == OS_channel_table_size)
  168.       error_out_of_channels ();
  169.     if (CHANNEL_CLOSED_P (channel))
  170.       return (channel);
  171.     channel += 1;
  172.   }
  173. }
  174.  
  175. int
  176. OS_channel_open_p (Tchannel channel)
  177. {
  178.   return (CHANNEL_OPEN_P (channel));
  179. }
  180.  
  181. static void
  182. channel_close_on_abort_1 (void * cp)
  183. {
  184.   OS_channel_close (* ((Tchannel *) cp));
  185. }
  186.  
  187. void
  188. OS_channel_close_on_abort (Tchannel channel)
  189. {
  190.   Tchannel * cp = ((Tchannel *) (dstack_alloc (sizeof (Tchannel))));
  191.   (*cp) = (channel);
  192.   transaction_record_action (tat_abort, channel_close_on_abort_1, cp);
  193. }
  194.  
  195. static void
  196. NT_handle_close_on_abort_1 (void * hp)
  197. {
  198.   (void) CloseHandle (* ((HANDLE *) hp));
  199. }
  200.  
  201. void
  202. NT_handle_close_on_abort (HANDLE h)
  203. {
  204.   HANDLE * hp = (dstack_alloc (sizeof (HANDLE)));
  205.   (*hp) = h;
  206.   transaction_record_action (tat_abort, NT_handle_close_on_abort_1, hp);
  207. }
  208.  
  209. enum channel_type
  210. OS_channel_type (Tchannel channel)
  211. {
  212.   return (CHANNEL_TYPE (channel));
  213. }
  214.  
  215. static void
  216. generic_channel_close (Tchannel channel, int errorp)
  217. {
  218.   if ((!CloseHandle (CHANNEL_HANDLE (channel))) && errorp)
  219.     NT_error_api_call ((GetLastError ()), apicall_CloseHandle);
  220. }
  221.  
  222. static long
  223. generic_channel_read (Tchannel channel, void * buffer, unsigned long n_bytes)
  224. {
  225.   DWORD bytes_read;
  226.   if ((!ReadFile ((CHANNEL_HANDLE (channel)),
  227.           buffer, n_bytes, (&bytes_read), 0))
  228.       && (bytes_read > 0))
  229.     NT_error_api_call ((GetLastError ()), apicall_ReadFile);
  230.   return (bytes_read);
  231. }
  232.  
  233. static long
  234. generic_channel_write (Tchannel channel, const void * buffer,
  235.                unsigned long n_bytes)
  236. {
  237.   DWORD n_written;
  238.   STD_BOOL_API_CALL
  239.     (WriteFile,
  240.      ((CHANNEL_HANDLE (channel)), ((LPCVOID) buffer), n_bytes, (&n_written),
  241.       0));
  242.   return (n_written);
  243. }
  244.  
  245. static long
  246. generic_channel_n_read (Tchannel channel)
  247. {
  248.   /* This means "unknown".  */
  249.   return (-2);
  250. }
  251.  
  252. static void
  253. initialize_channel_class_generic (void)
  254. {
  255.   channel_class_t * class = (OS_malloc (sizeof (channel_class_t)));
  256.   (CHANNEL_CLASS_TYPE (class)) = channel_type_unknown;
  257.   (CHANNEL_CLASS_OP_READ (class)) = generic_channel_read;
  258.   (CHANNEL_CLASS_OP_WRITE (class)) = generic_channel_write;
  259.   (CHANNEL_CLASS_OP_CLOSE (class)) = generic_channel_close;
  260.   (CHANNEL_CLASS_OP_N_READ (class)) = generic_channel_n_read;
  261.   NT_channel_class_generic = class;
  262. }
  263.  
  264. static long
  265. file_channel_n_read (Tchannel channel)
  266. {
  267.   DWORD length = (GetFileSize ((CHANNEL_HANDLE (channel)), 0));
  268.   off_t position;
  269.   if (length == 0xFFFFFFFF)
  270.     return (0);
  271.   position = (OS_file_position (channel));
  272.   return ((position < ((off_t) length)) ? (((off_t) length) - position) : 0);
  273. }
  274.  
  275. static void
  276. initialize_channel_class_file (void)
  277. {
  278.   channel_class_t * class = (OS_malloc (sizeof (channel_class_t)));
  279.   (*class) = (*NT_channel_class_generic);
  280.   (CHANNEL_CLASS_TYPE (class)) = channel_type_file;
  281.   (CHANNEL_CLASS_OP_N_READ (class)) = file_channel_n_read;
  282.   NT_channel_class_file = class;
  283. }
  284.  
  285. static long
  286. screen_channel_read (Tchannel channel, void * buffer, unsigned long n_bytes)
  287. {
  288.   DWORD bytes_read
  289.     = (Screen_Read ((CHANNEL_HANDLE (channel)),
  290.             ((BOOL) (CHANNEL_BUFFERED (channel))),
  291.             buffer,
  292.             n_bytes));
  293.   if (bytes_read == 0xFFFFFFFF)
  294.     {
  295.       /* For pleasantness give up rest of this timeslice.  */
  296.       Sleep (0);
  297.       REQUEST_INTERRUPT (INT_Global_1);    /* windows polling */
  298.       return (-1);
  299.     }
  300.   return (bytes_read);
  301. }
  302.  
  303. static long
  304. screen_channel_write (Tchannel channel, const void * buffer,
  305.               unsigned long n_bytes)
  306. {
  307.   HANDLE h = (CHANNEL_HANDLE (channel));
  308.   SendMessage (h, SCREEN_WRITE, ((WPARAM) n_bytes), ((LPARAM) buffer));
  309.   if (h == master_tty_window)
  310.     SendMessage (h, WM_PAINT, 0, 0);
  311.   return (n_bytes);
  312. }
  313.  
  314. static long
  315. screen_channel_n_read (Tchannel channel)
  316. {
  317.   /* This is incorrect.  However, it's a pain to do the right thing.
  318.      Furthermore, NT_channel_n_read is only used by "select", and for
  319.      that particular case, this is the correct value.  */
  320.   return (-1);
  321. }
  322.  
  323. static void
  324. initialize_channel_class_screen (void)
  325. {
  326.   channel_class_t * class = (OS_malloc (sizeof (channel_class_t)));
  327.   (CHANNEL_CLASS_TYPE (class)) = channel_type_terminal;
  328.   (CHANNEL_CLASS_OP_READ (class)) = screen_channel_read;
  329.   (CHANNEL_CLASS_OP_WRITE (class)) = screen_channel_write;
  330.   (CHANNEL_CLASS_OP_CLOSE (class)) = 0;
  331.   (CHANNEL_CLASS_OP_N_READ (class)) = screen_channel_n_read;
  332.   NT_channel_class_screen = class;
  333. }
  334.  
  335. void
  336. OS_make_pipe (Tchannel * readerp, Tchannel * writerp)
  337. {
  338.   HANDLE hread;
  339.   HANDLE hwrite;
  340.   STD_BOOL_API_CALL (CreatePipe, ((&hread), (&hwrite), 0, 0));
  341.   transaction_begin ();
  342.   NT_handle_close_on_abort (hwrite);
  343.   (*readerp) = (NT_make_channel (hread, NT_channel_class_anonymous_pipe));
  344.   transaction_commit ();
  345.   transaction_begin ();
  346.   OS_channel_close_on_abort (*readerp);
  347.   (*writerp) = (NT_make_channel (hwrite, NT_channel_class_anonymous_pipe));
  348.   transaction_commit ();
  349. }
  350.  
  351. static long
  352. pipe_channel_read (Tchannel channel, void * buffer, unsigned long n_bytes)
  353. {
  354. #ifdef TRACE_NTIO
  355.   fprintf (trace_file, "pipe_channel_read: channel=%d blocking=%s\n",
  356.        channel,
  357.        ((CHANNEL_NONBLOCKING (channel)) ? "no" : "yes"));
  358.   fflush (trace_file);
  359. #endif
  360.   if (CHANNEL_NONBLOCKING (channel))
  361.     {
  362.       long n = (NT_channel_n_read (channel));
  363. #ifdef TRACE_NTIO
  364.       fprintf (trace_file, "pipe_channel_read: n=%d\n", n);
  365.       fflush (trace_file);
  366. #endif
  367.       if (n <= 0)
  368.     return (n);
  369.     }
  370.   return (generic_channel_read (channel, buffer, n_bytes));
  371. }
  372.  
  373. static long
  374. pipe_channel_n_read (Tchannel channel)
  375. {
  376.   DWORD n;
  377. #ifdef TRACE_NTIO
  378.   fprintf (trace_file, "pipe_channel_n_read: channel=%d\n", channel);
  379.   fflush (trace_file);
  380. #endif
  381.   if (!PeekNamedPipe ((CHANNEL_HANDLE (channel)), 0, 0, 0, (&n), 0))
  382.     {
  383.       DWORD code = (GetLastError ());
  384.       if ((code == ERROR_INVALID_HANDLE)
  385.       || (code == ERROR_BROKEN_PIPE))
  386.     /* ERROR_BROKEN_PIPE means the other end of the pipe has been
  387.        closed, so return zero which means "end of file".  */
  388.     return (0);
  389.       NT_error_api_call (code, apicall_PeekNamedPipe);
  390.     }
  391. #ifdef TRACE_NTIO
  392.   fprintf (trace_file, "pipe_channel_n_read: n=%d\n", n);
  393.   fflush (trace_file);
  394. #endif
  395.   /* Zero bytes available means "read would block", so return -1.  */
  396.   return ((n == 0) ? (-1) : n);
  397. }
  398.  
  399. static void
  400. initialize_channel_class_anonymous_pipe (void)
  401. {
  402.   channel_class_t * class = (OS_malloc (sizeof (channel_class_t)));
  403.   (CHANNEL_CLASS_TYPE (class)) = channel_type_win32_anonymous_pipe;
  404.   (CHANNEL_CLASS_OP_READ (class)) = pipe_channel_read;
  405.   (CHANNEL_CLASS_OP_WRITE (class)) = generic_channel_write;
  406.   (CHANNEL_CLASS_OP_CLOSE (class)) = generic_channel_close;
  407.   (CHANNEL_CLASS_OP_N_READ (class)) = pipe_channel_n_read;
  408.   NT_channel_class_anonymous_pipe = class;
  409. }
  410.  
  411. static void
  412. initialize_channel_class_named_pipe (void)
  413. {
  414.   channel_class_t * class = (OS_malloc (sizeof (channel_class_t)));
  415.   (*class) = (*NT_channel_class_anonymous_pipe);
  416.   (CHANNEL_CLASS_TYPE (class)) = channel_type_win32_named_pipe;
  417.   NT_channel_class_named_pipe = class;
  418. }
  419.  
  420. static long
  421. cooked_channel_write (Tchannel channel, const void * buffer,
  422.               unsigned long n_bytes) 
  423. {
  424.   /* Map LF to CR/LF */
  425.   static const unsigned char crlf [] = {CARRIAGE_RETURN, LINEFEED};
  426.   const unsigned char * bstart = buffer;
  427.   const unsigned char * start = bstart;
  428.   const unsigned char * end = (start + n_bytes);
  429.   while (start < end)
  430.     {
  431.       const unsigned char * scan = start;
  432.       while ((scan < end) && ((*scan) != LINEFEED))
  433.     scan += 1;
  434.       if (scan > start)
  435.     {
  436.       unsigned int n_bytes = (scan - start);
  437.       long n_written
  438.         = ((* (CHANNEL_CLASS_OP_WRITE (CHANNEL_CLASS (channel))))
  439.            (channel, start, n_bytes));
  440.       if (n_written < 0)
  441.         return (start - bstart);
  442.       if (((unsigned int) n_written) < n_bytes)
  443.         return ((start - bstart) + n_written);
  444.     }
  445.       if (scan < end)
  446.     {
  447.       unsigned int n_bytes = (sizeof (crlf));
  448.       long n_written
  449.         = ((* (CHANNEL_CLASS_OP_WRITE (CHANNEL_CLASS (channel))))
  450.            (channel, crlf, n_bytes));
  451.       if (n_written < ((long) n_bytes))
  452.         /* This backs out incorrectly if only CR is written out.  */
  453.         return (scan - bstart);
  454.     }
  455.       start = (scan + 1);
  456.     }
  457.   return (n_bytes);
  458. }
  459.  
  460. size_t
  461. OS_channel_read_load_file (Tchannel channel, void * buffer, size_t nbytes)
  462. {
  463.   DWORD scr;
  464.   return ((ReadFile (CHANNEL_HANDLE (channel), buffer, nbytes, &scr, 0))
  465.       ? scr : 0);
  466. }
  467.  
  468. size_t
  469. OS_channel_write_dump_file (Tchannel channel, const void * buffer,
  470.                 size_t nbytes)
  471. {
  472.   DWORD  scr;
  473.   return ((WriteFile (CHANNEL_HANDLE (channel), ((LPCVOID) buffer), nbytes,
  474.               &scr, 0))
  475.       ? scr : 0);
  476. }
  477.  
  478. void
  479. OS_channel_write_string (Tchannel channel, const char * string)
  480. {
  481.   long length = (strlen (string));
  482.   if ((OS_channel_write (channel, string, length)) != length)
  483.     error_external_return ();
  484. }
  485.  
  486. int
  487. OS_channel_nonblocking_p (Tchannel channel)
  488. {
  489.   return (CHANNEL_NONBLOCKING (channel));
  490. }
  491.  
  492. void
  493. OS_channel_nonblocking (Tchannel channel)
  494. {
  495.   (CHANNEL_NONBLOCKING (channel)) = 1;
  496. }
  497.  
  498. void
  499. OS_channel_blocking (Tchannel channel)
  500. {
  501.   (CHANNEL_NONBLOCKING (channel)) = 0;
  502. }
  503.  
  504. int
  505. OS_terminal_buffered_p (Tchannel channel)
  506. {
  507.   return (CHANNEL_BUFFERED (channel));
  508. }
  509.  
  510. void
  511. OS_terminal_buffered (Tchannel channel)
  512. {
  513.   (CHANNEL_BUFFERED (channel)) = 1;
  514. }
  515.  
  516. void
  517. OS_terminal_nonbuffered (Tchannel channel)
  518. {
  519.   (CHANNEL_BUFFERED (channel)) = 0;
  520. }
  521.  
  522. int
  523. OS_terminal_cooked_output_p (Tchannel channel)
  524. {
  525.   return (CHANNEL_COOKED (channel));
  526. }
  527.  
  528. void
  529. OS_terminal_cooked_output (Tchannel channel)
  530. {
  531.   CHANNEL_COOKED (channel) = 1;
  532. }
  533.  
  534. void
  535. OS_terminal_raw_output (Tchannel channel)
  536. {
  537.   CHANNEL_COOKED (channel) = 0;
  538. }
  539.  
  540. void
  541. OS_terminal_flush_input (Tchannel channel)
  542. {
  543. }
  544.  
  545. void
  546. OS_terminal_flush_output (Tchannel channel)
  547. {
  548. }
  549.  
  550. void
  551. OS_terminal_drain_output (Tchannel channel)
  552. {
  553. }
  554.  
  555. unsigned int
  556. arg_baud_index (unsigned int argument)
  557. {
  558.   return (arg_index_integer (argument, 1));
  559. }
  560.  
  561. unsigned int
  562. OS_terminal_get_ispeed (Tchannel channel)
  563. {
  564.   return (0);
  565. }
  566.  
  567. unsigned int
  568. OS_terminal_get_ospeed (Tchannel channel)
  569. {
  570.   return (0);
  571. }
  572.  
  573. void
  574. OS_terminal_set_ispeed (Tchannel channel, unsigned int baud)
  575. {
  576. }
  577.  
  578. void
  579. OS_terminal_set_ospeed (Tchannel channel, unsigned int baud)
  580. {
  581. }
  582.  
  583. unsigned int
  584. OS_baud_index_to_rate (unsigned int index)
  585. {
  586.   return (9600);
  587. }
  588.  
  589. int
  590. OS_baud_rate_to_index (unsigned int rate)
  591. {
  592.   return ((rate == 9600) ? 0 : -1);
  593. }
  594.  
  595. unsigned int
  596. OS_terminal_state_size (void)
  597. {
  598.   return (3);
  599. }
  600.  
  601. void
  602. OS_terminal_get_state (Tchannel channel, void * state_ptr)
  603. {
  604.   unsigned char * statep = ((unsigned char *) state_ptr);
  605.   (*statep++) = (CHANNEL_NONBLOCKING (channel));
  606.   (*statep++) = (CHANNEL_BUFFERED (channel));
  607.   (*statep)   = (CHANNEL_COOKED (channel));
  608. }
  609.  
  610. void
  611. OS_terminal_set_state (Tchannel channel, void * state_ptr)
  612. {
  613.   unsigned char * statep = ((unsigned char *) state_ptr);
  614.   (CHANNEL_NONBLOCKING (channel)) = (*statep++);
  615.   (CHANNEL_BUFFERED (channel))    = (*statep++);
  616.   (CHANNEL_COOKED (channel))      = (*statep);
  617. }
  618.  
  619. int
  620. OS_job_control_p (void)
  621. {
  622.   return (0);
  623. }
  624.  
  625. int
  626. OS_have_ptys_p (void)
  627. {
  628.   return (0);
  629. }
  630.  
  631. /* Initialization/Termination code. */
  632.  
  633. int OS_have_select_p = 0;
  634.  
  635. extern HANDLE master_tty_window;
  636. extern void EXFUN (NT_initialize_channels, (void));
  637. extern void EXFUN (NT_reset_channels, (void));
  638. extern void EXFUN (NT_restore_channels, (void));
  639.  
  640. void
  641. NT_reset_channels (void)
  642. {
  643.   OS_free (NT_channel_table);
  644.   NT_channel_table = 0;
  645.   OS_channel_table_size = 0;
  646. }
  647.  
  648. void
  649. NT_restore_channels (void)
  650. {
  651.   if (master_tty_window != ((HANDLE) NULL))
  652.     Screen_Destroy (TRUE, master_tty_window);
  653.   master_tty_window = ((HANDLE) NULL);
  654. }
  655.  
  656. void
  657. NT_initialize_channels (void)
  658. {
  659.   master_tty_window = (Screen_Create (NULL, "MIT Scheme", SW_SHOWNORMAL));
  660.   if (win32_under_win32s_p ())
  661.     OS_have_select_p = 0;
  662.   else
  663.     OS_have_select_p = 1;
  664.   /* The following API call boosts the number of available handles to
  665.      its maximum value.  This has no effect under NT, which does not
  666.      place a limit on the number of handles.  */
  667.   (void) SetHandleCount (255);
  668.   OS_channel_table_size = NT_DEFAULT_CHANNEL_TABLE_SIZE;
  669.   NT_channel_table
  670.     = (OS_malloc (OS_channel_table_size * (sizeof (struct channel))));
  671.   {
  672.     Tchannel channel;
  673.     for (channel = 0; (channel < OS_channel_table_size); channel += 1)
  674.       MARK_CHANNEL_CLOSED (channel);
  675.   }
  676.   add_reload_cleanup (NT_channel_close_all);
  677.   initialize_channel_class_generic ();
  678.   initialize_channel_class_file ();
  679.   initialize_channel_class_screen ();
  680.   initialize_channel_class_anonymous_pipe ();
  681.   initialize_channel_class_named_pipe ();
  682. }
  683.