* Change channel data structure. Now, instead of being tagged with a
authorChris Hanson <org/chris-hanson/cph>
Fri, 24 Oct 1997 07:25:05 +0000 (07:25 +0000)
committerChris Hanson <org/chris-hanson/cph>
Fri, 24 Oct 1997 07:25:05 +0000 (07:25 +0000)
  "type", it is tagged with a "class".  The "class" has associated
  operations, so that basic channel operations such as reading and
  writing are generic.  This change allows the code to be modularized
  a bit better, and will facilitate the introduction of sockets.

* Eliminate the procedure NT_pipe_channel_available, replacing it with
  the generic procedure NT_channel_n_read.

* Eliminate references to long-obsolete "console" stuff.

* Change file-pointer positioning code to use SetFilePointer rather
  than __llseek.

* Don't try to signal an error if MsgWaitForMultipleObjects returns an
  unexpected answer -- only if it returns WAIT_FAILED.  We are only
  using it as a mechanism for blocking.

* Make cosmetic changes, eliminating unnecessary instances of "DEFUN"
  and the like.  These were introduced for unix, because there were
  non-ANSI compilers at that time.  On NT, all compilers are ANSI.

v7/src/microcode/ntfile.c
v7/src/microcode/ntio.c
v7/src/microcode/ntio.h
v7/src/microcode/nttty.c
v7/src/microcode/prntio.c

index 486e4c61991dd40fef03595da8c33ba389fe0bd6..b781dc88f404a2a496fa8449eb2a5ed13bb8ec8b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: ntfile.c,v 1.10 1997/08/22 16:33:14 cph Exp $
+$Id: ntfile.c,v 1.11 1997/10/24 07:24:39 cph Exp $
 
 Copyright (c) 1992-97 Massachusetts Institute of Technology
 
@@ -35,67 +35,14 @@ MIT in each case. */
 #include "nt.h"
 #include "osfile.h"
 #include "ntio.h"
-
-extern void EXFUN (terminal_open, (Tchannel channel));
 \f
-static enum channel_type
-DEFUN (handle_channel_type, (hFile), HANDLE hFile)
-{
-  if (Screen_IsScreenHandle (hFile))
-    return  channel_type_terminal;
-//  if (IsConsoleHandle (hFile))
-//    return  channel_type_terminal;
-  switch (GetFileType (hFile))
-  {
-    default:
-    case  FILE_TYPE_UNKNOWN:   return  channel_type_unknown;
-    case  FILE_TYPE_DISK:      return  channel_type_file;
-    case  FILE_TYPE_CHAR:      return  channel_type_win32_char;
-    case  FILE_TYPE_PIPE:      return  channel_type_win32_pipe;
-  }
-}
-
-Tchannel
-DEFUN (OS_open_handle, (hFile), HANDLE hFile)
-{
-  enum channel_type type;
-  Tchannel channel;
-  
-//  if (hFile == STDIN_HANDLE) {
-//    channel = (NT_make_channel (STDIN_HANDLE, channel_type_terminal));
-//    CHANNEL_COOKED(channel) = 1;
-//  }
-//
-//  else if (hFile == STDOUT_HANDLE) {
-//    channel = (NT_make_channel (STDOUT_HANDLE, channel_type_terminal));
-//    CHANNEL_COOKED(channel) = 1;
-//  }
-//
-//  else if (hFile == STDERR_HANDLE) {
-//    channel = (NT_make_channel (STDERR_HANDLE, channel_type_terminal));
-//    CHANNEL_COOKED(channel) = 1;
-//  }
-
-//  else
-  {
-    type = handle_channel_type (hFile);
-    channel = (NT_make_channel (hFile, type));
-
-    /* Like Unix, all terminals initialize to cooked mode. */
-    if (type == channel_type_terminal)
-      CHANNEL_COOKED(channel) = 1;
-  }
-  return  channel;
-}
-
-
 #define DEFUN_OPEN_FILE(name, args)                                    \
 Tchannel                                                               \
-DEFUN (name, (filename), CONST char * filename)                                \
+name (const char * filename)                                           \
 {                                                                      \
   HANDLE hFile;                                                                \
   STD_HANDLE_API_CALL (hFile, CreateFile, args);                       \
-  return (OS_open_handle (hFile));                                     \
+  return (NT_open_handle (hFile));                                     \
 }
 
 // In the following we specify FILE_SHARE_READ | FILE_SHARE_WRITE
@@ -116,7 +63,7 @@ DEFUN_OPEN_FILE (OS_open_io_file,
    OPEN_ALWAYS, (FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS), 0));
 
 Tchannel
-DEFUN (OS_open_append_file, (filename), CONST char * filename)
+OS_open_append_file (const char * filename)
 {
   HANDLE hFile;
   STD_HANDLE_API_CALL
@@ -131,106 +78,70 @@ DEFUN (OS_open_append_file, (filename), CONST char * filename)
                  ));
   if ((SetFilePointer (hFile, 0, 0, FILE_END)) == 0xFFFFFFFF)
     NT_error_api_call ((GetLastError ()), apicall_SetFilePointer);
-  return (OS_open_handle (hFile));
+  return (NT_open_handle (hFile));
 }
 \f
 static Tchannel
-DEFUN (make_load_channel, (handle), HANDLE handle)
+make_load_channel (HANDLE handle)
 {
-  enum channel_type type = handle_channel_type (handle);
+  channel_class_t * class = (NT_handle_channel_class (handle));
   return
-    (((type == channel_type_terminal)
-      || (type == channel_type_directory))
+    ((((CHANNEL_CLASS_TYPE (class)) == channel_type_terminal)
+      || ((CHANNEL_CLASS_TYPE (class)) == channel_type_directory))
      ? NO_CHANNEL
-     : (NT_make_channel (handle, type)));
+     : (NT_make_channel (handle, class)));
 }
 
 Tchannel
