From 6defbaaaaa641754a8401d54181bf6fe7d3e99f6 Mon Sep 17 00:00:00 2001 From: Chris Hanson Date: Fri, 24 Oct 1997 07:25:05 +0000 Subject: [PATCH] * Change channel data structure. Now, instead of being tagged with a "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 | 175 +++--------- v7/src/microcode/ntio.c | 584 ++++++++++++++++++++------------------ v7/src/microcode/ntio.h | 72 +++-- v7/src/microcode/nttty.c | 41 +-- v7/src/microcode/prntio.c | 10 +- 5 files changed, 421 insertions(+), 461 deletions(-) diff --git a/v7/src/microcode/ntfile.c b/v7/src/microcode/ntfile.c index 486e4c619..b781dc88f 100644 --- a/v7/src/microcode/ntfile.c +++ b/v7/src/microcode/ntfile.c @@ -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)); -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)); } 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 (); } diff --git a/v7/src/microcode/ntio.c b/v7/src/microcode/ntio.c index 685162631..d69a23d33 100644 --- a/v7/src/microcode/ntio.c +++ b/v7/src/microcode/ntio.c @@ -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) ; #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); +} + +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)); +} + 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; } } - + 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)); } -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; +} + +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; +} + +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); } - -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) + +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))); -} 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 (); -} 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; +} + +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; } 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); } /* 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; } 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 (); } diff --git a/v7/src/microcode/ntio.h b/v7/src/microcode/ntio.h index 63b028541..52646ff13 100644 --- a/v7/src/microcode/ntio.h +++ b/v7/src/microcode/ntio.h @@ -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 - + #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 ' ' diff --git a/v7/src/microcode/nttty.c b/v7/src/microcode/nttty.c index 531cc2c9c..77175fdcf 100644 --- a/v7/src/microcode/nttty.c +++ b/v7/src/microcode/nttty.c @@ -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); } - -#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"; } diff --git a/v7/src/microcode/prntio.c b/v7/src/microcode/prntio.c index 21a9f167f..3aa75be66 100644 --- a/v7/src/microcode/prntio.c +++ b/v7/src/microcode/prntio.c @@ -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); } -- 2.25.1