Add code to create anonymous pipes, to determine how many characters
authorChris Hanson <org/chris-hanson/cph>
Wed, 22 Oct 1997 05:23:25 +0000 (05:23 +0000)
committerChris Hanson <org/chris-hanson/cph>
Wed, 22 Oct 1997 05:23:25 +0000 (05:23 +0000)
are in the pipe given the read end of the pipe, and to implement
non-blocking mode when reading a pipe.  Fix OS_channel_write to
generate correct error messages.

v7/src/microcode/ntio.c
v7/src/microcode/ntio.h

index 0ca9b03eb9cc2c046688a03512b4eaebab40477b..68516263100bac25c9ed65c681364a7d15a1c0ff 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: ntio.c,v 1.16 1997/08/24 04:05:49 cph Exp $
+$Id: ntio.c,v 1.17 1997/10/22 05:23:18 cph Exp $
 
 Copyright (c) 1992-97 Massachusetts Institute of Technology
 
@@ -251,6 +251,13 @@ DEFUN (OS_channel_read, (channel, buffer, nbytes),
          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)),
@@ -266,91 +273,78 @@ DEFUN (OS_channel_read, (channel, buffer, nbytes),
       }
     }
 }
+
+long
+NT_pipe_channel_available (Tchannel channel)
+{
+  DWORD n;
+  if (!PeekNamedPipe ((CHANNEL_HANDLE (channel)), 0, 0, 0, (&n), 0))
+    {
+      DWORD code = (GetLastError ());
+      if (code == ERROR_BROKEN_PIPE)
+       return (-1);
+      NT_error_api_call (code, apicall_PeekNamedPipe);
+    }
+  return (n);
+}
 \f
-static int
-DEFUN (raw_write, (fd, buffer, nbytes),
-       HANDLE fd AND CONST unsigned char * buffer AND DWORD nbytes)
+static DWORD
+raw_write (HANDLE fd, const unsigned char * buffer, size_t n_bytes)
 {
-  DWORD bytesWritten;
+  DWORD n_written;
   if (Screen_IsScreenHandle (fd))
-  {
-    SendMessage (fd, SCREEN_WRITE, (WPARAM)nbytes, (LPARAM)buffer);
-    return (nbytes);
-  }
+    {
+      SendMessage (fd, SCREEN_WRITE, ((WPARAM) n_bytes), ((LPARAM) buffer));
+      return (n_bytes);
+    }
   if (IsConsoleHandle (fd))
-    return (nt_console_write (((void *) buffer), nbytes));
-  if (WriteFile (fd, buffer, nbytes, &bytesWritten, 0))
-    return (bytesWritten);
-  else
-    return (-1);
+    return (nt_console_write (((void *) buffer), n_bytes));
+  STD_BOOL_API_CALL (WriteFile, (fd, buffer, n_bytes, (&n_written), 0));
+  return (n_written);
 }
 
-#define SYSCALL_WRITE(fd, buffer, size, so_far) do                     \
-{                                                                      \
-  size_t _size = (size);                                               \
-  int _written;                                                                \
-  _written = raw_write ((fd), (buffer), (_size));                      \
-  if (_size != ((size_t) _written))                                    \
-    return ((_written < 0) ? -1 : (so_far) + _written);                        \
-} while (0)
+static DWORD
+text_write (HANDLE hFile, const unsigned char * buffer, size_t 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);
 
-long
-DEFUN (text_write, (hFile, buffer, nbytes),
-       HANDLE hFile AND CONST unsigned char * buffer AND size_t nbytes)
-{ /* Map LF to CR/LF */
-  static CONST unsigned char crlf[] = {CARRIAGE_RETURN, LINEFEED};
-  CONST unsigned char * start;
-  size_t i;
-
-  for (i = 0, start = buffer; i < nbytes; start = &buffer[i])
-  { size_t len;
-
-    while ((i < nbytes) && (buffer[i] != LINEFEED))
-      i++;
-    len = (&buffer[i] - start);
-
-    if (len != 0)
-      SYSCALL_WRITE (hFile, start, len, (i - len));
-
-    if ((i < nbytes) && (buffer[i] == LINEFEED))
-    { /* We are sitting on a linefeed. Write out CRLF */
-      /* This backs out incorrectly if only CR is written out */
-      SYSCALL_WRITE (hFile, crlf, (sizeof (crlf)), i);
-      i = i + 1; /* Skip over special character */
+  while (start < end)
+    {
+      const unsigned char * scan = start;
+      while ((scan < end) && ((*scan) != LINEFEED))
+       scan += 1;
+      if (scan > start)
+       {
+         unsigned int n_bytes = (scan - start);
+         DWORD n_written = (raw_write (hFile, start, n_bytes));
+         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));
+         if (n_written < n_bytes)
+           /* This backs out incorrectly if only CR is written out.  */
+           return (scan - buffer);
+       }
+      start = (scan + 1);
     }
-  }
-  return (nbytes);
+  return (n_bytes);
 }
 
-#undef SYSCALL_WRITE
-
 long
-DEFUN (OS_channel_write, (channel, buffer, nbytes),
-       Tchannel channel AND CONST PTR buffer AND size_t nbytes)
+OS_channel_write (Tchannel channel, const void * buffer, size_t n_bytes)
 {
-  if (nbytes == 0)
-    return (0);
-
-  while (1)
-  {
-    HANDLE  hFile;
-    long    scr;
-
-    hFile = CHANNEL_HANDLE(channel);
-    scr = ((CHANNEL_COOKED (channel))
-          ? (text_write (hFile, buffer, nbytes))
-          : (raw_write (hFile, buffer, nbytes)));
-
-    if (scr < 0)
-    {
-      NT_prim_check_errno (syscall_write);
-      continue;
-    }
-
-    if (scr > nbytes)
-      error_external_return ();
-    return scr;
-  }
+  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
@@ -384,21 +378,19 @@ DEFUN (OS_channel_write_string, (channel, string),
 }
 
 void
-DEFUN (OS_make_pipe, (readerp, writerp),
-       Tchannel * readerp AND
-       Tchannel * writerp)
+OS_make_pipe (Tchannel * readerp, Tchannel * writerp)
 {
-/*
   HANDLE hread;
   HANDLE hwrite;
-  SECURITY_ATTRIBUTES sa;
-
-  (sa . nLength) = (sizeof (sa));
-  (sa . lpSecurityDescriptor) = 0;
-  (sa . bInheritHandle) = FALSE;
-
-  (CreatePipe ((&hread), (&hwrite), (&sa), 0))
-*/
+  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
index 58d5b1e33b17f3c4ef6dbb049503f69bf1a24ba1..63b0285419998b5fe2d3e75dd338fa38a2cdee3c 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: ntio.h,v 1.7 1997/06/19 05:55:51 cph Exp $
+$Id: ntio.h,v 1.8 1997/10/22 05:23:25 cph Exp $
 
 Copyright (c) 1992-97 Massachusetts Institute of Technology
 
@@ -64,6 +64,7 @@ extern struct channel * channel_table;
 extern Tchannel NT_make_channel (HANDLE, enum channel_type);
 extern void NT_initialize_channel (Tchannel, HANDLE, enum channel_type);
 extern void NT_handle_close_on_abort (HANDLE);
+extern long NT_pipe_channel_available (Tchannel);
 
 #define BACKSPACE              '\b'
 #define SPACE                  ' '