-DEFUN (OS_open_load_file, (filename), CONST char * filename)
+OS_open_load_file (const char * filename)
 {
-      /*SRA:*/
-   HANDLE  hFile;
-   
-   hFile = CreateFile (filename, GENERIC_READ,
-                                FILE_SHARE_READ /*FILE_SHARE_READ?*/,
-                                0 /*security?*/,
-                                OPEN_EXISTING,
-                                0,
-                                0);
-   if (hFile != INVALID_HANDLE_VALUE)
-     return  make_load_channel (hFile);
-
-   /* try to truncate extension for .bcon hack*/
-   {
-     char newname [MAX_PATH+10];
-     int i;
-     strncpy (newname, filename, MAX_PATH);
-     for (i=0; newname[i]; i++);
-     if (i<4)  return  NO_CHANNEL;
-     if (newname[i-5]=='.') {
-       newname[i-1] = 0;
-       hFile = CreateFile (newname, GENERIC_READ, FILE_SHARE_READ,
-                          0, OPEN_EXISTING, 0, 0);
-       if (hFile != INVALID_HANDLE_VALUE)
-        return  make_load_channel (hFile);
-     }
-   }
-   return  NO_CHANNEL;
+  HANDLE handle
+    = (CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, 0,
+                  OPEN_EXISTING, 0, 0));
+  return
+    ((handle != INVALID_HANDLE_VALUE)
+     ? (make_load_channel (handle))
+     : NO_CHANNEL);
 }
 
 Tchannel
-DEFUN (OS_open_dump_file, (filename), CONST char * filename)
+OS_open_dump_file (const char * filename)
 {
-   HANDLE  hFile = CreateFile (        filename,
-                               GENERIC_WRITE,
-                               FILE_SHARE_READ /*no sharing*/,
-                               0 /*security?*/,
-                               CREATE_ALWAYS,
-                               0,
-                               0);
-
-  if (hFile != INVALID_HANDLE_VALUE)
-    return  make_load_channel (hFile);
-  
-  return  NO_CHANNEL;
+  HANDLE handle
+    = (CreateFile (filename, GENERIC_WRITE, FILE_SHARE_READ, 0,
+                  CREATE_ALWAYS, 0, 0));
+  return
+    ((handle != INVALID_HANDLE_VALUE)
+     ? (make_load_channel (handle))
+     : NO_CHANNEL);
 }
 
 off_t
-DEFUN (OS_file_length, (channel), Tchannel channel)
+OS_file_length (Tchannel channel)
 {
-  DWORD result;
-  DWORD code;
-  while (1)
-    {
-      result = (GetFileSize ((CHANNEL_HANDLE (channel)), 0));
-      if (result != 0xFFFFFFFF)
-       return (result);
-      code = (GetLastError ());
-      if (code != NO_ERROR)
-       NT_error_api_call (code, apicall_GetFileSize);
-    }
+  DWORD result = (GetFileSize ((CHANNEL_HANDLE (channel)), 0));
+  if (result == 0xFFFFFFFF)
+    NT_error_api_call ((GetLastError ()), apicall_GetFileSize);
+  return (result);
 }
 
 off_t
-DEFUN (OS_file_position, (channel), Tchannel channel)
+OS_file_position (Tchannel channel)
 {
-  off_t result
-    = (_llseek (((HFILE) (CHANNEL_HANDLE (channel))), 0L, SEEK_CUR));
-  if (result == 0)
-    NT_error_unix_call (errno, syscall_lseek);
-  return (result);
+  DWORD position
+    = (SetFilePointer ((CHANNEL_HANDLE (channel)), 0, 0, FILE_CURRENT));
+  if (position == 0xFFFFFFFF)
+    NT_error_api_call ((GetLastError ()), apicall_SetFilePointer);
+  return (position);
 }
 
 void
-DEFUN (OS_file_set_position, (channel, position),
-       Tchannel channel AND
-       off_t position)
+OS_file_set_position (Tchannel channel, off_t position)
 {
-  off_t result
-    = (_llseek (((HFILE) (CHANNEL_HANDLE (channel))), position, SEEK_SET));
-  if (result == 0)
-    NT_error_unix_call (errno, syscall_lseek);
-  if (result != position)
+  DWORD old_position
+    = (SetFilePointer ((CHANNEL_HANDLE (channel)), position, 0, FILE_BEGIN));
+  if (old_position == 0xFFFFFFFF)
+    NT_error_api_call ((GetLastError ()), apicall_SetFilePointer);
+  if (old_position != position)
     error_external_return ();
 }
index 68516263100bac25c9ed65c681364a7d15a1c0ff..d69a23d33d8971912a368cccae2f1f67eaee56bc 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: ntio.c,v 1.17 1997/10/22 05:23:18 cph Exp $
+$Id: ntio.c,v 1.18 1997/10/24 07:24:56 cph Exp $
 
 Copyright (c) 1992-97 Massachusetts Institute of Technology
 
@@ -43,69 +43,126 @@ MIT in each case. */
 
 #include "ntscreen.h"
 
-#ifndef fileno
-#define fileno(fp)     ((fp)->_file)
-#endif
+channel_class_t * NT_channel_class_generic;
+channel_class_t * NT_channel_class_file;
+channel_class_t * NT_channel_class_screen;
+channel_class_t * NT_channel_class_pipe;
 
 static Tchannel channel_allocate (void);
+static long cooked_channel_write (Tchannel, const void *, unsigned long) ;
 \f
 #ifndef NT_DEFAULT_CHANNEL_TABLE_SIZE
 #define NT_DEFAULT_CHANNEL_TABLE_SIZE 1024
 #endif
 
 size_t OS_channel_table_size;
-struct channel * channel_table;
-
-#ifndef GUI
-  HANDLE STDIN_HANDLE,  STDOUT_HANDLE,  STDERR_HANDLE;
-#endif
+struct channel * NT_channel_table;
 
 Tchannel
-NT_make_channel (HANDLE handle, enum channel_type type)
+NT_make_channel (HANDLE handle, channel_class_t * class)
 {
   Tchannel channel;
   transaction_begin ();
   NT_handle_close_on_abort (handle);
   channel = (channel_allocate ());
-  NT_initialize_channel (channel, handle, type);
+  (CHANNEL_CLASS (channel)) = class;
+  (CHANNEL_HANDLE (channel)) = handle;
+  (CHANNEL_INTERNAL (channel)) = 0;
+  (CHANNEL_NONBLOCKING (channel)) = 0;
+  (CHANNEL_BUFFERED (channel)) = 1;
+  (CHANNEL_COOKED (channel)) = 0;
   transaction_commit ();
   return (channel);
 }
 
