From 7e56d6d07ecd1b014e9e481a8612fd2f6c017f5c Mon Sep 17 00:00:00 2001 From: Chris Hanson Date: Wed, 22 Oct 1997 05:23:25 +0000 Subject: [PATCH] Add code to create anonymous pipes, to determine how many characters 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 | 164 +++++++++++++++++++--------------------- v7/src/microcode/ntio.h | 3 +- 2 files changed, 80 insertions(+), 87 deletions(-) diff --git a/v7/src/microcode/ntio.c b/v7/src/microcode/ntio.c index 0ca9b03eb..685162631 100644 --- a/v7/src/microcode/ntio.c +++ b/v7/src/microcode/ntio.c @@ -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); +} -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))); } 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 (); } int diff --git a/v7/src/microcode/ntio.h b/v7/src/microcode/ntio.h index 58d5b1e33..63b028541 100644 --- a/v7/src/microcode/ntio.h +++ b/v7/src/microcode/ntio.h @@ -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 ' ' -- 2.25.1