+channel_class_t *
+NT_handle_channel_class (HANDLE handle)
+{
+  if (Screen_IsScreenHandle (handle))
+    return (NT_channel_class_screen);
+  switch (GetFileType (handle))
+    {
+    case FILE_TYPE_DISK: return (NT_channel_class_file);
+    case FILE_TYPE_PIPE: return (NT_channel_class_pipe);
+    case FILE_TYPE_CHAR: return (NT_channel_class_generic);
+    default: return (NT_channel_class_generic);
+    }
+}
+
+Tchannel
+NT_open_handle (HANDLE handle)
+{
+  Tchannel channel
+    = (NT_make_channel (handle, (NT_handle_channel_class (handle))));
+  /* Like Unix, all terminals initialize to cooked mode.  */
+  if ((CHANNEL_TYPE (channel)) == channel_type_terminal)
+    (CHANNEL_COOKED (channel)) = 1;
+  return (channel);
+}
+\f
+long
+OS_channel_read (Tchannel channel, void * buffer, size_t n_bytes)
+{
+  return
+    ((n_bytes == 0)
+     ? 0
+     : ((* (CHANNEL_CLASS_OP_READ (CHANNEL_CLASS (channel))))
+       (channel, buffer, n_bytes)));
+}
+
+long
+OS_channel_write (Tchannel channel, const void * buffer, size_t n_bytes)
+{
+  return
+    ((n_bytes == 0)
+     ? 0
+     : (CHANNEL_COOKED (channel))
+     ? (cooked_channel_write (channel, buffer, n_bytes))
+     : ((* (CHANNEL_CLASS_OP_WRITE (CHANNEL_CLASS (channel))))
+       (channel, buffer, n_bytes)));
+}
+
 void
-NT_initialize_channel (Tchannel channel, HANDLE handle, enum channel_type type)
+OS_channel_close (Tchannel channel)
 {
-  (CHANNEL_HANDLE (channel)) = handle;
-  (CHANNEL_TYPE (channel)) = type;
-  (CHANNEL_INTERNAL (channel)) = 0;
-  (CHANNEL_NONBLOCKING (channel)) = 0;
-  (CHANNEL_BUFFERED (channel)) = 1;
-  (CHANNEL_COOKED (channel)) = 0;
+  if (! ((CHANNEL_CLOSED_P (channel)) || (CHANNEL_INTERNAL (channel))))
+    {
+      (* (CHANNEL_CLASS_OP_CLOSE (CHANNEL_CLASS (channel)))) (channel, 1);
+      MARK_CHANNEL_CLOSED (channel);
+    }
 }
 
+void
+OS_channel_close_noerror (Tchannel channel)
+{
+  if (! ((CHANNEL_CLOSED_P (channel)) || (CHANNEL_INTERNAL (channel))))
+    {
+      (* (CHANNEL_CLASS_OP_CLOSE (CHANNEL_CLASS (channel)))) (channel, 0);
+      MARK_CHANNEL_CLOSED (channel);
+    }
+}
+
+long
+NT_channel_n_read (Tchannel channel)
+{
+  if (CHANNEL_CLOSED_P (channel))
+    return (0);
+  {
+    DWORD flags;
+    if (!GetHandleInformation ((CHANNEL_HANDLE (channel)), (&flags)))
+      return (0);
+  }
+  return ((* (CHANNEL_CLASS_OP_N_READ (CHANNEL_CLASS (channel)))) (channel));
+}
+\f
 static void
-DEFUN_VOID (NT_channel_close_all)
+NT_channel_close_all (void)
 {
   Tchannel channel;
   for (channel = 0; (channel < OS_channel_table_size); channel += 1)
     if (CHANNEL_OPEN_P (channel))
       OS_channel_close_noerror (channel);
-  return;
-}
-
-#ifndef GUI
-static BOOL _stdcall
-NT_ctrl_handler (DWORD dwCtrlType)
-{
-    switch (dwCtrlType) {
-      case CTRL_C_EVENT:
-       REQUEST_INTERRUPT (INT_Character);
-       return  TRUE;
-      default:
-       return  FALSE;
-    }
 }
-#endif /* GUI */
 
 static Tchannel
 channel_allocate (void)
@@ -120,44 +177,21 @@ channel_allocate (void)
     channel += 1;
   }
 }
-\f
+
 int
-DEFUN (OS_channel_open_p, (channel), Tchannel channel)
+OS_channel_open_p (Tchannel channel)
 {
   return (CHANNEL_OPEN_P (channel));
 }
 
-void
-DEFUN (OS_channel_close, (channel), Tchannel channel)
-{
-  if (! (CHANNEL_INTERNAL (channel)))
-  {
-    STD_BOOL_API_CALL (CloseHandle, (CHANNEL_HANDLE (channel)));
-    MARK_CHANNEL_CLOSED (channel);
-  }
-  return;
-}
-
-void
-DEFUN (OS_channel_close_noerror, (channel), Tchannel channel)
-{
-  if (! (CHANNEL_INTERNAL (channel)))
-  {
-    if (! Screen_IsScreenHandle (CHANNEL_HANDLE (channel)))
-      CloseHandle (CHANNEL_HANDLE (channel));
-    MARK_CHANNEL_CLOSED (channel);
-  }
-  return;
-}
-
 static void
-DEFUN (channel_close_on_abort_1, (cp), PTR cp)
+channel_close_on_abort_1 (void * cp)
 {
   OS_channel_close (* ((Tchannel *) cp));
 }
 
 void
-DEFUN (OS_channel_close_on_abort, (channel), Tchannel channel)
+OS_channel_close_on_abort (Tchannel channel)
 {
   Tchannel * cp = ((Tchannel *) (dstack_alloc (sizeof (Tchannel))));
   (*cp) = (channel);
@@ -179,138 +213,190 @@ NT_handle_close_on_abort (HANDLE h)
 }
 
 enum channel_type
-DEFUN (OS_channel_type, (channel), Tchannel channel)
+OS_channel_type (Tchannel channel)
 {
   return (CHANNEL_TYPE (channel));
 }
 \f
-void
-DEFUN (OS_terminal_flush_input, (channel), Tchannel channel)
-{ extern void EXFUN (flush_conio_buffers, (void));
+static void
+generic_channel_close (Tchannel channel, int errorp)
+{
+  if ((!CloseHandle (CHANNEL_HANDLE (channel))) && errorp)
+    NT_error_api_call ((GetLastError ()), apicall_CloseHandle);
+}
 
-//  if (IsWindow (CHANNEL_HANDLE (channel)))  /*SRA:dubious*/
-//    flush_conio_buffers();
-  return;
+static long
+generic_channel_read (Tchannel channel, void * buffer, unsigned long n_bytes)
+{
+  DWORD bytes_read;
+  if ((!ReadFile ((CHANNEL_HANDLE (channel)),
+                 buffer, n_bytes, (&bytes_read), 0))
+      && (bytes_read > 0))
+    NT_error_api_call ((GetLastError ()), apicall_ReadFile);
+  return (bytes_read);
 }
 
-void
-DEFUN (OS_terminal_flush_output, (channel), Tchannel channel)
+static long
+generic_channel_write (Tchannel channel, const void * buffer,
+                      unsigned long n_bytes)
 {
-  return;
+  DWORD n_written;
+  STD_BOOL_API_CALL
+    (WriteFile,
+     ((CHANNEL_HANDLE (channel)), buffer, n_bytes, (&n_written), 0));
+  return (n_written);
 }
 
-void
-DEFUN (OS_terminal_drain_output, (channel), Tchannel channel)
+static long
+generic_channel_n_read (Tchannel channel)
 {
-  return;
+  /* This means "unknown".  */
+  return (-2);
 }
 
 static void
-Relinquish_Timeslice (void)
+initialize_channel_class_generic (void)
 {
-  Sleep (0);
-  REQUEST_INTERRUPT (INT_Global_1);    /* windows polling */
-  return;
+  channel_class_t * class = (OS_malloc (sizeof (channel_class_t)));
+  (CHANNEL_CLASS_TYPE (class)) = channel_type_unknown;
+  (CHANNEL_CLASS_OP_READ (class)) = generic_channel_read;
+  (CHANNEL_CLASS_OP_WRITE (class)) = generic_channel_write;
+  (CHANNEL_CLASS_OP_CLOSE (class)) = generic_channel_close;
+  (CHANNEL_CLASS_OP_N_READ (class)) = generic_channel_n_read;
+  NT_channel_class_generic = class;
 }
 
-long
-DEFUN (OS_channel_read, (channel, buffer, nbytes),
-       Tchannel channel AND
-       PTR buffer AND
-       size_t nbytes)
+static long
+file_channel_n_read (Tchannel channel)
 {
-  if (nbytes == 0)
-    return (0);
+  off_t position = (OS_file_position (channel));
+  off_t length = (OS_file_length (channel));
+  return ((position < length) ? (length - position) : 0);
+}
 
-  if (Screen_IsScreenHandle (CHANNEL_HANDLE (channel)))
+static void
+initialize_channel_class_file (void)
+{
+  channel_class_t * class = (OS_malloc (sizeof (channel_class_t)));
+  (*class) = (*NT_channel_class_generic);
+  (CHANNEL_CLASS_TYPE (class)) = channel_type_file;
+  (CHANNEL_CLASS_OP_N_READ (class)) = file_channel_n_read;
+  NT_channel_class_file = class;
+}
+\f
+static long
+screen_channel_read (Tchannel channel, void * buffer, unsigned long n_bytes)
+{
+  DWORD bytes_read
+    = (Screen_Read ((CHANNEL_HANDLE (channel)),
+                   ((BOOL) (CHANNEL_BUFFERED (channel))),
+                   buffer,
+                   n_bytes));
+  if (bytes_read == 0xFFFFFFFF)
     {
-      DWORD bytes_read
-       = (Screen_Read ((CHANNEL_HANDLE (channel)),
-                       ((BOOL) (CHANNEL_BUFFERED (channel))),
-                       buffer,
-                       nbytes));
-      if (bytes_read == 0xFFFFFFFF)
-       {
-         /* For pleasantness give up rest of this timeslice.  */
-         Relinquish_Timeslice ();
-         return (-1);
-       }
-      if (bytes_read > nbytes)
-       error_external_return ();
-      return (bytes_read);
+      /* For pleasantness give up rest of this timeslice.  */
+      Sleep (0);
+      REQUEST_INTERRUPT (INT_Global_1);        /* windows polling */
+      return (-1);
     }
+  return (bytes_read);
+}
 
-  while (1)
+static long
+screen_channel_write (Tchannel channel, const void * buffer,
+                     unsigned long n_bytes)
+{
+  SendMessage ((CHANNEL_HANDLE (channel)), SCREEN_WRITE,
+              ((WPARAM) n_bytes), ((LPARAM) buffer));
+  return (n_bytes);
+}
+
+static long
+screen_channel_n_read (Tchannel channel)
+{
+  /* This is incorrect.  However, it's a pain to do the right thing.
+     Furthermore, NT_channel_n_read is only used by "select", and for
+     that particular case, this is the correct value.  */
+  return (-1);
+}
+
+static void
+initialize_channel_class_screen (void)
+{
+  channel_class_t * class = (OS_malloc (sizeof (channel_class_t)));
+  (CHANNEL_CLASS_TYPE (class)) = channel_type_terminal;
+  (CHANNEL_CLASS_OP_READ (class)) = screen_channel_read;
+  (CHANNEL_CLASS_OP_WRITE (class)) = screen_channel_write;
+  (CHANNEL_CLASS_OP_CLOSE (class)) = 0;
+  (CHANNEL_CLASS_OP_N_READ (class)) = screen_channel_n_read;
+  NT_channel_class_screen = class;
+}
+\f
+void
+OS_make_pipe (Tchannel * readerp, Tchannel * writerp)
+{
+  HANDLE hread;
+  HANDLE hwrite;
+  STD_BOOL_API_CALL (CreatePipe, ((&hread), (&hwrite), 0, 0));
+  transaction_begin ();
+  NT_handle_close_on_abort (hwrite);
+  (*readerp) = (NT_make_channel (hread, NT_channel_class_pipe));
+  transaction_commit ();
+  transaction_begin ();
+  OS_channel_close_on_abort (*readerp);
+  (*writerp) = (NT_make_channel (hwrite, NT_channel_class_pipe));
+  transaction_commit ();
+}
+
+static long
+pipe_channel_read (Tchannel channel, void * buffer, unsigned long n_bytes)
+{
+  if (CHANNEL_NONBLOCKING (channel))
     {
-      if (IsConsoleHandle (CHANNEL_HANDLE (channel)))
-       {
-         /* Fake the console being a nonblocking channel that has
-            nothing after each alternate read.  */
-         static int nonblock = 1;
-         nonblock = (!nonblock);
-         if (nonblock)
-           return (-1);
-       }
-      if ((CHANNEL_NONBLOCKING (channel))
-         && ((CHANNEL_TYPE (channel)) == channel_type_win32_pipe))
-       {
-         long n = (NT_pipe_channel_available (channel));
-         if (n <= 0)
-           return ((n == 0) ? (-1) : 0);
-       }
-      {
-       DWORD bytes_read;
-       if ((!ReadFile ((CHANNEL_HANDLE (channel)),
-                       buffer,
-                       nbytes,
-                       (&bytes_read),
-                       0))
-           && (bytes_read > 0))
-         NT_error_api_call ((GetLastError ()), apicall_ReadFile);
-       if (bytes_read > nbytes)
-         error_external_return ();
-       return (bytes_read);
-      }
+      long n = (NT_channel_n_read (channel));
+      if (n <= 0)
+       return (n);
     }
+  return (generic_channel_read (channel, buffer, n_bytes));
 }
 
-long
-NT_pipe_channel_available (Tchannel channel)
+static long
+pipe_channel_n_read (Tchannel channel)
 {
   DWORD n;
   if (!PeekNamedPipe ((CHANNEL_HANDLE (channel)), 0, 0, 0, (&n), 0))
     {
       DWORD code = (GetLastError ());
       if (code == ERROR_BROKEN_PIPE)
-       return (-1);
+       /* ERROR_BROKEN_PIPE means the other end of the pipe has been
+          closed, so return zero which means "end of file".  */
+       return (0);
       NT_error_api_call (code, apicall_PeekNamedPipe);
     }
-  return (n);
+  /* Zero bytes available means "read would block", so return -1.  */
+  return ((n == 0) ? (-1) : n);
 }
-\f
-static DWORD
-raw_write (HANDLE fd, const unsigned char * buffer, size_t n_bytes)
+
+static void
+initialize_channel_class_pipe (void)
 {
-  DWORD n_written;
-  if (Screen_IsScreenHandle (fd))
-    {
-      SendMessage (fd, SCREEN_WRITE, ((WPARAM) n_bytes), ((LPARAM) buffer));
-      return (n_bytes);
-    }
-  if (IsConsoleHandle (fd))
-    return (nt_console_write (((void *) buffer), n_bytes));
-  STD_BOOL_API_CALL (WriteFile, (fd, buffer, n_bytes, (&n_written), 0));
-  return (n_written);
+  channel_class_t * class = (OS_malloc (sizeof (channel_class_t)));
+  (CHANNEL_CLASS_TYPE (class)) = channel_type_win32_pipe;
+  (CHANNEL_CLASS_OP_READ (class)) = pipe_channel_read;
+  (CHANNEL_CLASS_OP_WRITE (class)) = generic_channel_write;
+  (CHANNEL_CLASS_OP_CLOSE (class)) = generic_channel_close;
+  (CHANNEL_CLASS_OP_N_READ (class)) = pipe_channel_n_read;
+  NT_channel_class_pipe = class;
 }
-
-static DWORD
-text_write (HANDLE hFile, const unsigned char * buffer, size_t n_bytes) 
+\f
+static long
+cooked_channel_write (Tchannel channel, const void * buffer,
+                     unsigned long n_bytes) 
 {
   /* Map LF to CR/LF */
   static const unsigned char crlf [] = {CARRIAGE_RETURN, LINEFEED};
   const unsigned char * start = buffer;
   const unsigned char * end = (start + n_bytes);
-
   while (start < end)
     {
       const unsigned char * scan = start;
@@ -319,14 +405,20 @@ text_write (HANDLE hFile, const unsigned char * buffer, size_t n_bytes)
       if (scan > start)
        {
          unsigned int n_bytes = (scan - start);
-         DWORD n_written = (raw_write (hFile, start, n_bytes));
+         long n_written
+           = ((* (CHANNEL_CLASS_OP_WRITE (CHANNEL_CLASS (channel))))
+              (channel, start, n_bytes));
+         if (n_written < 0)
+           return (start - buffer);
          if (n_written < n_bytes)
            return ((start - buffer) + n_written);
        }
       if (scan < end)
        {
          unsigned int n_bytes = (sizeof (crlf));
-         DWORD n_written = (raw_write (hFile, crlf, n_bytes));
+         long n_written
+           = ((* (CHANNEL_CLASS_OP_WRITE (CHANNEL_CLASS (channel))))
+              (channel, crlf, n_bytes));
          if (n_written < n_bytes)
            /* This backs out incorrectly if only CR is written out.  */
            return (scan - buffer);
@@ -335,211 +427,175 @@ text_write (HANDLE hFile, const unsigned char * buffer, size_t n_bytes)
     }
   return (n_bytes);
 }
-
-long
-OS_channel_write (Tchannel channel, const void * buffer, size_t n_bytes)
-{
-  return
-    ((n_bytes == 0)
-     ? 0
-     : (CHANNEL_COOKED (channel))
-     ? (text_write ((CHANNEL_HANDLE (channel)), buffer, n_bytes))
-     : (raw_write ((CHANNEL_HANDLE (channel)), buffer, n_bytes)));
-}
 \f
 size_t
-DEFUN (OS_channel_read_load_file, (channel, buffer, nbytes),
-       Tchannel channel AND PTR buffer AND size_t nbytes)
+OS_channel_read_load_file (Tchannel channel, void * buffer, size_t nbytes)
 {
   DWORD scr;
-
   return ((ReadFile (CHANNEL_HANDLE (channel), buffer, nbytes, &scr, 0))
          ? scr : 0);
 }
 
 size_t
-DEFUN (OS_channel_write_dump_file, (channel, buffer, nbytes),
-       Tchannel channel AND CONST PTR buffer AND size_t nbytes)
+OS_channel_write_dump_file (Tchannel channel, const void * buffer,
+                           size_t nbytes)
 {
   DWORD  scr;
-
   return ((WriteFile (CHANNEL_HANDLE (channel), buffer, nbytes, &scr, 0))
          ? scr : 0);
 }
 
 void
-DEFUN (OS_channel_write_string, (channel, string),
-       Tchannel channel AND
-       CONST char * string)
+OS_channel_write_string (Tchannel channel, const char * string)
 {
   long length = (strlen (string));
   if ((OS_channel_write (channel, string, length)) != length)
     error_external_return ();
 }
-
-void
-OS_make_pipe (Tchannel * readerp, Tchannel * writerp)
-{
-  HANDLE hread;
-  HANDLE hwrite;
-  STD_BOOL_API_CALL (CreatePipe, ((&hread), (&hwrite), 0, 0));
-  transaction_begin ();
-  NT_handle_close_on_abort (hwrite);
-  (*readerp) = (NT_make_channel (hread, channel_type_win32_pipe));
-  transaction_commit ();
-  transaction_begin ();
-  OS_channel_close_on_abort (*readerp);
-  (*writerp) = (NT_make_channel (hwrite, channel_type_win32_pipe));
-  transaction_commit ();
-}
 \f
 int
-DEFUN (OS_channel_nonblocking_p, (channel), Tchannel channel)
+OS_channel_nonblocking_p (Tchannel channel)
 {
   return (CHANNEL_NONBLOCKING (channel));
 }
 
 void
-DEFUN (OS_channel_nonblocking, (channel), Tchannel channel)
+OS_channel_nonblocking (Tchannel channel)
 {
   (CHANNEL_NONBLOCKING (channel)) = 1;
-  return;
 }
 
 void
-DEFUN (OS_channel_blocking, (channel), Tchannel channel)
+OS_channel_blocking (Tchannel channel)
 {
   (CHANNEL_NONBLOCKING (channel)) = 0;
 }
 
 int
-DEFUN (OS_terminal_buffered_p, (channel), Tchannel channel)
+OS_terminal_buffered_p (Tchannel channel)
 {
   return (CHANNEL_BUFFERED (channel));
 }
 
 void
-DEFUN (OS_terminal_buffered, (channel), Tchannel channel)
+OS_terminal_buffered (Tchannel channel)
 {
-  CHANNEL_BUFFERED (channel) = 1;
+  (CHANNEL_BUFFERED (channel)) = 1;
 }
 
 void
-DEFUN (OS_terminal_nonbuffered, (channel), Tchannel channel)
+OS_terminal_nonbuffered (Tchannel channel)
 {
-  CHANNEL_BUFFERED (channel) = 0;
+  (CHANNEL_BUFFERED (channel)) = 0;
 }
 
 int
-DEFUN (OS_terminal_cooked_output_p, (channel), Tchannel channel)
+OS_terminal_cooked_output_p (Tchannel channel)
 {
   return (CHANNEL_COOKED (channel));
 }
 
 void
-DEFUN (OS_terminal_cooked_output, (channel), Tchannel channel)
+OS_terminal_cooked_output (Tchannel channel)
 {
   CHANNEL_COOKED (channel) = 1;
 }
 
 void
-DEFUN (OS_terminal_raw_output, (channel), Tchannel channel)
+OS_terminal_raw_output (Tchannel channel)
+{
+  CHANNEL_COOKED (channel) = 0;
+}
+\f
+void
+OS_terminal_flush_input (Tchannel channel)
+{
+}
+
+void
+OS_terminal_flush_output (Tchannel channel)
+{
+}
+
+void
+OS_terminal_drain_output (Tchannel channel)
 {
-  CHANNEL_COOKED(channel) = 0;
 }
 \f
 unsigned int
-DEFUN (arg_baud_index, (argument), unsigned int argument)
+arg_baud_index (unsigned int argument)
 {
   return (arg_index_integer (argument, 1));
 }
 
 unsigned int
-DEFUN (OS_terminal_get_ispeed, (channel), Tchannel channel)
+OS_terminal_get_ispeed (Tchannel channel)
 {
   return (0);
 }
 
 unsigned int
-DEFUN (OS_terminal_get_ospeed, (channel), Tchannel channel)
+OS_terminal_get_ospeed (Tchannel channel)
 {
   return (0);
 }
 
 void
-DEFUN (OS_terminal_set_ispeed, (channel, baud),
-       Tchannel channel AND
-       unsigned int baud)
+OS_terminal_set_ispeed (Tchannel channel, unsigned int baud)
 {
-  return;
 }
 
 void
-DEFUN (OS_terminal_set_ospeed, (channel, baud),
-       Tchannel channel AND
-       unsigned int baud)
+OS_terminal_set_ospeed (Tchannel channel, unsigned int baud)
 {
-  return;
 }
 
 unsigned int
-DEFUN (OS_baud_index_to_rate, (index), unsigned int index)
+OS_baud_index_to_rate (unsigned int index)
 {
   return (9600);
 }
 
 int
-DEFUN (OS_baud_rate_to_index, (rate), unsigned int rate)
+OS_baud_rate_to_index (unsigned int rate)
 {
   return ((rate == 9600) ? 0 : -1);
 }
 
 unsigned int
-DEFUN_VOID (OS_terminal_state_size)
+OS_terminal_state_size (void)
 {
   return (3);
 }
 
 void
-DEFUN (OS_terminal_get_state, (channel, state_ptr),
-       Tchannel channel AND PTR state_ptr)
+OS_terminal_get_state (Tchannel channel, void * state_ptr)
 {
   unsigned char * statep = ((unsigned char *) state_ptr);
-
-  *statep++ = CHANNEL_NONBLOCKING (channel);
-  *statep++ = CHANNEL_BUFFERED (channel);
-  *statep   = CHANNEL_COOKED (channel);
-
-  return;
+  (*statep++) = (CHANNEL_NONBLOCKING (channel));
+  (*statep++) = (CHANNEL_BUFFERED (channel));
+  (*statep)   = (CHANNEL_COOKED (channel));
 }
 
 void
-DEFUN (OS_terminal_set_state, (channel, state_ptr),
-       Tchannel channel AND PTR state_ptr)
+OS_terminal_set_state (Tchannel channel, void * state_ptr)
 {
   unsigned char * statep = ((unsigned char *) state_ptr);
-
-  CHANNEL_NONBLOCKING (channel) = *statep++;
-  CHANNEL_BUFFERED (channel)    = *statep++;
-  CHANNEL_COOKED (channel)      = *statep;
-
-  return;
+  (CHANNEL_NONBLOCKING (channel)) = (*statep++);
+  (CHANNEL_BUFFERED (channel))    = (*statep++);
+  (CHANNEL_COOKED (channel))      = (*statep);
 }
 
-#ifndef FALSE
-#  define FALSE 0
-#endif
-
 int
-DEFUN_VOID (OS_job_control_p)
+OS_job_control_p (void)
 {
-  return (FALSE);
+  return (0);
 }
 
 int
-DEFUN_VOID (OS_have_ptys_p)
+OS_have_ptys_p (void)
 {
-  return (FALSE);
+  return (0);
 }
 \f
 /* Initialization/Termination code. */
@@ -552,49 +608,25 @@ extern void EXFUN (NT_reset_channels, (void));
 extern void EXFUN (NT_restore_channels, (void));
 
 void
-DEFUN_VOID (NT_reset_channels)
+NT_reset_channels (void)
 {
-  free (channel_table);
-  channel_table = 0;
+  OS_free (NT_channel_table);
+  NT_channel_table = 0;
   OS_channel_table_size = 0;
-  return;
 }
 
 void
-DEFUN_VOID (NT_restore_channels)
+NT_restore_channels (void)
 {
   if (master_tty_window != ((HANDLE) NULL))
     Screen_Destroy (TRUE, master_tty_window);
   master_tty_window = ((HANDLE) NULL);
-  return;
 }
 \f
 void
-DEFUN_VOID (NT_initialize_channels)
+NT_initialize_channels (void)
 {
-#ifndef GUI
-  STDIN_HANDLE  = (GetStdHandle (STD_INPUT_HANDLE));
-  STDOUT_HANDLE = (GetStdHandle (STD_OUTPUT_HANDLE));
-  STDERR_HANDLE = (GetStdHandle (STD_ERROR_HANDLE));
-
-  if (STDIN_HANDLE == INVALID_HANDLE_VALUE  ||
-      STDOUT_HANDLE == INVALID_HANDLE_VALUE  ||
-      STDERR_HANDLE == INVALID_HANDLE_VALUE)
-  {
-    outf_fatal ("\nUnable to get standard handles %s(%d).\n",
-                __FILE__, __LINE__);
-    termination_init_error ();
-  }
-
-  SetConsoleMode (STDIN_HANDLE,
-                 (  ENABLE_LINE_INPUT
-                  | ENABLE_ECHO_INPUT
-                  | ENABLE_PROCESSED_INPUT));
-  SetConsoleCtrlHandler (NT_ctrl_handler, TRUE);
-#endif /* GUI */
-
-  master_tty_window = Screen_Create (NULL, "MIT Scheme", SW_SHOWNORMAL);
-
+  master_tty_window = (Screen_Create (NULL, "MIT Scheme", SW_SHOWNORMAL));
   if (win32_under_win32s_p ())
     OS_have_select_p = 0;
   else
@@ -604,16 +636,16 @@ DEFUN_VOID (NT_initialize_channels)
      place a limit on the number of handles.  */
   (void) SetHandleCount (255);
   OS_channel_table_size = NT_DEFAULT_CHANNEL_TABLE_SIZE;
-  channel_table = (malloc (OS_channel_table_size * (sizeof (struct channel))));
-  if (channel_table == 0)
-  {
-    outf_fatal ("\nUnable to allocate channel table.\n");
-    termination_init_error ();
-  }
+  NT_channel_table
+    = (OS_malloc (OS_channel_table_size * (sizeof (struct channel))));
   {
     Tchannel channel;
     for (channel = 0; (channel < OS_channel_table_size); channel += 1)
       MARK_CHANNEL_CLOSED (channel);
   }
   add_reload_cleanup (NT_channel_close_all);
+  initialize_channel_class_generic ();
+  initialize_channel_class_file ();
+  initialize_channel_class_screen ();
+  initialize_channel_class_pipe ();
 }
index 63b0285419998b5fe2d3e75dd338fa38a2cdee3c..52646ff13d90d9436e687fd2c189acbf169fb46a 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: ntio.h,v 1.8 1997/10/22 05:23:25 cph Exp $
+$Id: ntio.h,v 1.9 1997/10/24 07:25:01 cph Exp $
 
 Copyright (c) 1992-97 Massachusetts Institute of Technology
 
@@ -34,37 +34,67 @@ MIT in each case. */
 
 #ifndef SCM_NTIO_H
 #define SCM_NTIO_H
-
+\f
 #include "osio.h"
 
-struct channel
+typedef long channel_op_read (Tchannel, void *, unsigned long);
+typedef long channel_op_write (Tchannel, const void *, unsigned long);
+typedef void channel_op_close (Tchannel, int);
+typedef long channel_op_n_read (Tchannel);
+
+typedef struct _channel_class_t
 {
-  HANDLE   handle;
   enum channel_type type;
+  channel_op_read * op_read;
+  channel_op_write * op_write;
+  channel_op_close * op_close;
+  channel_op_n_read * op_n_read;
+} channel_class_t;
+
+#define CHANNEL_CLASS_TYPE(class) ((class) -> type)
+#define CHANNEL_CLASS_OP_READ(class) ((class) -> op_read)
+#define CHANNEL_CLASS_OP_WRITE(class) ((class) -> op_write)
+#define CHANNEL_CLASS_OP_CLOSE(class) ((class) -> op_close)
+#define CHANNEL_CLASS_OP_N_READ(class) ((class) -> op_n_read)
+
+struct channel
+{
+  channel_class_t * class;
+  HANDLE handle;
   unsigned int internal : 1;
   unsigned int nonblocking : 1;
   unsigned int buffered : 1;
   unsigned int cooked : 1;
 };
 
-#define MARK_CHANNEL_CLOSED(chan) ((CHANNEL_HANDLE (chan)) =  (HANDLE)(-1))
-#define CHANNEL_CLOSED_P(chan)    ((CHANNEL_HANDLE (chan)) == (HANDLE)(-1))
-#define CHANNEL_OPEN_P(chan)      ((CHANNEL_HANDLE (chan)) != (HANDLE)(-1))
-#define CHANNEL_HANDLE(channel) ((channel_table [channel]) . handle)
-#define CHANNEL_TYPE(channel) ((channel_table [(channel)]) . type)
-#define CHANNEL_INTERNAL(channel) ((channel_table [(channel)]) . internal)
-#define CHANNEL_NONBLOCKING(channel)                                   \
-  ((channel_table [(channel)]) . nonblocking)
-#define CHANNEL_BLOCKING_P(channel)                                    \
-  (!CHANNEL_NONBLOCKING(channel))
-#define CHANNEL_BUFFERED(channel) ((channel_table [(channel)]) . buffered)
-#define CHANNEL_COOKED(channel) ((channel_table [(channel)]) . cooked)
-
-extern struct channel * channel_table;
-extern Tchannel NT_make_channel (HANDLE, enum channel_type);
-extern void NT_initialize_channel (Tchannel, HANDLE, enum channel_type);
+#define CHANNEL_CLASS(c) ((NT_channel_table[c]) . class)
+#define CHANNEL_HANDLE(c) ((NT_channel_table[c]) . handle)
+#define CHANNEL_INTERNAL(c) ((NT_channel_table[c]) . internal)
+#define CHANNEL_NONBLOCKING(c) ((NT_channel_table[c]) . nonblocking)
+#define CHANNEL_BUFFERED(c) ((NT_channel_table[c]) . buffered)
+#define CHANNEL_COOKED(c) ((NT_channel_table[c]) . cooked)
+
+#define CHANNEL_TYPE(channel) (CHANNEL_CLASS_TYPE (CHANNEL_CLASS (channel)))
+#define MARK_CHANNEL_CLOSED(channel)                                   \
+  ((CHANNEL_HANDLE (channel)) = INVALID_HANDLE_VALUE)
+#define CHANNEL_CLOSED_P(channel)                                      \
+  ((CHANNEL_HANDLE (channel)) == INVALID_HANDLE_VALUE)
+#define CHANNEL_OPEN_P(channel)                                                \
+  ((CHANNEL_HANDLE (channel)) != INVALID_HANDLE_VALUE)
+#define CHANNEL_BLOCKING_P(channel) (!CHANNEL_NONBLOCKING (channel))
+
+extern channel_class_t * NT_channel_class_generic;
+extern channel_class_t * NT_channel_class_file;
+extern channel_class_t * NT_channel_class_screen;
+extern channel_class_t * NT_channel_class_console;
+extern channel_class_t * NT_channel_class_pipe;
+extern struct channel * NT_channel_table;
+
+extern Tchannel NT_make_channel (HANDLE, channel_class_t *);
+extern channel_class_t * NT_handle_channel_class (HANDLE);
+extern Tchannel NT_open_handle (HANDLE);
 extern void NT_handle_close_on_abort (HANDLE);
-extern long NT_pipe_channel_available (Tchannel);
+extern long NT_channel_n_read (Tchannel);
 
 #define BACKSPACE              '\b'
 #define SPACE                  ' '
index 531cc2c9c1e02fb7f467f2d3fdb6137c88d4ab2a..77175fdcfe3d77bfdcb72d7a0db5d9191761f1d5 100644 (file)
@@ -1,8 +1,8 @@
 /* -*-C-*-
 
-$Id: nttty.c,v 1.6 1996/10/02 18:58:24 cph Exp $
+$Id: nttty.c,v 1.7 1997/10/24 07:25:05 cph Exp $
 
-Copyright (c) 1992-96 Massachusetts Institute of Technology
+Copyright (c) 1992-97 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -53,65 +53,50 @@ static char * tty_command_beep;
 static char * tty_command_clear;
 
 Tchannel
-DEFUN_VOID (OS_tty_input_channel)
+OS_tty_input_channel (void)
 {
   return (input_channel);
 }
 
 Tchannel
-DEFUN_VOID (OS_tty_output_channel)
+OS_tty_output_channel (void)
 {
   return (output_channel);
 }
 
 unsigned int
-DEFUN_VOID (OS_tty_x_size)
+OS_tty_x_size (void)
 {
-  Screen_GetSize (master_tty_window, &tty_y_size, &tty_x_size);
+  Screen_GetSize (master_tty_window, (&tty_y_size), (&tty_x_size));
   return (tty_x_size);
 }
 
 unsigned int
-DEFUN_VOID (OS_tty_y_size)
+OS_tty_y_size (void)
 {
-  Screen_GetSize (master_tty_window, &tty_y_size, &tty_x_size);
+  Screen_GetSize (master_tty_window, (&tty_y_size), (&tty_x_size));
   return (tty_y_size);
 }
 
 CONST char *
-DEFUN_VOID (OS_tty_command_beep)
+OS_tty_command_beep (void)
 {
   return (tty_command_beep);
 }
 
 CONST char *
-DEFUN_VOID (OS_tty_command_clear)
+OS_tty_command_clear (void)
 {
   return (tty_command_clear);
 }
-\f
-#ifndef TERMCAP_BUFFER_SIZE
-#define TERMCAP_BUFFER_SIZE 0
-#endif
-
-#ifndef DEFAULT_TTY_X_SIZE
-#define DEFAULT_TTY_X_SIZE 80
-#endif
-
-#ifndef DEFAULT_TTY_Y_SIZE
-#define DEFAULT_TTY_Y_SIZE 25
-#endif
 
 void
-DEFUN_VOID (NT_initialize_tty)
+NT_initialize_tty (void)
 {
-  extern Tchannel EXFUN (OS_open_handle, (int fd));
-  input_channel  = (OS_open_handle ((int) master_tty_window));
+  input_channel = (NT_open_handle (master_tty_window));
   (CHANNEL_INTERNAL (input_channel)) = 1;
   output_channel = input_channel;
-  (CHANNEL_INTERNAL (output_channel)) = 1;
-  Screen_GetSize (master_tty_window, &tty_y_size, &tty_x_size);
-
+  Screen_GetSize (master_tty_window, (&tty_y_size), (&tty_x_size));
   tty_command_beep = ALERT_STRING;
   tty_command_clear = "\014";
 }
index 21a9f167f877c969597263d70271e10c9468ecc7..3aa75be6649afb163766b6a7db9c963e9bce633c 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: prntio.c,v 1.7 1997/10/22 05:27:26 cph Exp $
+$Id: prntio.c,v 1.8 1997/10/24 07:24:34 cph Exp $
 
 Copyright (c) 1993-97 Massachusetts Institute of Technology
 
@@ -172,16 +172,18 @@ wait_for_multiple_objects_1 (unsigned long n_channels, Tchannel * channels,
        unsigned int index;
        for (index = 0; (index < n_channels); index += 1)
          if ((index != console_index)
-             && (((CHANNEL_TYPE (channels[index])) != channel_type_win32_pipe)
-                 || ((NT_pipe_channel_available (channels[index])) != 0)))
+             && ((NT_channel_n_read (channels[index])) != (-1)))
            return (index);
       }
       if (OS_process_any_status_change ())
        return (-3);
       if (!blockp)
        return (-1);
+      /* Block waiting for a message to arrive.  The asynchronous
+        interrupt thread guarantees that a message will arrive in a
+        reasonable amount of time.  */
       if ((MsgWaitForMultipleObjects (0, 0, FALSE, INFINITE, QS_ALLINPUT))
-         != WAIT_OBJECT_0)
+         == WAIT_FAILED)
        NT_error_api_call
          ((GetLastError ()), apicall_MsgWaitForMultipleObjects);
     }