--- /dev/null
+/* -*-C-*-
+
+$Id: os2.c,v 1.1 1994/11/28 03:42:53 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+\f
+void *
+OS_malloc (unsigned int size)
+{
+ void * result = (malloc (size));
+ if (result == 0)
+ OS2_error_system_call (ERROR_NOT_ENOUGH_MEMORY, syscall_malloc);
+ return (result);
+}
+
+void *
+OS_realloc (void * ptr, unsigned int size)
+{
+ void * result = (realloc (ptr, size));
+ if (result == 0)
+ OS2_error_system_call (ERROR_NOT_ENOUGH_MEMORY, syscall_realloc);
+ return (result);
+}
+
+void
+OS_free (void * ptr)
+{
+ free (ptr);
+}
+\f
+HMTX
+OS2_create_mutex_semaphore (void)
+{
+ HMTX result;
+ STD_API_CALL (dos_create_mutex_sem, (0, (&result), 0, 0));
+ return (result);
+}
+
+void
+OS2_close_mutex_semaphore (HMTX s)
+{
+ STD_API_CALL (dos_close_mutex_sem, (s));
+}
+
+void
+OS2_request_mutex_semaphore (HMTX s)
+{
+ STD_API_CALL (dos_request_mutex_sem, (s, SEM_INDEFINITE_WAIT));
+}
+
+void
+OS2_release_mutex_semaphore (HMTX s)
+{
+ STD_API_CALL (dos_release_mutex_sem, (s));
+}
+
+HEV
+OS2_create_event_semaphore (void)
+{
+ HEV result;
+ STD_API_CALL (dos_create_event_sem, (0, (&result), 0, 0));
+ return (result);
+}
+
+void
+OS2_close_event_semaphore (HEV s)
+{
+ STD_API_CALL (dos_close_event_sem, (s));
+}
+
+int
+OS2_post_event_semaphore (HEV s)
+{
+ XTD_API_CALL
+ (dos_post_event_sem, (s),
+ {
+ if (rc == ERROR_ALREADY_POSTED)
+ return (1);
+ });
+ return (0);
+}
+
+ULONG
+OS2_reset_event_semaphore (HEV s)
+{
+ ULONG post_count;
+ XTD_API_CALL
+ (dos_reset_event_sem, (s, (&post_count)),
+ {
+ if (rc == ERROR_ALREADY_RESET)
+ return (0);
+ });
+ return (post_count);
+}
+
+int
+OS2_wait_event_semaphore (HEV s, int blockp)
+{
+ XTD_API_CALL
+ (dos_wait_event_sem,
+ (s, (blockp ? SEM_INDEFINITE_WAIT : SEM_IMMEDIATE_RETURN)),
+ {
+ if ((rc == ERROR_TIMEOUT) && (!blockp))
+ return (0);
+ });
+ return (1);
+}
+\f
+HQUEUE
+OS2_create_queue (ULONG priority)
+{
+ static unsigned int n = 0;
+ char buffer [64];
+ HQUEUE result;
+ sprintf (buffer, "\\queues\\scm%d\\%d.que", OS2_scheme_pid, (n++));
+ STD_API_CALL (dos_create_queue, ((&result), priority, buffer));
+ return (result);
+}
+
+void
+OS2_close_queue (HQUEUE q)
+{
+ STD_API_CALL (dos_close_queue, (q));
+}
+
+void
+OS2_write_queue (HQUEUE q, ULONG type, ULONG length, PVOID data, ULONG priority)
+{
+ STD_API_CALL (dos_write_queue, (q, type, length, data, priority));
+}
+
+int
+OS2_read_queue (HQUEUE q, ULONG * type, ULONG * length, PVOID * data, HEV s)
+{
+ REQUESTDATA request;
+ BYTE priority;
+ (request.pid) = OS2_scheme_pid;
+ if (s != NULLHANDLE)
+ (void) OS2_reset_event_semaphore (s);
+ XTD_API_CALL
+ (dos_read_queue,
+ (q, (&request), length, data, 0,
+ ((s == NULLHANDLE) ? DCWW_WAIT : DCWW_NOWAIT), (&priority), s),
+ {
+ if ((rc == ERROR_QUE_EMPTY) && (s != NULLHANDLE))
+ return (0);
+ });
+ (*type) = (request.ulData);
+ return (1);
+}
+
+ULONG
+OS2_system_variable (ULONG index)
+{
+ ULONG result;
+ STD_API_CALL
+ (dos_query_sys_info, (index, index, (&result), (sizeof (result))));
+ return (result);
+}
+
+void
+OS2_logic_error_1 (const char * description,
+ const char * file,
+ unsigned int line)
+{
+ outf_fatal ("\nFatal error in file \"%s\", line %d:\n%s\nGet a wizard.\n",
+ description, file, line);
+ termination_init_error ();
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2.h,v 1.1 1994/11/28 03:42:53 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+/* OS/2 system include file */
+
+#ifndef SCM_OS2_H
+#define SCM_OS2_H
+
+#include "dstack.h"
+#include "osscheme.h"
+#include "syscall.h"
+
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_KBD
+#define INCL_VIO
+#include <os2.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <setjmp.h>
+#include <limits.h>
+
+#include "os2api.h"
+#include "os2msg.h"
+#include "os2io.h"
+#include "os2thrd.h"
+#include "os2ctty.h"
+#include "os2cthrd.h"
+
+#define OS2_MAX_FILE_HANDLES() 20
+
+#define FILE_ANY \
+ (FILE_NORMAL | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED)
+
+extern HMTX OS2_create_mutex_semaphore (void);
+extern void OS2_close_mutex_semaphore (HMTX);
+extern void OS2_request_mutex_semaphore (HMTX);
+extern void OS2_release_mutex_semaphore (HMTX);
+
+extern HEV OS2_create_event_semaphore (void);
+extern void OS2_close_event_semaphore (HEV);
+extern int OS2_post_event_semaphore (HEV);
+extern ULONG OS2_reset_event_semaphore (HEV);
+extern int OS2_wait_event_semaphore (HEV, int);
+
+extern HQUEUE OS2_create_queue (ULONG);
+extern void OS2_close_queue (HQUEUE);
+extern void OS2_write_queue (HQUEUE, ULONG, ULONG, PVOID, ULONG);
+extern int OS2_read_queue (HQUEUE, ULONG *, ULONG *, PVOID *, HEV);
+
+extern ULONG OS2_system_variable (ULONG);
+
+/* Logic errors are fatal and can't be caught. These are errors that
+ should never happen, and if one does occur the program cannot
+ proceed. */
+#define OS2_logic_error(d) OS2_logic_error_1 ((d), __FILE__, __LINE__)
+extern void OS2_logic_error_1 (const char *, const char *, unsigned int);
+
+#endif /* SCM_OS2_H */
--- /dev/null
+/* -*-C-*-
+
+$Id: os2api.h,v 1.1 1994/11/28 03:42:54 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_OS2API_H
+#define SCM_OS2API_H
+
+#define XTD_API_CALL(proc, args, if_error) \
+{ \
+ while (1) \
+ { \
+ APIRET rc = (proc args); \
+ if (rc == NO_ERROR) \
+ break; \
+ if (rc != ERROR_INTERRUPT) \
+ { \
+ if_error; \
+ OS2_error_system_call (rc, syscall_ ## proc); \
+ } \
+ } \
+}
+
+#define STD_API_CALL(proc, args) XTD_API_CALL (proc, args, {})
+
+#ifdef CLOSED_API_CALLS
+
+extern APIRET dos_async_timer (ULONG, HSEM, PHTIMER);
+extern APIRET dos_close (HFILE);
+extern APIRET dos_close_event_sem (HEV);
+extern APIRET dos_close_mutex_sem (HMTX);
+extern APIRET dos_close_queue (HQUEUE);
+extern APIRET dos_create_dir (PSZ, PEAOP2);
+extern APIRET dos_create_event_sem (PSZ, PHEV, ULONG, BOOL32);
+extern APIRET dos_create_mutex_sem (PSZ, PHMTX, ULONG, BOOL32);
+extern APIRET dos_create_pipe (PHFILE, PHFILE, ULONG);
+extern APIRET dos_create_queue (PHQUEUE, ULONG, PSZ);
+extern APIRET dos_create_thread (PTID, PFNTHREAD, ULONG, ULONG, ULONG);
+extern APIRET dos_delete (PSZ);
+extern APIRET dos_delete_dir (PSZ);
+extern void dos_exit (ULONG, ULONG);
+extern APIRET dos_find_close (HDIR);
+extern APIRET dos_find_first (PSZ, PHDIR, ULONG, PVOID, ULONG, PULONG, ULONG);
+extern APIRET dos_find_next (HDIR, PVOID, ULONG, PULONG);
+extern APIRET dos_get_info_blocks (PTIB *, PPIB *);
+extern APIRET dos_get_message (PCHAR *, ULONG, PCHAR, ULONG, ULONG, PSZ, PULONG);
+extern APIRET dos_kill_thread (TID);
+extern APIRET dos_move (PSZ, PSZ);
+extern APIRET dos_open (PSZ, PHFILE, PULONG, ULONG, ULONG, ULONG, ULONG, PEAOP2);
+extern APIRET dos_post_event_sem (HEV);
+extern APIRET dos_query_current_dir (ULONG, PBYTE, PULONG);
+extern APIRET dos_query_current_disk (PULONG, PULONG);
+extern APIRET dos_query_file_info (HFILE, ULONG, PVOID, ULONG);
+extern APIRET dos_query_h_type (HFILE, PULONG, PULONG);
+extern APIRET dos_query_n_p_h_state (HPIPE, PULONG);
+extern APIRET dos_query_path_info (PSZ, ULONG, PVOID, ULONG);
+extern APIRET dos_query_sys_info (ULONG, ULONG, PVOID, ULONG);
+extern APIRET dos_read (HFILE, PVOID, ULONG, PULONG);
+extern APIRET dos_read_queue (HQUEUE, PREQUESTDATA, PULONG, PPVOID, ULONG, BOOL32, PBYTE, HEV);
+extern APIRET dos_release_mutex_sem (HMTX);
+extern APIRET dos_request_mutex_sem (HMTX, ULONG);
+extern APIRET dos_reset_event_sem (HEV, PULONG);
+extern APIRET dos_scan_env (PSZ, PSZ *);
+extern APIRET dos_set_current_dir (PSZ);
+extern APIRET dos_set_default_disk (ULONG);
+extern APIRET dos_set_file_ptr (HFILE, LONG, ULONG, PULONG);
+extern APIRET dos_set_file_size (HFILE, ULONG);
+extern APIRET dos_set_path_info (PSZ, ULONG, PVOID, ULONG, ULONG);
+extern APIRET dos_start_timer (ULONG, HSEM, PHTIMER);
+extern APIRET dos_stop_timer (PHTIMER);
+extern APIRET dos_wait_event_sem (HEV, ULONG);
+extern APIRET dos_write (HFILE, PVOID, ULONG, PULONG);
+extern APIRET dos_write_queue (HQUEUE, ULONG, ULONG, PVOID, ULONG);
+extern APIRET kbd_char_in (PKBDKEYINFO, USHORT, HKBD);
+extern APIRET vio_wrt_tty (PCH, USHORT, HVIO);
+
+#else /* not CLOSED_API_CALLS */
+
+#define dos_async_timer DosAsyncTimer
+#define dos_close DosClose
+#define dos_close_event_sem DosCloseEventSem
+#define dos_close_mutex_sem DosCloseMutexSem
+#define dos_close_queue DosCloseQueue
+#define dos_create_dir DosCreateDir
+#define dos_create_event_sem DosCreateEventSem
+#define dos_create_mutex_sem DosCreateMutexSem
+#define dos_create_pipe DosCreatePipe
+#define dos_create_queue DosCreateQueue
+#define dos_create_thread DosCreateThread
+#define dos_delete DosDelete
+#define dos_delete_dir DosDeleteDir
+#define dos_exit DosExit
+#define dos_find_close DosFindClose
+#define dos_find_first DosFindFirst
+#define dos_find_next DosFindNext
+#define dos_get_info_blocks DosGetInfoBlocks
+#define dos_get_message DosGetMessage
+#define dos_kill_thread DosKillThread
+#define dos_move DosMove
+#define dos_open DosOpen
+#define dos_post_event_sem DosPostEventSem
+#define dos_query_current_dir DosQueryCurrentDir
+#define dos_query_current_disk DosQueryCurrentDisk
+#define dos_query_file_info DosQueryFileInfo
+#define dos_query_h_type DosQueryHType
+#define dos_query_n_p_h_state DosQueryNPHState
+#define dos_query_path_info DosQueryPathInfo
+#define dos_query_sys_info DosQuerySysInfo
+#define dos_read DosRead
+#define dos_read_queue DosReadQueue
+#define dos_release_mutex_sem DosReleaseMutexSem
+#define dos_request_mutex_sem DosRequestMutexSem
+#define dos_reset_event_sem DosResetEventSem
+#define dos_scan_env DosScanEnv
+#define dos_set_current_dir DosSetCurrentDir
+#define dos_set_default_disk DosSetDefaultDisk
+#define dos_set_file_ptr DosSetFilePtr
+#define dos_set_file_size DosSetFileSize
+#define dos_set_path_info DosSetPathInfo
+#define dos_start_timer DosStartTimer
+#define dos_stop_timer DosStopTimer
+#define dos_wait_event_sem DosWaitEventSem
+#define dos_write DosWrite
+#define dos_write_queue DosWriteQueue
+#define kbd_char_in KbdCharIn
+#define vio_wrt_tty VioWrtTTY
+
+#define syscall_dos_async_timer syscall_DosAsyncTimer
+#define syscall_dos_close syscall_DosClose
+#define syscall_dos_close_event_sem syscall_DosCloseEventSem
+#define syscall_dos_close_mutex_sem syscall_DosCloseMutexSem
+#define syscall_dos_close_queue syscall_DosCloseQueue
+#define syscall_dos_create_dir syscall_DosCreateDir
+#define syscall_dos_create_event_sem syscall_DosCreateEventSem
+#define syscall_dos_create_mutex_sem syscall_DosCreateMutexSem
+#define syscall_dos_create_pipe syscall_DosCreatePipe
+#define syscall_dos_create_queue syscall_DosCreateQueue
+#define syscall_dos_create_thread syscall_DosCreateThread
+#define syscall_dos_delete syscall_DosDelete
+#define syscall_dos_delete_dir syscall_DosDeleteDir
+#define syscall_dos_exit syscall_DosExit
+#define syscall_dos_find_close syscall_DosFindClose
+#define syscall_dos_find_first syscall_DosFindFirst
+#define syscall_dos_find_next syscall_DosFindNext
+#define syscall_dos_get_info_blocks syscall_DosGetInfoBlocks
+#define syscall_dos_get_message syscall_DosGetMessage
+#define syscall_dos_kill_thread syscall_DosKillThread
+#define syscall_dos_move syscall_DosMove
+#define syscall_dos_open syscall_DosOpen
+#define syscall_dos_post_event_sem syscall_DosPostEventSem
+#define syscall_dos_query_current_dir syscall_DosQueryCurrentDir
+#define syscall_dos_query_current_disk syscall_DosQueryCurrentDisk
+#define syscall_dos_query_file_info syscall_DosQueryFileInfo
+#define syscall_dos_query_h_type syscall_DosQueryHType
+#define syscall_dos_query_n_p_h_state syscall_DosQueryNPHState
+#define syscall_dos_query_path_info syscall_DosQueryPathInfo
+#define syscall_dos_query_sys_info syscall_DosQuerySysInfo
+#define syscall_dos_read syscall_DosRead
+#define syscall_dos_read_queue syscall_DosReadQueue
+#define syscall_dos_release_mutex_sem syscall_DosReleaseMutexSem
+#define syscall_dos_request_mutex_sem syscall_DosRequestMutexSem
+#define syscall_dos_reset_event_sem syscall_DosResetEventSem
+#define syscall_dos_scan_env syscall_DosScanEnv
+#define syscall_dos_set_current_dir syscall_DosSetCurrentDir
+#define syscall_dos_set_default_disk syscall_DosSetDefaultDisk
+#define syscall_dos_set_file_ptr syscall_DosSetFilePtr
+#define syscall_dos_set_file_size syscall_DosSetFileSize
+#define syscall_dos_set_path_info syscall_DosSetPathInfo
+#define syscall_dos_start_timer syscall_DosStartTimer
+#define syscall_dos_stop_timer syscall_DosStopTimer
+#define syscall_dos_wait_event_sem syscall_DosWaitEventSem
+#define syscall_dos_write syscall_DosWrite
+#define syscall_dos_write_queue syscall_DosWriteQueue
+#define syscall_kbd_char_in syscall_KbdCharIn
+#define syscall_vio_wrt_tty syscall_VioWrtTTY
+#define syscall_VIO16WRTTTY syscall_VioWrtTTY
+
+#endif /* not CLOSED_API_CALLS */
+
+#endif /* SCM_OS2API_H */
--- /dev/null
+/* -*-C-*-
+
+$Id: os2conio.c,v 1.1 1994/11/28 03:42:54 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+#ifdef USE_PMIO
+#include <pmio.h>
+#endif
+\f
+typedef struct line_buffer_s
+{
+ msg_t * message;
+ struct line_buffer_s * next;
+} line_buffer_t;
+
+static void console_thread (void *);
+#ifndef USE_PMIO
+static int getch (void);
+#endif
+static void grab_console_lock (void);
+static void release_console_lock (void);
+
+static void init_line_buffer (void);
+static line_buffer_t * make_line_buffer (line_buffer_t *);
+static void push_line_buffer (void);
+static void pop_line_buffer (void);
+static line_buffer_t * reverse_line_buffer (void);
+
+static void process_input_char (char);
+static void do_rubout (void);
+static void add_to_line (char);
+static void do_newline (void);
+static void do_self_insert (char);
+static void add_char_to_line_buffer (char);
+static void finish_line (void);
+static void send_char (char);
+static void send_readahead (msg_t *);
+static void handle_console_interrupt (msg_t *);
+
+static void console_operator
+ (Tchannel, chop_t, choparg_t, choparg_t, choparg_t);;
+static void flush_input (void);
+static void console_input_buffered (Tchannel, int, int *);
+static void console_output_cooked (Tchannel, int, int *);
+
+static void write_char (char, int);
+static void write_output (const char *, size_t, int);
+static void write_output_1 (const char *, const char *);
+static unsigned int char_output_length (char);
+
+#define LINEFEED '\012'
+
+static HMTX console_lock;
+static int input_buffered_p;
+static int output_cooked_p;
+static qid_t console_writer_qid;
+static channel_context_t * console_context;
+static line_buffer_t * line_buffer;
+
+void
+OS2_initialize_console (void)
+{
+#ifdef USE_PMIO
+ pmio_fontspec = "6.System VIO";
+ set_width (80);
+ set_height (40);
+ start_pmio ();
+#endif
+ console_lock = (OS2_create_mutex_semaphore ());
+ input_buffered_p = 1;
+ output_cooked_p = 1;
+ console_context = (OS2_make_channel_context ());
+ OS2_open_qid ((CHANNEL_CONTEXT_READER_QID (console_context)),
+ OS2_scheme_tqueue);
+ console_writer_qid = (CHANNEL_CONTEXT_WRITER_QID (console_context));
+ OS2_open_qid (console_writer_qid, (OS2_make_std_tqueue ()));
+ (void) OS2_beginthread (console_thread, 0, 0x4000);
+}
+\f
+static void
+console_thread (void * arg)
+{
+ grab_console_lock ();
+ init_line_buffer ();
+ release_console_lock ();
+ (void) OS2_thread_initialize (console_writer_qid);
+ while (1)
+ {
+ int c = (getch ());
+ if (c == EOF)
+ break;
+ {
+ int code = (OS2_keyboard_interrupt_handler (c));
+ if (code == '\0')
+ process_input_char (c);
+ else
+ {
+ msg_t * message = (OS2_create_message (mt_console_interrupt));
+ (SM_CONSOLE_INTERRUPT_CODE (message)) = code;
+ OS2_send_message (OS2_interrupt_qid, message);
+ /* Flush buffers only for certain chars? */
+ flush_input ();
+ }
+ }
+ }
+ OS2_endthread ();
+}
+
+#ifndef USE_PMIO
+static int
+getch (void)
+{
+ while (1)
+ {
+#if 1
+ KBDKEYINFO info;
+ XTD_API_CALL
+ (kbd_char_in, ((&info), IO_WAIT, 0),
+ {
+ if (rc == ERROR_KBD_INVALID_HANDLE)
+ return (EOF);
+ });
+ if ((info . fbStatus) == 0x40)
+ return (info . chChar);
+#else
+ int c = (_getch ());
+ if (c == EOF)
+ return (EOF);
+ else if ((c == 0) || (c == 0xe0))
+ {
+ /* Discard extended keycodes. */
+ if ((_getch ()) == EOF)
+ return (EOF);
+ }
+ else
+ return (c);
+#endif
+ }
+}
+#endif /* not USE_PMIO */
+
+static void
+grab_console_lock (void)
+{
+ OS2_request_mutex_semaphore (console_lock);
+}
+
+static void
+release_console_lock (void)
+{
+ OS2_release_mutex_semaphore (console_lock);
+}
+\f
+static void
+init_line_buffer (void)
+{
+ line_buffer = 0;
+ push_line_buffer ();
+}
+
+static line_buffer_t *
+make_line_buffer (line_buffer_t * next)
+{
+ line_buffer_t * buffer = (OS_malloc (sizeof (line_buffer_t)));
+ msg_t * message = (OS2_make_readahead ());
+ (SM_READAHEAD_SIZE (message)) = 0;
+ (buffer -> message) = message;
+ (buffer -> next) = next;
+ return (buffer);
+}
+
+static void
+push_line_buffer (void)
+{
+ line_buffer = (make_line_buffer (line_buffer));
+}
+
+static void
+pop_line_buffer (void)
+{
+ line_buffer_t * buffer = line_buffer;
+ OS2_destroy_message (buffer -> message);
+ line_buffer = (buffer -> next);
+ OS_free (buffer);
+}
+
+static line_buffer_t *
+reverse_line_buffer (void)
+{
+ line_buffer_t * this = line_buffer;
+ line_buffer_t * prev = 0;
+ line_buffer_t * next;
+ line_buffer = 0;
+ while (1)
+ {
+ next = (this -> next);
+ (this -> next) = prev;
+ if (next == 0)
+ break;
+ prev = this;
+ this = next;
+ }
+ push_line_buffer ();
+ return (this);
+}
+
+#define LINE_BUFFER_SIZE (SM_READAHEAD_SIZE (line_buffer -> message))
+#define LINE_BUFFER_DATA (SM_READAHEAD_DATA (line_buffer -> message))
+\f
+static void
+process_input_char (char c)
+{
+ if (!input_buffered_p)
+ send_char (c);
+ else switch (c)
+ {
+ case '\b':
+ case '\177':
+ do_rubout ();
+ break;
+ case '\r':
+ do_self_insert (LINEFEED);
+ finish_line ();
+ break;
+ default:
+ do_self_insert (c);
+ break;
+ }
+}
+
+static void
+do_self_insert (char c)
+{
+ add_char_to_line_buffer (c);
+ write_char (c, 1);
+}
+
+static void
+add_char_to_line_buffer (char c)
+{
+ grab_console_lock ();
+ if (LINE_BUFFER_SIZE == SM_READAHEAD_MAX)
+ push_line_buffer ();
+ (LINE_BUFFER_DATA [LINE_BUFFER_SIZE ++]) = c;
+ release_console_lock ();
+}
+
+static void
+do_rubout (void)
+{
+ grab_console_lock ();
+ if (LINE_BUFFER_SIZE == 0)
+ {
+ if ((line_buffer -> next) == 0)
+ {
+ release_console_lock ();
+ write_char ('\a', 0);
+ return;
+ }
+ pop_line_buffer ();
+ }
+ {
+ unsigned int n
+ = (char_output_length (LINE_BUFFER_DATA [-- LINE_BUFFER_SIZE]));
+ unsigned int i;
+ release_console_lock ();
+ for (i = 0; (i < n); i += 1)
+ write_char ('\b', 0);
+ for (i = 0; (i < n); i += 1)
+ write_char (' ', 0);
+ for (i = 0; (i < n); i += 1)
+ write_char ('\b', 0);
+ }
+}
+\f
+static void
+finish_line (void)
+{
+ line_buffer_t * buffer;
+ grab_console_lock ();
+ buffer = (reverse_line_buffer ());
+ release_console_lock ();
+ while (buffer != 0)
+ {
+ send_readahead (buffer -> message);
+ buffer = (buffer -> next);
+ OS_free (buffer);
+ }
+}
+
+static void
+send_char (char c)
+{
+ msg_t * message = (OS2_make_readahead ());
+ (SM_READAHEAD_SIZE (message)) = 1;
+ ((SM_READAHEAD_DATA (message)) [0]) = c;
+ send_readahead (message);
+}
+
+static void
+send_readahead (msg_t * message)
+{
+ OS2_send_message (console_writer_qid, message);
+ OS2_wait_for_readahead_ack (console_writer_qid);
+}
+\f
+void
+OS2_initialize_console_channel (Tchannel channel)
+{
+ (CHANNEL_OPERATOR_CONTEXT (channel)) = console_context;
+ (CHANNEL_OPERATOR (channel)) = console_operator;
+}
+
+static void
+console_operator (Tchannel channel, chop_t operation,
+ choparg_t arg1, choparg_t arg2, choparg_t arg3)
+{
+ switch (operation)
+ {
+ case chop_read:
+ (* ((long *) arg3))
+ = (channel_thread_read (channel, ((char *) arg1), ((size_t) arg2)));
+ break;
+ case chop_write:
+ write_output (((const char *) arg1), ((size_t) arg2), output_cooked_p);
+ (* ((long *) arg3)) = ((size_t) arg2);
+ break;
+ case chop_close:
+ case chop_output_flush:
+ case chop_output_drain:
+ break;
+ case chop_input_flush:
+ flush_input ();
+ break;
+ case chop_input_buffered:
+ console_input_buffered (channel, ((int) arg1), ((int *) arg2));
+ break;
+ case chop_output_cooked:
+ console_output_cooked (channel, ((int) arg1), ((int *) arg2));
+ break;
+ default:
+ OS2_logic_error ("Unknown operation for console.");
+ break;
+ }
+}
+
+static void
+flush_input (void)
+{
+ grab_console_lock ();
+ while ((line_buffer -> next) != 0)
+ pop_line_buffer ();
+ LINE_BUFFER_SIZE = 0;
+ release_console_lock ();
+}
+
+static void
+console_input_buffered (Tchannel channel, int new, int * pold)
+{
+ if (new < 0)
+ (* pold) = input_buffered_p;
+ else
+ {
+ int old = input_buffered_p;
+ input_buffered_p = new;
+ if (old && (!new))
+ {
+ grab_console_lock ();
+ finish_line ();
+ }
+ }
+}
+
+static void
+console_output_cooked (Tchannel channel, int new, int * pold)
+{
+ if (new < 0)
+ (* pold) = output_cooked_p;
+ else
+ output_cooked_p = new;
+}
+\f
+static void
+write_char (char c, int cooked_p)
+{
+ write_output ((&c), 1, cooked_p);
+}
+
+static void
+write_output (const char * data, size_t size, int cooked_p)
+{
+ const char * scan = data;
+ const char * end = (scan + size);
+ char output_translation [256];
+ char * out = output_translation;
+ char * out_limit = (out + ((sizeof (output_translation)) - 4));
+ char c;
+ if (!cooked_p)
+ write_output_1 (scan, end);
+ else
+ while (1)
+ {
+ if ((scan == end) || (out >= out_limit))
+ {
+ write_output_1 (output_translation, out);
+ if (scan == end)
+ break;
+ out = output_translation;
+ }
+ c = (*scan++);
+ if (isprint (c))
+ (*out++) = c;
+ else if (c == LINEFEED)
+ {
+ (*out++) = '\r';
+ (*out++) = c;
+ }
+ else if (c < 0x20)
+ {
+ (*out++) = '^';
+ (*out++) = ('@' + c);
+ }
+ else
+ {
+ (*out++) = '\\';
+ (*out++) = ('0' + ((c >> 6) & 3));
+ (*out++) = ('0' + ((c >> 3) & 7));
+ (*out++) = ('0' + (c & 7));
+ }
+ }
+}
+
+static void
+write_output_1 (const char * scan, const char * end)
+{
+#ifdef USE_PMIO
+ put_raw ((end - scan), scan);
+#else /* not USE_PMIO */
+#if 1
+ STD_API_CALL (vio_wrt_tty, (((PCH) scan), (end - scan), 0));
+#else
+ while (1)
+ {
+ ULONG n;
+ APIRET rc = (dos_write (1, ((void *) scan), (end - scan), (& n)));
+ if (rc != NO_ERROR)
+ break;
+ scan += n;
+ if (scan == end)
+ break;
+ }
+#endif
+#endif /* not USE_PMIO */
+}
+
+static unsigned int
+char_output_length (char c)
+{
+ return ((isprint (c)) ? 1 : (c < 0x20) ? 2 : 4);
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2cthrd.c,v 1.1 1994/11/28 03:42:55 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+/* Scheme side of channel thread interface */
+
+#include "os2.h"
+\f
+void
+OS2_initialize_channel_thread_messages (void)
+{
+ SET_MSG_TYPE_LENGTH (mt_readahead, sm_readahead_t);
+ SET_MSG_TYPE_LENGTH (mt_readahead_ack, sm_readahead_ack_t);
+}
+
+channel_context_t *
+OS2_make_channel_context (void)
+{
+ channel_context_t * context = (OS_malloc (sizeof (channel_context_t)));
+ OS2_make_qid_pair ((& (CHANNEL_CONTEXT_READER_QID (context))),
+ (& (CHANNEL_CONTEXT_WRITER_QID (context))));
+ (CHANNEL_CONTEXT_READAHEAD (context)) = 0;
+ (CHANNEL_CONTEXT_READAHEAD_INDEX (context)) = 0;
+ (CHANNEL_CONTEXT_EOFP (context)) = 0;
+ return (context);
+}
+
+long
+channel_thread_read (Tchannel channel, char * buffer, size_t size)
+{
+ channel_context_t * context = (CHANNEL_OPERATOR_CONTEXT (channel));
+ qid_t qid = (CHANNEL_CONTEXT_READER_QID (context));
+ msg_t * message;
+ unsigned int index;
+ unsigned int navail;
+ if (CHANNEL_CONTEXT_EOFP (context))
+ return (0);
+ message = (CHANNEL_CONTEXT_READAHEAD (context));
+ index = (CHANNEL_CONTEXT_READAHEAD_INDEX (context));
+ if (message == 0)
+ {
+ if (CHANNEL_NONBLOCKING (channel))
+ {
+ message = (OS2_receive_message (qid, 0));
+ if (message == 0)
+ {
+ (CHANNEL_CONTEXT_READAHEAD (context)) = 0;
+ return (-1);
+ }
+ }
+ else
+ message = (OS2_receive_message (qid, 1));
+ /* Acknowledge the message so that the readahead thread will
+ know that it is safe to start reading some more. */
+ OS2_send_message (qid, (OS2_make_readahead_ack ()));
+ if (OS2_error_message_p (message))
+ OS2_handle_error_message (message);
+ if ((MSG_TYPE (message)) != mt_readahead)
+ OS2_logic_error ("Illegal message from channel thread.");
+ index = 0;
+ }
+ if ((SM_READAHEAD_SIZE (message)) == 0)
+ {
+ OS2_destroy_message (message);
+ (CHANNEL_CONTEXT_READAHEAD (context)) = 0;
+ (CHANNEL_CONTEXT_EOFP (context)) = 1;
+ return (0);
+ }
+ navail = ((SM_READAHEAD_SIZE (message)) - index);
+ if (navail <= size)
+ {
+ FASTCOPY ((SM_READAHEAD_DATA (message)), buffer, navail);
+ OS2_destroy_message (message);
+ (CHANNEL_CONTEXT_READAHEAD (context)) = 0;
+ return (navail);
+ }
+ else
+ {
+ FASTCOPY ((SM_READAHEAD_DATA (message)), buffer, size);
+ (CHANNEL_CONTEXT_READAHEAD (context)) = message;
+ (CHANNEL_CONTEXT_READAHEAD_INDEX (context)) = (index + size);
+ return (size);
+ }
+}
+
+void
+OS2_wait_for_readahead_ack (qid_t qid)
+{
+ /* Wait for an acknowledgement before starting another read.
+ This regulates the amount of data in the queue. */
+ msg_t * message = (OS2_receive_message (qid, 1));
+ if ((MSG_TYPE (message)) != mt_readahead_ack)
+ OS2_logic_error ("Expected readahead_ack message.");
+ OS2_destroy_message (message);
+}
+
+void
+channel_thread_close (Tchannel channel)
+{
+ channel_context_t * context = (CHANNEL_OPERATOR_CONTEXT (channel));
+ /* Closing handle should force input thread to kill itself. */
+ STD_API_CALL (dos_close, (CHANNEL_HANDLE (channel)));
+ if ((CHANNEL_CONTEXT_READAHEAD (context)) != 0)
+ OS2_destroy_message (CHANNEL_CONTEXT_READAHEAD (context));
+ OS2_close_qid (CHANNEL_CONTEXT_READER_QID (context));
+ OS_free (context);
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2cthrd.h,v 1.1 1994/11/28 03:42:55 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_OS2CTHRD_H
+#define SCM_OS2CTHRD_H
+\f
+#ifndef SM_READAHEAD_MAX
+#define SM_READAHEAD_MAX 4096
+#endif
+
+typedef struct
+{
+ qid_t reader_qid;
+ qid_t writer_qid;
+ msg_t * readahead;
+ unsigned int readahead_index;
+ char eofp;
+} channel_context_t;
+#define CHANNEL_CONTEXT_READER_QID(c) ((c) -> reader_qid)
+#define CHANNEL_CONTEXT_WRITER_QID(c) ((c) -> writer_qid)
+#define CHANNEL_CONTEXT_READAHEAD(c) ((c) -> readahead)
+#define CHANNEL_CONTEXT_READAHEAD_INDEX(c) ((c) -> readahead_index)
+#define CHANNEL_CONTEXT_EOFP(c) ((c) -> eofp)
+
+typedef struct
+{
+ DECLARE_MSG_HEADER_FIELDS;
+ ULONG size;
+ char data [SM_READAHEAD_MAX];
+} sm_readahead_t;
+#define SM_READAHEAD_SIZE(m) (((sm_readahead_t *) (m)) -> size)
+#define SM_READAHEAD_DATA(m) (((sm_readahead_t *) (m)) -> data)
+
+#define OS2_make_readahead() OS2_create_message (mt_readahead)
+#define OS2_make_readahead_ack() OS2_create_message (mt_readahead_ack)
+
+typedef msg_t sm_readahead_ack_t;
+
+extern channel_context_t * OS2_make_channel_context (void);
+extern long channel_thread_read (Tchannel, char *, size_t);
+extern void OS2_wait_for_readahead_ack (qid_t);
+extern void channel_thread_close (Tchannel);
+
+#endif /* SCM_OS2CTHRD_H */
--- /dev/null
+/* -*-C-*-
+
+$Id: os2ctty.c,v 1.1 1994/11/28 03:42:55 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+#include "osctty.h"
+#include "ossig.h"
+\f
+#define CONTROL_B_ENABLE (0x1)
+#define CONTROL_G_ENABLE (0x2)
+#define CONTROL_U_ENABLE (0x4)
+#define CONTROL_X_ENABLE (0x8)
+#define INTERACTIVE_INTERRUPT_ENABLE (0x10)
+#define TERMINATE_INTERRUPT_ENABLE (0x20)
+
+#define ALL_ENABLES \
+ (CONTROL_B_ENABLE | CONTROL_G_ENABLE | CONTROL_U_ENABLE \
+ | CONTROL_X_ENABLE | INTERACTIVE_INTERRUPT_ENABLE \
+ | TERMINATE_INTERRUPT_ENABLE)
+
+#define CONTROL_B '\002'
+#define CONTROL_G '\007'
+#define CONTROL_U '\025'
+#define CONTROL_X '\030'
+#define CONTROL_C '\003'
+
+#define KB_INT_CHARS_SIZE 5
+#define KB_INT_TABLE_SIZE 256
+
+static char keyboard_interrupt_characters [KB_INT_CHARS_SIZE];
+static enum interrupt_handler keyboard_interrupt_handlers [KB_INT_CHARS_SIZE];
+static enum interrupt_handler keyboard_interrupt_table [KB_INT_TABLE_SIZE];
+static enum interrupt_handler keyboard_break_interrupt;
+static Tinterrupt_enables keyboard_interrupt_enables;
+
+static void
+update_keyboard_interrupt_characters (void)
+{
+ unsigned int i;
+ for (i = 0; (i < KB_INT_TABLE_SIZE); i += 1)
+ (keyboard_interrupt_table[i]) = interrupt_handler_ignore;
+ for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
+ (keyboard_interrupt_table [keyboard_interrupt_characters [i]]) =
+ (keyboard_interrupt_handlers[i]);
+}
+
+void
+OS2_initialize_keyboard_interrupts (void)
+{
+ (keyboard_interrupt_characters[0]) = CONTROL_B;
+ (keyboard_interrupt_handlers[0]) = interrupt_handler_control_b;
+ (keyboard_interrupt_characters[1]) = CONTROL_G;
+ (keyboard_interrupt_handlers[1]) = interrupt_handler_control_g;
+ (keyboard_interrupt_characters[2]) = CONTROL_U;
+ (keyboard_interrupt_handlers[2]) = interrupt_handler_control_u;
+ (keyboard_interrupt_characters[3]) = CONTROL_X;
+ (keyboard_interrupt_handlers[3]) = interrupt_handler_control_x;
+ (keyboard_interrupt_characters[4]) = CONTROL_C;
+ (keyboard_interrupt_handlers[4]) = interrupt_handler_interactive;
+ keyboard_break_interrupt = interrupt_handler_terminate;
+ update_keyboard_interrupt_characters ();
+ keyboard_interrupt_enables = ALL_ENABLES;
+}
+\f
+void
+OS_ctty_get_interrupt_enables (Tinterrupt_enables * mask)
+{
+ (*mask) = keyboard_interrupt_enables;
+}
+
+void
+OS_ctty_set_interrupt_enables (Tinterrupt_enables * mask)
+{
+ keyboard_interrupt_enables = ((*mask) & ALL_ENABLES);
+}
+
+unsigned int
+OS_ctty_num_int_chars (void)
+{
+ return (KB_INT_CHARS_SIZE + 1);
+}
+
+cc_t
+OS_tty_map_interrupt_char (cc_t int_char)
+{
+ return (int_char);
+}
+
+cc_t *
+OS_ctty_get_int_chars (void)
+{
+ static cc_t characters [KB_INT_CHARS_SIZE + 1];
+ unsigned int i;
+ for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
+ (characters[i]) = (keyboard_interrupt_characters[i]);
+ (characters[i]) = '\0'; /* dummy for control-break */
+ return (characters);
+}
+
+void
+OS_ctty_set_int_chars (cc_t * characters)
+{
+ unsigned int i;
+ for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
+ (keyboard_interrupt_characters[i]) = (characters[i]);
+ update_keyboard_interrupt_characters ();
+}
+
+cc_t *
+OS_ctty_get_int_char_handlers (void)
+{
+ static cc_t handlers [KB_INT_CHARS_SIZE + 1];
+ unsigned int i;
+ for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
+ (handlers[i]) = ((cc_t) (keyboard_interrupt_handlers[i]));
+ (handlers[i]) = ((cc_t) keyboard_break_interrupt);
+ return (handlers);
+}
+
+void
+OS_ctty_set_int_char_handlers (cc_t * handlers)
+{
+ unsigned int i;
+ for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
+ (keyboard_interrupt_handlers[i]) =
+ ((enum interrupt_handler) (handlers[i]));
+ keyboard_break_interrupt = ((enum interrupt_handler) (handlers[i]));
+ update_keyboard_interrupt_characters ();
+}
+\f
+static char
+check_if_enabled (enum interrupt_handler handler)
+{
+ unsigned int bitmask;
+ char result;
+ switch (handler)
+ {
+ case interrupt_handler_control_b:
+ bitmask = CONTROL_B_ENABLE;
+ result = 'B';
+ break;
+ case interrupt_handler_control_g:
+ bitmask = CONTROL_G_ENABLE;
+ result = 'G';
+ break;
+ case interrupt_handler_control_u:
+ bitmask = CONTROL_U_ENABLE;
+ result = 'U';
+ break;
+ case interrupt_handler_control_x:
+ bitmask = CONTROL_X_ENABLE;
+ result = 'X';
+ break;
+ case interrupt_handler_interactive:
+ bitmask = INTERACTIVE_INTERRUPT_ENABLE;
+ result = '!';
+ break;
+ case interrupt_handler_terminate:
+ bitmask = TERMINATE_INTERRUPT_ENABLE;
+ result = '@';
+ break;
+ default:
+ bitmask = 0;
+ result = '\0';
+ break;
+ }
+ return (((keyboard_interrupt_enables & bitmask) == 0) ? '\0' : result);
+}
+
+char
+OS2_keyboard_interrupt_handler (char c)
+{
+ return (check_if_enabled (keyboard_interrupt_table[c]));
+}
+
+char
+OS2_keyboard_break_interrupt_handler (void)
+{
+ return (check_if_enabled (keyboard_break_interrupt));
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2ctty.h,v 1.1 1994/11/28 03:42:56 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_OS2CTTY_H
+#define SCM_OS2CTTY_H
+
+extern char OS2_keyboard_interrupt_handler (char);
+extern char OS2_keyboard_break_interrupt_handler (void);
+
+#endif /* SCM_OS2CTTY_H */
--- /dev/null
+/* -*-C-*-
+
+$Id: os2env.c,v 1.1 1994/11/28 03:42:56 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "scheme.h"
+#undef END_OF_CHAIN
+#include "os2.h"
+#include "osenv.h"
+#include <time.h>
+#include <sys\types.h>
+
+#ifdef __IBMC__
+
+#include <sys\timeb.h>
+
+#else /* not __IBMC__ */
+#ifdef __GCC2__
+
+#include <errno.h>
+#include <sys/times.h>
+
+#endif /* __GCC2__ */
+#endif /* not __IBMC__ */
+
+static void initialize_real_time_clock (void);
+static double get_real_time_clock (void);
+
+static void initialize_timer (void);
+static void timer_thread (void *);
+static void handle_timer_event (msg_t *);
+
+void
+OS2_initialize_environment (void)
+{
+ initialize_real_time_clock ();
+ initialize_timer ();
+}
+\f
+time_t
+OS_encoded_time (void)
+{
+ time_t t = (time (0));
+ if (t < 0)
+ OS2_error_system_call (errno, syscall_time);
+ return (t);
+}
+
+void
+OS_decode_time (time_t t, struct time_structure * buffer)
+{
+ struct tm * ts = (localtime (&t));
+ if (ts == 0)
+ OS2_error_system_call (errno, syscall_localtime);
+ (buffer -> year) = ((ts -> tm_year) + 1900);
+ (buffer -> month) = ((ts -> tm_mon) + 1);
+ (buffer -> day) = (ts -> tm_mday);
+ (buffer -> hour) = (ts -> tm_hour);
+ (buffer -> minute) = (ts -> tm_min);
+ (buffer -> second) = (ts -> tm_sec);
+ {
+ /* In localtime() encoding, 0 is Sunday; in ours, it's Monday. */
+ int wday = (ts -> tm_wday);
+ (buffer -> day_of_week) = ((wday == 0) ? 6 : (wday - 1));
+ }
+}
+
+time_t
+OS_encode_time (struct time_structure * buffer)
+{
+ struct tm ts;
+ (ts . tm_year) = ((buffer -> year) - 1900);
+ (ts . tm_mon) = ((buffer -> month) - 1);
+ (ts . tm_mday) = (buffer -> day);
+ (ts . tm_hour) = (buffer -> hour);
+ (ts . tm_min) = (buffer -> minute);
+ (ts . tm_sec) = (buffer -> second);
+ (ts . tm_isdst) = -1; /* Let mktime figure it out */
+ {
+ time_t t = (mktime (&ts));
+ if (t < 0)
+ OS2_error_system_call (errno, syscall_mktime);
+ return (t);
+ }
+}
+
+static double initial_rtc;
+
+static void
+initialize_real_time_clock (void)
+{
+ initial_rtc = (get_real_time_clock ());
+}
+
+double
+OS_real_time_clock (void)
+{
+ return ((get_real_time_clock ()) - initial_rtc);
+}
+
+static double
+get_real_time_clock (void)
+{
+#ifdef __IBMC__
+ struct timeb rtc;
+ _ftime (&rtc);
+ return ((((double) (rtc . time)) * 1000.0) + ((double) (rtc . millitm)));
+#else /* not __IBMC__ */
+#ifdef __GCC2__
+ struct tms rtc;
+ times (&rtc);
+ return (((double) (rtc . tms_utime)) * (1000.0 / ((double) CLK_TCK)));
+#endif /* __GCC2__ */
+#endif /* not __IBMC__ */
+}
+
+double
+OS_process_clock (void)
+{
+ /* This must not signal an error in normal use. */
+ return (OS_real_time_clock ());
+}
+\f
+static HEV timer_event;
+static int timer_handle_valid;
+static HTIMER timer_handle;
+static TID timer_tid;
+
+static void
+initialize_timer (void)
+{
+ timer_event = (OS2_create_event_semaphore ());
+ timer_handle_valid = 0;
+ timer_tid = (OS2_beginthread (timer_thread, 0, 0));
+}
+
+void
+OS2_kill_timer_thread (void)
+{
+ OS2_kill_thread (timer_tid);
+}
+
+static void
+timer_thread (void * arg)
+{
+ (void) OS2_thread_initialize (QID_NONE);
+ while (1)
+ {
+ ULONG count = (OS2_reset_event_semaphore (timer_event));
+ while (count > 0)
+ {
+ OS2_send_message (OS2_interrupt_qid,
+ (OS2_create_message (mt_timer_event)));
+ count -= 1;
+ }
+ (void) OS2_wait_event_semaphore (timer_event, 1);
+ }
+}
+
+void
+OS_real_timer_set (clock_t first, clock_t interval)
+{
+ /* **** No support for (first != interval), but runtime system never
+ does that anyway. */
+ OS_real_timer_clear ();
+ if (interval != 0)
+ {
+ STD_API_CALL (dos_start_timer, (interval,
+ ((HSEM) (&timer_event)),
+ (&timer_handle)));
+ timer_handle_valid = 1;
+ }
+ else if (first != 0)
+ {
+ STD_API_CALL (dos_async_timer, (first,
+ ((HSEM) (&timer_event)),
+ (&timer_handle)));
+ timer_handle_valid = 1;
+ }
+}
+
+void
+OS_real_timer_clear (void)
+{
+ if (timer_handle_valid)
+ {
+ STD_API_CALL (dos_stop_timer, (timer_handle));
+ timer_handle_valid = 0;
+ }
+ (void) OS2_reset_event_semaphore (timer_event);
+}
+\f
+void
+OS_process_timer_set (clock_t first, clock_t interval)
+{
+ OS2_error_unimplemented_primitive ();
+}
+
+void
+OS_process_timer_clear (void)
+{
+}
+
+void
+OS_profile_timer_set (clock_t first, clock_t interval)
+{
+ OS2_error_unimplemented_primitive ();
+}
+
+void
+OS_profile_timer_clear (void)
+{
+}
+\f
+static size_t current_dir_path_size = 0;
+static char * current_dir_path = 0;
+
+const char *
+OS_working_dir_pathname (void)
+{
+ ULONG drive_number;
+ {
+ ULONG drive_map;
+ STD_API_CALL (dos_query_current_disk, ((&drive_number), (&drive_map)));
+ }
+ if ((current_dir_path_size == 0) || (current_dir_path == 0))
+ {
+ current_dir_path_size = 1024;
+ current_dir_path = (OS_malloc (current_dir_path_size));
+ }
+ while (1)
+ {
+ ULONG size = (current_dir_path_size - 3);
+ {
+ APIRET rc =
+ (dos_query_current_dir
+ (drive_number, (current_dir_path + 3), (&size)));
+ if (rc == NO_ERROR)
+ break;
+ if (rc != ERROR_BUFFER_OVERFLOW)
+ OS2_error_system_call (rc, syscall_dos_query_current_dir);
+ }
+ do
+ current_dir_path_size *= 2;
+ while ((current_dir_path_size - 3) < size);
+ OS_free (current_dir_path);
+ current_dir_path = (OS_malloc (current_dir_path_size));
+ }
+ (current_dir_path[0]) = ('a' + drive_number - 1);
+ (current_dir_path[1]) = ':';
+ (current_dir_path[2]) = '\\';
+ return (current_dir_path);
+}
+
+void
+OS_set_working_dir_pathname (const char * name)
+{
+ extern char * OS2_remove_trailing_backslash (const char *);
+ unsigned int length;
+ name = (OS2_remove_trailing_backslash (name));
+ /* **** Documentation doesn't clarify whether DosSetCurrentDir will
+ handle the drive prefix correctly or not. */
+ length = (strlen (name));
+ if ((length >= 2) && ((name[1]) == ':'))
+ {
+ STD_API_CALL
+ (dos_set_default_disk,
+ ((name[0]) - ((islower (name[0])) ? 'a' : 'A') + 1));
+ name += 2;
+ }
+ STD_API_CALL (dos_set_current_dir, ((char *) name));
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2file.c,v 1.1 1994/11/28 03:42:57 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+#include "osfile.h"
+
+static ULONG set_file_pointer (Tchannel, ULONG, LONG);
+
+#define OS2_OPEN_MODE(m) \
+ ((((m) & CHANNEL_READ) == 0) \
+ ? (OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE) \
+ : (((m) & CHANNEL_WRITE) == 0) \
+ ? (OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE) \
+ : (OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYWRITE))
+\f
+static Tchannel
+open_file (const char * filename, ULONG attr, ULONG flags, unsigned int mode)
+{
+ HFILE handle;
+ ULONG action;
+ STD_API_CALL
+ (dos_open, (((char *) filename), (&handle), (&action), 0, attr, flags,
+ (OS2_OPEN_MODE (mode)), 0));
+ return (OS2_make_channel (handle, mode));
+}
+
+Tchannel
+OS_open_input_file (const char * filename)
+{
+ return
+ (open_file (filename,
+ FILE_NORMAL,
+ (OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW),
+ CHANNEL_READ));
+}
+
+Tchannel
+OS_open_output_file (const char * filename)
+{
+ return
+ (open_file (filename,
+ FILE_NORMAL,
+ (OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW),
+ CHANNEL_WRITE));
+}
+
+Tchannel
+OS_open_io_file (const char * filename)
+{
+ return
+ (open_file (filename,
+ FILE_NORMAL,
+ (OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW),
+ (CHANNEL_READ | CHANNEL_WRITE)));
+}
+
+Tchannel
+OS_open_append_file (const char * filename)
+{
+ Tchannel channel =
+ (open_file (filename,
+ FILE_NORMAL,
+ (OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW),
+ CHANNEL_WRITE));
+ transaction_begin ();
+ OS_channel_close_on_abort (channel);
+ (void) set_file_pointer (channel, FILE_END, 0);
+ transaction_commit ();
+ return (channel);
+}
+\f
+static Tchannel
+open_file_noerror (const char * filename, ULONG attr, ULONG flags,
+ unsigned int mode)
+{
+ HFILE handle;
+ ULONG action;
+ if ((dos_open (((char *) filename), (&handle), (&action), 0, attr, flags,
+ (OS2_OPEN_MODE (mode)), 0))
+ != NO_ERROR)
+ return (NO_CHANNEL);
+ {
+ Tchannel channel = (OS2_make_channel (handle, mode));
+ if ((CHANNEL_TYPE (channel)) == channel_type_file)
+ return (channel);
+ OS_channel_close_noerror (channel);
+ return (NO_CHANNEL);
+ }
+}
+
+Tchannel
+OS_open_load_file (const char * filename)
+{
+ return
+ (open_file_noerror
+ (filename,
+ FILE_NORMAL,
+ (OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW),
+ CHANNEL_READ));
+}
+
+Tchannel
+OS_open_dump_file (const char * filename)
+{
+ return
+ (open_file_noerror
+ (filename,
+ FILE_NORMAL,
+ (OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW),
+ CHANNEL_WRITE));
+}
+
+off_t
+OS_file_length (Tchannel channel)
+{
+ FILESTATUS3 buffer;
+ if ((CHANNEL_TYPE (channel)) != channel_type_file)
+ OS2_error_system_call (ERROR_INVALID_HANDLE, syscall_dos_query_file_info);
+ STD_API_CALL
+ (dos_query_file_info,
+ ((CHANNEL_HANDLE (channel)), FIL_STANDARD,
+ (&buffer), (sizeof (buffer))));
+ return (buffer.cbFile);
+}
+
+off_t
+OS_file_position (Tchannel channel)
+{
+ return (set_file_pointer (channel, FILE_CURRENT, 0));
+}
+
+void
+OS_file_set_position (Tchannel channel, off_t position)
+{
+ if ((set_file_pointer (channel, FILE_BEGIN, position)) != position)
+ OS2_error_anonymous ();
+}
+
+static ULONG
+set_file_pointer (Tchannel channel, ULONG type, LONG distance)
+{
+ ULONG fp;
+ if ((CHANNEL_TYPE (channel)) != channel_type_file)
+ OS2_error_system_call (ERROR_INVALID_HANDLE, syscall_dos_set_file_ptr);
+ STD_API_CALL
+ (dos_set_file_ptr, ((CHANNEL_HANDLE (channel)), distance, type, (&fp)));
+ return (fp);
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2fs.c,v 1.1 1994/11/28 03:42:57 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+#include "osfs.h"
+
+#ifdef __GCC2__
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#endif
+
+static const char * make_pathname (const char *, const char *);
+static const char * filename_extension (const char *);
+extern char * OS2_remove_trailing_backslash (const char *);
+\f
+FILESTATUS3 *
+OS2_read_file_status (const char * filename)
+{
+ static FILESTATUS3 info;
+ XTD_API_CALL
+ (dos_query_path_info,
+ ((OS2_remove_trailing_backslash (filename)),
+ FIL_STANDARD, (&info), (sizeof (info))),
+ {
+ if ((rc == ERROR_FILE_NOT_FOUND)
+ || (rc == ERROR_PATH_NOT_FOUND)
+ /* ERROR_ACCESS_DENIED can occur if the file is a symbolic
+ link on a unix system mounted via NFS, and if the
+ symbolic link points to a nonexistent file. */
+ || (rc == ERROR_ACCESS_DENIED))
+ return (0);
+ });
+ return (&info);
+}
+
+void
+OS2_write_file_status (const char * filename, FILESTATUS3 * info)
+{
+ STD_API_CALL
+ (dos_set_path_info,
+ ((OS2_remove_trailing_backslash (filename)),
+ FIL_STANDARD, info, (sizeof (FILESTATUS3)), 0));
+}
+
+enum file_existence
+OS_file_existence_test (const char * filename)
+{
+ return ((OS2_read_file_status (filename))
+ ? file_does_exist
+ : file_doesnt_exist);
+}
+
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+
+int
+OS_file_access (const char * filename, unsigned int mode)
+{
+ FILESTATUS3 * info = (OS2_read_file_status (filename));
+ if (!info)
+ return (0);
+ if (((mode & W_OK) != 0) && (((info -> attrFile) & FILE_READONLY) != 0))
+ return (0);
+ if ((mode & X_OK) != 0)
+ {
+ if (((info -> attrFile) & FILE_DIRECTORY) != 0)
+ return (0);
+ {
+ const char * extension = (filename_extension (filename));
+ if (! (((stricmp (extension, ".exe")) == 0)
+ || ((stricmp (extension, ".com")) == 0)
+ || ((stricmp (extension, ".cmd")) == 0)
+ || ((stricmp (extension, ".bat")) == 0)))
+ return (0);
+ }
+ }
+ return (1);
+}
+
+int
+OS_file_directory_p (const char * filename)
+{
+ FILESTATUS3 * info = (OS2_read_file_status (filename));
+ return ((info == 0) ? 0 : (((info -> attrFile) & FILE_DIRECTORY) != 0));
+}
+
+const char *
+OS_file_soft_link_p (const char * filename)
+{
+ return (0);
+}
+\f
+void
+OS_file_remove (const char * filename)
+{
+ {
+ FILESTATUS3 * info = (OS2_read_file_status (filename));
+ if (info == 0)
+ return;
+ if (((info -> attrFile) & FILE_READONLY) != 0)
+ {
+ (info -> attrFile) &=~ FILE_READONLY;
+ STD_API_CALL
+ (dos_set_path_info,
+ (((char *) filename), FIL_STANDARD, info, (sizeof (*info)), 0));
+ }
+ }
+ STD_API_CALL (dos_delete, ((char *) filename));
+}
+
+void
+OS_file_remove_link (const char * filename)
+{
+ OS_file_remove (filename);
+}
+
+void
+OS_file_rename (const char * from_name, const char * to_name)
+{
+ STD_API_CALL (dos_move, (((char *) from_name), ((char *) to_name)));
+}
+
+void
+OS_file_link_hard (const char * from_name, const char * to_name)
+{
+ OS2_error_unimplemented_primitive ();
+}
+
+void
+OS_file_link_soft (const char * from_name, const char * to_name)
+{
+ OS2_error_unimplemented_primitive ();
+}
+
+void
+OS_directory_make (const char * directory_name)
+{
+ STD_API_CALL
+ (dos_create_dir, ((OS2_remove_trailing_backslash (directory_name)), 0));
+}
+
+void
+OS_directory_delete (const char * directory_name)
+{
+ STD_API_CALL
+ (dos_delete_dir, (OS2_remove_trailing_backslash (directory_name)));
+}
+\f
+typedef struct
+{
+ const char * search_pattern;
+ HDIR handle;
+ FILEFINDBUF3 info;
+ ULONG count;
+} dir_search_state;
+
+static dir_search_state * dir_search_states;
+static unsigned int n_dir_search_states;
+
+void
+OS2_initialize_directory_reader (void)
+{
+ dir_search_states = 0;
+ n_dir_search_states = 0;
+}
+
+static unsigned int
+allocate_dir_search_state (const char * search_pattern)
+{
+ if (n_dir_search_states == 0)
+ {
+ dir_search_state * states =
+ ((dir_search_state *) (OS_malloc ((sizeof (dir_search_state)) * 4)));
+ dir_search_states = states;
+ n_dir_search_states = 4;
+ {
+ dir_search_state * scan = dir_search_states;
+ dir_search_state * end = (scan + n_dir_search_states);
+ ((scan++) -> search_pattern) = search_pattern;
+ while (scan < end)
+ ((scan++) -> search_pattern) = 0;
+ }
+ return (0);
+ }
+ {
+ dir_search_state * scan = dir_search_states;
+ dir_search_state * end = (scan + n_dir_search_states);
+ while (scan < end)
+ if (((scan++) -> search_pattern) == 0)
+ {
+ ((--scan) -> search_pattern) = search_pattern;
+ return (scan - dir_search_states);
+ }
+ }
+ {
+ unsigned int result = n_dir_search_states;
+ unsigned int n_states = (2 * n_dir_search_states);
+ dir_search_state * states =
+ ((dir_search_state *)
+ (OS_realloc (((void *) dir_search_states),
+ ((sizeof (dir_search_state)) * n_states))));
+ {
+ dir_search_state * scan = (states + result);
+ dir_search_state * end = (states + n_states);
+ ((scan++) -> search_pattern) = search_pattern;
+ while (scan < end)
+ ((scan++) -> search_pattern) = 0;
+ }
+ dir_search_states = states;
+ n_dir_search_states = n_states;
+ return (result);
+ }
+}
+
+#define REFERENCE_DIR_SEARCH_STATE(index) (& (dir_search_states[(index)]))
+#define DEALLOCATE_DIR_SEARCH_STATE(state) \
+{ \
+ if ((state -> search_pattern) != 0) \
+ { \
+ OS_free ((void *) (state -> search_pattern)); \
+ (state -> search_pattern) = 0; \
+ } \
+}
+\f
+int
+OS_directory_valid_p (long index)
+{
+ return
+ ((0 <= index)
+ && (index < n_dir_search_states)
+ && (((REFERENCE_DIR_SEARCH_STATE (index)) -> search_pattern) != 0));
+}
+
+unsigned int
+OS_directory_open (const char * search_pattern)
+{
+ unsigned int index = (allocate_dir_search_state (search_pattern));
+ dir_search_state * s = (REFERENCE_DIR_SEARCH_STATE (index));
+ (s -> handle) = HDIR_CREATE;
+ (s -> count) = 1;
+ XTD_API_CALL
+ (dos_find_first,
+ (((char *) (s -> search_pattern)), (& (s -> handle)), FILE_ANY,
+ (& (s -> info)), (sizeof (s -> info)), (& (s -> count)), FIL_STANDARD),
+ {
+ if (rc == ERROR_NO_MORE_FILES)
+ {
+ (s -> count) = 0;
+ goto done;
+ }
+ });
+ done:
+ return (index);
+}
+
+static void
+dir_find_next (dir_search_state * s)
+{
+ (s -> count) = 1;
+ XTD_API_CALL
+ (dos_find_next,
+ ((s -> handle), (& (s -> info)), (sizeof (s -> info)), (& (s -> count))),
+ {
+ if (rc == ERROR_NO_MORE_FILES)
+ {
+ (s -> count) = 0;
+ return;
+ }
+ });
+}
+
+static const char *
+dir_current_name (dir_search_state * s)
+{
+ static char result [CCHMAXPATH];
+ strcpy (result, ((s -> info) . achName));
+ dir_find_next (s);
+ return (result);
+}
+
+const char *
+OS_directory_read (unsigned int index)
+{
+ dir_search_state * s = (REFERENCE_DIR_SEARCH_STATE (index));
+ return (((s -> count) == 0) ? 0 : (dir_current_name (s)));
+}
+
+const char *
+OS_directory_read_matching (unsigned int index, const char * prefix)
+{
+ dir_search_state * s = (REFERENCE_DIR_SEARCH_STATE (index));
+ unsigned int n = (strlen (prefix));
+ while (1)
+ {
+ if ((s -> count) == 0)
+ return (0);
+ if ((strnicmp (((s -> info) . achName), prefix, n)) == 0)
+ return (dir_current_name (s));
+ dir_find_next (s);
+ }
+}
+
+void
+OS_directory_close (unsigned int index)
+{
+ dir_search_state * s = (REFERENCE_DIR_SEARCH_STATE (index));
+ STD_API_CALL (dos_find_close, (s -> handle));
+ DEALLOCATE_DIR_SEARCH_STATE (s);
+}
+\f
+static const char *
+filename_extension (const char * filename)
+{
+ const char * start;
+ const char * period;
+ start = (strrchr (filename, '\\'));
+ start = ((start == 0) ? filename : (start + 1));
+ period = (strrchr (start, '.'));
+ return ((period == 0) ? (filename + (strlen (filename))) : period);
+}
+
+static const char *
+make_pathname (const char * directory, const char * name)
+{
+ unsigned int dirlen = (strlen (directory));
+ unsigned int namlen = (strlen (name));
+ char * result = (OS_malloc (dirlen + namlen + 2));
+ strcpy (result, directory);
+ if ((dirlen > 0) && ((result [dirlen - 1]) != '\\'))
+ strcat (result, "\\");
+ strcat (result, name);
+ return (result);
+}
+
+char *
+OS2_remove_trailing_backslash (const char * filename)
+{
+ static char result [CCHMAXPATH];
+ unsigned int len = (strlen (filename));
+ if ((len == 0) || ((filename [len - 1]) != '\\'))
+ return ((char *) filename);
+ FASTCOPY (filename, result, (len - 1));
+ (result [len - 1]) = '\0';
+ return (result);
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2io.c,v 1.1 1994/11/28 03:42:57 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+
+extern void add_reload_cleanup (void (*) (void));
+extern void OS2_initialize_console_channel (Tchannel);
+extern void OS2_initialize_pipe_channel (Tchannel);
+\f
+static enum channel_type handle_channel_type (LHANDLE);
+
+size_t OS_channel_table_size;
+struct channel * OS2_channel_table;
+Tchannel * OS2_channel_pointer_table;
+const int OS_have_select_p = 0;
+
+void
+OS2_initialize_channels (void)
+{
+ OS_channel_table_size = (OS2_MAX_FILE_HANDLES ());
+ OS2_channel_table =
+ (OS_malloc (OS_channel_table_size * (sizeof (struct channel))));
+ OS2_channel_pointer_table =
+ (OS_malloc (OS_channel_table_size * (sizeof (Tchannel))));
+ {
+ Tchannel channel;
+ for (channel = 0; (channel < OS_channel_table_size); channel += 1)
+ {
+ (CHANNEL_OPEN (channel)) = 0;
+ (OS2_channel_pointer_table [channel]) = channel;
+ }
+ }
+ add_reload_cleanup (OS2_channel_close_all_noerror);
+ SET_MSG_TYPE_LENGTH (mt_readahead, sm_readahead_t);
+ SET_MSG_TYPE_LENGTH (mt_readahead_ack, sm_readahead_ack_t);
+}
+
+void
+OS2_reset_channels (void)
+{
+ OS_free (OS2_channel_table);
+ OS2_channel_table = 0;
+ OS_channel_table_size = 0;
+}
+
+void
+OS2_channel_operation (Tchannel channel, chop_t operation,
+ choparg_t arg1, choparg_t arg2, choparg_t arg3)
+{
+ ((* (CHANNEL_OPERATOR (channel))) (channel, operation, arg1, arg2, arg3));
+}
+\f
+Tchannel
+OS2_make_channel (LHANDLE handle, unsigned int mode)
+{
+ Tchannel channel = 0;
+ enum channel_type type;
+ transaction_begin ();
+ OS2_handle_close_on_abort (handle);
+ while (1)
+ {
+ if (channel == OS_channel_table_size)
+ OS2_error_out_of_channels ();
+ if (! (CHANNEL_OPEN (channel)))
+ break;
+ channel += 1;
+ }
+ type = (handle_channel_type (handle));
+ (CHANNEL_HANDLE (channel)) = handle;
+ (CHANNEL_TYPE (channel)) = type;
+ (CHANNEL_OPEN (channel)) = 1;
+ (CHANNEL_INTERNAL (channel)) = 0;
+ (CHANNEL_NONBLOCKING (channel)) = 0;
+ (CHANNEL_INPUTP (channel)) = ((mode & CHANNEL_READ) != 0);
+ (CHANNEL_OUTPUTP (channel)) = ((mode & CHANNEL_WRITE) != 0);
+ (CHANNEL_OPERATOR (channel)) = 0;
+ switch (type)
+ {
+ case channel_type_console:
+ OS2_initialize_console_channel (channel);
+ break;
+ case channel_type_unnamed_pipe:
+ OS2_initialize_pipe_channel (channel);
+ break;
+ }
+ transaction_commit ();
+ return (channel);
+}
+
+static enum channel_type
+handle_channel_type (LHANDLE handle)
+{
+ /* **** For now, limit channel types to those that we know how to
+ handle in a reasonable way. Later we can add other types if
+ needed. However, we probably won't need other types since pipes
+ and files are sufficient to do nearly anything, and the console
+ will be flushed when the PM support is installed. */
+ ULONG type;
+ ULONG flags;
+ if ((dos_query_h_type (handle, (&type), (&flags))) == NO_ERROR)
+ switch (type & 0xff)
+ {
+ case FHT_DISKFILE:
+ return (channel_type_file);
+ case FHT_CHRDEV:
+ if ((flags & 0x3) != 0)
+ return (channel_type_console);
+ else if ((flags & 0x4) != 0)
+ /* return (channel_type_null); */
+ break;
+ else if ((flags & 0x8) != 0)
+ /* return (channel_type_clock); */
+ break;
+ else
+ /* return (channel_type_character_device); */
+ break;
+ case FHT_PIPE:
+ {
+ APIRET rc = (dos_query_n_p_h_state (handle, (&flags)));
+ if ((rc == NO_ERROR) || (rc == ERROR_PIPE_NOT_CONNECTED))
+ /* return (channel_type_named_pipe); */
+ break;
+ else
+ return (channel_type_unnamed_pipe);
+ }
+ }
+ OS2_error_anonymous ();
+ return (channel_type_unknown);
+}
+\f
+void
+OS_channel_close (Tchannel channel)
+{
+ if (! (CHANNEL_INTERNAL (channel)))
+ {
+ if (CHANNEL_ABSTRACT_P (channel))
+ OS2_channel_operation (channel, chop_close, 0, 0, 0);
+ else
+ STD_API_CALL (dos_close, (CHANNEL_HANDLE (channel)));
+ (CHANNEL_OPEN (channel)) = 0;
+ }
+}
+
+void
+OS2_channel_close_all_noerror (void)
+{
+ Tchannel channel;
+ for (channel = 0; (channel < OS_channel_table_size); channel += 1)
+ if (CHANNEL_OPEN (channel))
+ OS_channel_close_noerror (channel);
+}
+
+void
+OS_channel_close_noerror (Tchannel channel)
+{
+ transaction_begin ();
+ OS2_ignore_errors ();
+ OS_channel_close (channel);
+ transaction_commit ();
+}
+
+static void
+OS_channel_close_on_abort_1 (void * cp)
+{
+ OS_channel_close_noerror (* ((Tchannel *) cp));
+}
+
+void
+OS_channel_close_on_abort (Tchannel channel)
+{
+ Tchannel * cp = (dstack_alloc (sizeof (Tchannel)));
+ (*cp) = (channel);
+ transaction_record_action (tat_abort, OS_channel_close_on_abort_1, cp);
+}
+
+static void
+OS2_handle_close_on_abort_1 (void * hp)
+{
+ (void) dos_close (* ((LHANDLE *) hp));
+}
+
+void
+OS2_handle_close_on_abort (LHANDLE h)
+{
+ LHANDLE * hp = (dstack_alloc (sizeof (LHANDLE)));
+ (*hp) = h;
+ transaction_record_action (tat_abort, OS2_handle_close_on_abort_1, hp);
+}
+
+int
+OS_channel_open_p (Tchannel channel)
+{
+ return (CHANNEL_OPEN (channel));
+}
+
+enum channel_type
+OS_channel_type (Tchannel channel)
+{
+ return (CHANNEL_TYPE (channel));
+}
+\f
+long
+OS_channel_read (Tchannel channel, void * buffer, size_t nbytes)
+{
+ long n;
+ if (nbytes == 0)
+ return (0);
+ if (CHANNEL_ABSTRACT_P (channel))
+ OS2_channel_operation (channel, chop_read,
+ ((choparg_t) buffer),
+ ((choparg_t) nbytes),
+ ((choparg_t) (& n)));
+ else
+ STD_API_CALL
+ (dos_read, ((CHANNEL_HANDLE (channel)), buffer, nbytes,
+ ((ULONG *) (& n))));
+ return (n);
+}
+
+long
+OS_channel_write (Tchannel channel, const void * buffer, size_t nbytes)
+{
+ long n;
+ if (nbytes == 0)
+ return (0);
+ if (CHANNEL_ABSTRACT_P (channel))
+ OS2_channel_operation (channel,
+ chop_write,
+ ((choparg_t) buffer),
+ ((choparg_t) nbytes),
+ ((choparg_t) (& n)));
+ else
+ STD_API_CALL
+ (dos_write, ((CHANNEL_HANDLE (channel)), ((void *) buffer), nbytes,
+ ((ULONG *) (& n))));
+ return (n);
+}
+
+int
+OS_channel_nonblocking_p (Tchannel channel)
+{
+ return (CHANNEL_NONBLOCKING (channel));
+}
+
+void
+OS_channel_nonblocking (Tchannel channel)
+{
+ (CHANNEL_NONBLOCKING (channel)) = 1;
+}
+
+void
+OS_channel_blocking (Tchannel channel)
+{
+ (CHANNEL_NONBLOCKING (channel)) = 0;
+}
+\f
+size_t
+OS_channel_read_load_file (Tchannel channel, void * buffer, size_t nbytes)
+{
+ ULONG nread;
+ if ((dos_read ((CHANNEL_HANDLE (channel)), buffer, nbytes, (&nread))) != 0)
+ return (0);
+ return (nread);
+}
+
+size_t
+OS_channel_write_dump_file (Tchannel channel,
+ const void * buffer,
+ size_t nbytes)
+{
+ ULONG nwrite;
+ if ((dos_write
+ ((CHANNEL_HANDLE (channel)), ((void *) buffer), nbytes, (&nwrite)))
+ != 0)
+ return (0);
+ return (nwrite);
+}
+
+void
+OS_channel_write_string (Tchannel channel, const char * string)
+{
+ unsigned long length = (strlen (string));
+ if ((OS_channel_write (channel, string, length)) != length)
+ OS2_error_anonymous ();
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2io.h,v 1.1 1994/11/28 03:42:58 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_OS2IO_H
+#define SCM_OS2IO_H
+
+#include "osio.h"
+\f
+typedef enum
+{
+ chop_close,
+ chop_read,
+ chop_write,
+ chop_input_buffered,
+ chop_input_flush,
+ chop_output_cooked,
+ chop_output_flush,
+ chop_output_drain
+} chop_t;
+
+typedef void * choparg_t;
+typedef void (* channel_op_t)
+ (Tchannel, chop_t, choparg_t, choparg_t, choparg_t);
+
+struct channel
+{
+ LHANDLE handle;
+ channel_op_t operator;
+ void * operator_context;
+ enum channel_type type;
+ unsigned int open : 1;
+ unsigned int internal : 1;
+ unsigned int nonblocking : 1;
+ unsigned int inputp : 1;
+ unsigned int outputp : 1;
+};
+
+#define _CHANNEL(c) (OS2_channel_table [(c)])
+#define CHANNEL_POINTER(c) (& (OS2_channel_pointer_table [(c)]))
+#define CHANNEL_HANDLE(c) ((_CHANNEL (c)) . handle)
+#define CHANNEL_OPERATOR(c) ((_CHANNEL (c)) . operator)
+#define CHANNEL_OPERATOR_CONTEXT(c) ((_CHANNEL (c)) . operator_context)
+#define CHANNEL_TYPE(c) ((_CHANNEL (c)) . type)
+#define CHANNEL_OPEN(c) ((_CHANNEL (c)) . open)
+#define CHANNEL_INTERNAL(c) ((_CHANNEL (c)) . internal)
+#define CHANNEL_NONBLOCKING(c) ((_CHANNEL (c)) . nonblocking)
+#define CHANNEL_INPUTP(c) ((_CHANNEL (c)) . inputp)
+#define CHANNEL_OUTPUTP(c) ((_CHANNEL (c)) . outputp)
+
+#define CHANNEL_ABSTRACT_P(c) ((CHANNEL_OPERATOR (c)) != 0)
+
+#define channel_type_console channel_type_os2_console
+#define channel_type_unnamed_pipe channel_type_os2_unnamed_pipe
+#define channel_type_named_pipe channel_type_os2_named_pipe
+
+/* Channel modes: */
+#define CHANNEL_READ 1
+#define CHANNEL_WRITE 2
+
+extern struct channel * OS2_channel_table;
+extern Tchannel * OS2_channel_pointer_table;
+extern Tchannel OS2_make_channel (LHANDLE, unsigned int);
+extern void OS2_channel_close_all_noerror (void);
+extern void OS_channel_close_on_abort (Tchannel);
+extern void OS2_handle_close_on_abort (LHANDLE);
+extern void OS2_channel_operation
+ (Tchannel, chop_t, choparg_t, choparg_t, choparg_t);
+
+#endif /* SCM_OS2IO_H */
--- /dev/null
+/* -*-C-*-
+
+$Id: os2msg.c,v 1.1 1994/11/28 03:42:58 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+/* Master Message Queue */
+
+#include "os2.h"
+
+static qid_t allocate_qid (void);
+static void OS2_initialize_message_lengths (void);
+static void read_and_dispatch_nonblocking (tqueue_t *);
+static void read_and_dispatch_one_blocking (tqueue_t *);
+static void write_subqueue (msg_t *);
+static msg_t * read_subqueue (qid_t);
+static int subqueue_emptyp (qid_t);
+static int read_tqueue (tqueue_t *, int);
+static void write_tqueue (tqueue_t *, msg_t *);
+static int read_std_tqueue (tqueue_t *, int);
+static void write_std_tqueue (tqueue_t *, msg_t *);
+static tqueue_t * make_scm_tqueue (void);
+static int read_scm_tqueue (tqueue_t *, int);
+static void write_scm_tqueue (tqueue_t *, msg_t *);
+static void process_interrupt_messages (void);
+static int read_pm_tqueue (tqueue_t *, int);
+static void write_pm_tqueue (tqueue_t *, msg_t *);
+\f
+typedef struct msg_list_s
+{
+ msg_t * message;
+ struct msg_list_s * next;
+} msg_list_t;
+
+typedef struct
+{
+ unsigned int allocatedp : 1; /* queue allocated? */
+ unsigned int openp : 1; /* queue open? */
+ qid_t twin; /* other end of connection */
+ tqueue_t * tqueue; /* thread queue for reception */
+ msg_list_t * subqueue_head; /* head of receiving subqueue */
+ msg_list_t * subqueue_tail; /* tail of receiving subqueue */
+} iqid_t;
+
+static iqid_t queue_array [QID_MAX + 1];
+static HMTX qid_lock;
+
+tqueue_t * OS2_scheme_tqueue;
+static qid_t OS2_interrupt_qid_local;
+qid_t OS2_interrupt_qid;
+
+#define _QID(q) (queue_array [(q)])
+#define QID_ALLOCATEDP(q) ((_QID (q)) . allocatedp)
+#define QID_TWIN(q) ((_QID (q)) . twin)
+#define QID_TQUEUE(q) ((_QID (q)) . tqueue)
+#define QID_SUBQUEUE_HEAD(q) ((_QID (q)) . subqueue_head)
+#define QID_SUBQUEUE_TAIL(q) ((_QID (q)) . subqueue_tail)
+
+#define MSG_QUEUE_TYPE(m) 0
+#define MSG_QUEUE_PRIORITY(m) 0
+
+void
+OS2_initialize_message_queues (void)
+{
+ {
+ qid_t qid = 0;
+ while (1)
+ {
+ (QID_ALLOCATEDP (qid)) = 0;
+ (QID_TQUEUE (qid)) = 0;
+ (QID_TWIN (qid)) = QID_NONE;
+ (QID_SUBQUEUE_HEAD (qid)) = 0;
+ (QID_SUBQUEUE_TAIL (qid)) = 0;
+ if (qid == QID_MAX)
+ break;
+ qid += 1;
+ }
+ }
+ OS2_initialize_message_lengths ();
+ SET_MSG_TYPE_LENGTH (mt_console_interrupt, sm_console_interrupt_t);
+ SET_MSG_TYPE_LENGTH (mt_timer_event, sm_timer_event_t);
+ qid_lock = (OS2_create_mutex_semaphore ());
+ OS2_scheme_tqueue = (make_scm_tqueue ());
+ OS2_make_qid_pair ((&OS2_interrupt_qid_local), (&OS2_interrupt_qid));
+ OS2_open_qid (OS2_interrupt_qid_local, OS2_scheme_tqueue);
+}
+\f
+void
+OS2_make_qid_pair (qid_t * pq1, qid_t * pq2)
+{
+ qid_t q1 = (allocate_qid ());
+ qid_t q2 = (allocate_qid ());
+ (QID_TWIN (q1)) = q2;
+ (QID_TWIN (q2)) = q1;
+ (*pq1) = q1;
+ (*pq2) = q2;
+}
+
+static qid_t
+allocate_qid (void)
+{
+ unsigned int qid = 0;
+ OS2_request_mutex_semaphore (qid_lock);
+ while (1)
+ {
+ if ((QID_ALLOCATEDP (qid)) == 0)
+ break;
+ if (qid == QID_MAX)
+ OS2_logic_error ("No more QIDs available.");
+ qid += 1;
+ }
+ (QID_ALLOCATEDP (qid)) = 1;
+ (QID_TQUEUE (qid)) = 0;
+ (QID_TWIN (qid)) = QID_NONE;
+ (QID_SUBQUEUE_HEAD (qid)) = 0;
+ (QID_SUBQUEUE_TAIL (qid)) = 0;
+ OS2_release_mutex_semaphore (qid_lock);
+ return (qid);
+}
+
+void
+OS2_open_qid (qid_t qid, tqueue_t * tqueue)
+{
+ if ((QID_TQUEUE (qid)) != 0)
+ OS2_logic_error ("Reopening already open QID.");
+ if (tqueue == 0)
+ OS2_logic_error ("Null tqueue passed to OS2_open_qid.");
+ (QID_TQUEUE (qid)) = tqueue;
+}
+
+int
+OS2_qid_openp (qid_t qid)
+{
+ return ((QID_TQUEUE (qid)) != 0);
+}
+
+void
+OS2_close_qid (qid_t qid)
+{
+ {
+ msg_list_t * elt = (QID_SUBQUEUE_HEAD (qid));
+ while (elt != 0)
+ {
+ msg_list_t * next = (elt -> next);
+ OS_free (elt);
+ elt = next;
+ }
+ }
+ (QID_SUBQUEUE_HEAD (qid)) = 0;
+ (QID_SUBQUEUE_TAIL (qid)) = 0;
+ (QID_TQUEUE (qid)) = 0;
+ OS2_request_mutex_semaphore (qid_lock);
+ {
+ qid_t twin = (QID_TWIN (qid));
+ if (twin != QID_NONE)
+ {
+ (QID_TWIN (twin)) = QID_NONE;
+ (QID_TWIN (qid)) = QID_NONE;
+ }
+ }
+ (QID_ALLOCATEDP (qid)) = 0;
+ OS2_release_mutex_semaphore (qid_lock);
+}
+\f
+/* Message Lengths */
+
+#define MESSAGE_LENGTH(t) (message_lengths [(unsigned int) (t)])
+static msg_length_t message_lengths [MSG_TYPE_SUP];
+
+static void
+OS2_initialize_message_lengths (void)
+{
+ unsigned int type = 0;
+ while (1)
+ {
+ (MESSAGE_LENGTH (type)) = 0;
+ if (type == MSG_TYPE_MAX)
+ break;
+ type += 1;
+ }
+}
+
+msg_length_t
+OS2_message_type_length (msg_type_t type)
+{
+ msg_length_t length = (MESSAGE_LENGTH (type));
+ if (length == 0)
+ OS2_logic_error ("Message type has unknown length.");
+ return (length);
+}
+
+void
+OS2_set_message_type_length (msg_type_t type, msg_length_t length)
+{
+ (MESSAGE_LENGTH (type)) = length;
+}
+\f
+/* Message Transmission and Reception */
+
+msg_t *
+OS2_create_message (msg_type_t type)
+{
+ /* Do allocation carefully to prevent infinite loop when signalling
+ "out of memory" condition. */
+ msg_t * message =
+ (malloc ((unsigned long) (OS2_message_type_length (type))));
+ if (message == 0)
+ if ((type == mt_syscall_error)
+ && ((SM_SYSCALL_ERROR_CODE (message)) == ERROR_NOT_ENOUGH_MEMORY)
+ && ((SM_SYSCALL_ERROR_NAME (message)) == syscall_malloc))
+ OS2_logic_error ("Unable to allocate memory for error message.");
+ else
+ OS2_error_system_call (ERROR_NOT_ENOUGH_MEMORY, syscall_malloc);
+ (_MSG_TYPE (message)) = ((unsigned char) type);
+ return (message);
+}
+
+void
+OS2_destroy_message (msg_t * message)
+{
+ OS_free ((void *) message);
+}
+
+void
+OS2_send_message (qid_t qid, msg_t * message)
+{
+ qid_t twin = (QID_TWIN (qid));
+ tqueue_t * tqueue = (QID_TQUEUE (twin));
+ if (tqueue == 0)
+ OS2_logic_error ("Write to closed QID.");
+ (MSG_SENDER (message)) = twin;
+ write_tqueue (tqueue, message);
+}
+
+msg_t *
+OS2_receive_message (qid_t qid, int blockp)
+{
+ tqueue_t * tqueue = (QID_TQUEUE (qid));
+ msg_t * message;
+ while (1)
+ {
+ read_and_dispatch_nonblocking (tqueue);
+ if ((TQUEUE_TYPE (tqueue)) == tqt_scm)
+ {
+ process_interrupt_messages ();
+ deliver_pending_interrupts ();
+ }
+ message = (read_subqueue (qid));
+ if ((!blockp) || (message != 0))
+ break;
+ read_and_dispatch_one_blocking (tqueue);
+ }
+ return (message);
+}
+
+static void
+read_and_dispatch_nonblocking (tqueue_t * tqueue)
+{
+ while (read_tqueue (tqueue, 0))
+ ;
+}
+
+static void
+read_and_dispatch_one_blocking (tqueue_t * tqueue)
+{
+ (void) read_tqueue (tqueue, 1);
+}
+\f
+static void
+write_subqueue (msg_t * message)
+{
+ qid_t qid = (MSG_SENDER (message));
+ msg_list_t * tail = (QID_SUBQUEUE_TAIL (qid));
+ msg_list_t * elt = (OS_malloc (sizeof (struct msg_list_s)));
+ (elt -> message) = message;
+ (elt -> next) = 0;
+ if (tail == 0)
+ (QID_SUBQUEUE_HEAD (qid)) = elt;
+ else
+ (tail -> next) = elt;
+ (QID_SUBQUEUE_TAIL (qid)) = elt;
+}
+
+static msg_t *
+read_subqueue (qid_t qid)
+{
+ msg_list_t * head = (QID_SUBQUEUE_HEAD (qid));
+ if (head == 0)
+ return (0);
+ {
+ msg_t * message = (head -> message);
+ (QID_SUBQUEUE_HEAD (qid)) = (head -> next);
+ if ((head -> next) == 0)
+ (QID_SUBQUEUE_TAIL (qid)) = 0;
+ OS_free (head);
+ return (message);
+ }
+}
+
+static int
+subqueue_emptyp (qid_t qid)
+{
+ return ((QID_SUBQUEUE_HEAD (qid)) == 0);
+}
+
+static int
+read_tqueue (tqueue_t * tqueue, int blockp)
+{
+ switch (TQUEUE_TYPE (tqueue))
+ {
+ case tqt_std:
+ return (read_std_tqueue (tqueue, blockp));
+ case tqt_scm:
+ return (read_scm_tqueue (tqueue, blockp));
+ case tqt_pm:
+ return (read_pm_tqueue (tqueue, blockp));
+ }
+}
+
+static void
+write_tqueue (tqueue_t * tqueue, msg_t * message)
+{
+ switch (TQUEUE_TYPE (tqueue))
+ {
+ case tqt_std:
+ write_std_tqueue (tqueue, message);
+ break;
+ case tqt_scm:
+ write_scm_tqueue (tqueue, message);
+ break;
+ case tqt_pm:
+ write_pm_tqueue (tqueue, message);
+ break;
+ }
+}
+\f
+typedef struct
+{
+ tqueue_type_t type;
+ HQUEUE queue; /* queue */
+ HEV event; /* associated event semaphore */
+} std_tqueue_t;
+#define STD_TQUEUE_QUEUE(q) (((std_tqueue_t *) (q)) -> queue)
+#define STD_TQUEUE_EVENT(q) (((std_tqueue_t *) (q)) -> event)
+
+tqueue_t *
+OS2_make_std_tqueue (void)
+{
+ tqueue_t * tqueue = (OS_malloc (sizeof (std_tqueue_t)));
+ (TQUEUE_TYPE (tqueue)) = tqt_std;
+ (STD_TQUEUE_QUEUE (tqueue)) = (OS2_create_queue (QUE_FIFO));
+ (STD_TQUEUE_EVENT (tqueue)) = (OS2_create_event_semaphore ());
+ return (tqueue);
+}
+
+static int
+read_std_tqueue (tqueue_t * tqueue, int blockp)
+{
+ ULONG type;
+ ULONG length;
+ PVOID data;
+ msg_t * message;
+ const char * s = "Non-message read from message queue.";
+
+ if (!OS2_read_queue ((STD_TQUEUE_QUEUE (tqueue)),
+ (&type),
+ (&length),
+ (&data),
+ (blockp ? NULLHANDLE : (STD_TQUEUE_EVENT (tqueue)))))
+ return (0);
+ if (length < (sizeof (msg_t)))
+ OS2_logic_error (s);
+ message = ((msg_t *) data);
+ if ((type != 0) || (length != (MSG_LENGTH (message))))
+ OS2_logic_error (s);
+ write_subqueue (message);
+ return (1);
+}
+
+static void
+write_std_tqueue (tqueue_t * tqueue, msg_t * message)
+{
+ OS2_write_queue ((STD_TQUEUE_QUEUE (tqueue)),
+ 0,
+ (MSG_LENGTH (message)),
+ ((PVOID) message),
+ 0);
+}
+\f
+static tqueue_t *
+make_scm_tqueue (void)
+{
+ tqueue_t * tqueue = (OS2_make_std_tqueue ());
+ (TQUEUE_TYPE (tqueue)) = tqt_scm;
+ return (tqueue);
+}
+
+static int
+read_scm_tqueue (tqueue_t * tqueue, int blockp)
+{
+ /* The handling of the interrupt bit is a little tricky. We clear
+ the bit, then handle any events, and finally clear the bit again.
+ If the bit is set during the second clear, we must loop since
+ another event might have been queued in the window between the
+ last read and the second clear -- and since we cleared the bit no
+ one else is going to look at the queue until another event comes
+ along.
+
+ This code serves two purposes. First, this is the only way to
+ reliably clear the interrupt bit to avoid having an event stuck
+ in the queue and the Scheme thread not bothering to look.
+ Second, if we arrive at this read-dispatch loop by some means
+ other than the attention-interrupt mechanism, this will clear the
+ bit and thus avoid ever invoking the mechanism. */
+ int result = 0;
+ (void) test_and_clear_attention_interrupt ();
+ do
+ if (read_std_tqueue (tqueue, blockp))
+ {
+ result = 1;
+ /* If blockp was set, after we have read one message we read
+ any remaining messages in non-blocking mode. */
+ blockp = 0;
+ }
+ while (test_and_clear_attention_interrupt ());
+ return (result);
+}
+
+static void
+write_scm_tqueue (tqueue_t * tqueue, msg_t * message)
+{
+ write_std_tqueue (tqueue, message);
+ request_attention_interrupt ();
+}
+
+void
+OS2_handle_attention_interrupt (void)
+{
+ read_and_dispatch_nonblocking (QID_TQUEUE (OS2_interrupt_qid_local));
+ process_interrupt_messages ();
+}
+
+static void
+process_interrupt_messages (void)
+{
+ /* Reads all of the interrupts out of the interrupt queue, and sets
+ the corresponding bits in the interrupt word. */
+ while (1)
+ {
+ msg_t * message = (read_subqueue (OS2_interrupt_qid_local));
+ if (message == 0)
+ break;
+ switch (MSG_TYPE (message))
+ {
+ case mt_console_interrupt:
+ tty_set_next_interrupt_char (SM_CONSOLE_INTERRUPT_CODE (message));
+ break;
+ case mt_timer_event:
+ request_timer_interrupt ();
+ break;
+ default:
+ OS2_logic_error ("Illegal message type in interrupt queue.");
+ break;
+ }
+ OS2_destroy_message (message);
+ }
+}
+\f
+static int
+read_pm_tqueue (tqueue_t * tqueue, int blockp)
+{
+ return (0);
+}
+
+static void
+write_pm_tqueue (tqueue_t * tqueue, msg_t * message)
+{
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2msg.h,v 1.1 1994/11/28 03:42:59 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_OS2MSG_H
+#define SCM_OS2MSG_H
+\f
+typedef enum
+{
+ mt_readahead,
+ mt_readahead_ack,
+ mt_console_interrupt,
+ mt_error,
+ mt_kill_request,
+ mt_syscall_error,
+ mt_timer_event,
+ mt_supremum
+} msg_type_t;
+#define MSG_TYPE_SUP ((unsigned int) mt_supremum)
+#define MSG_TYPE_MAX (MSG_TYPE_SUP - 1)
+
+typedef unsigned char qid_t;
+#define QID_MAX (UCHAR_MAX - 1)
+#define QID_NONE UCHAR_MAX
+
+typedef unsigned short msg_length_t;
+#define MSG_LENGTH_MAX USHRT_MAX
+
+/* Fields of message header:
+ type: small integer classifying the type of message
+ sender: qid identifying the message sender (used for replies)
+ */
+
+#define DECLARE_MSG_HEADER_FIELDS \
+ unsigned char type; \
+ qid_t sender
+
+typedef struct
+{
+ DECLARE_MSG_HEADER_FIELDS;
+} msg_t;
+
+#define _MSG(m) ((msg_t *) (m))
+#define _MSG_TYPE(m) ((_MSG (m)) -> type)
+#define MSG_TYPE(m) ((msg_type_t) (_MSG_TYPE (m)))
+#define MSG_SENDER(m) ((_MSG (m)) -> sender)
+
+typedef enum
+{
+ tqt_std,
+ tqt_scm,
+ tqt_pm
+} tqueue_type_t;
+
+typedef struct
+{
+ tqueue_type_t type;
+} tqueue_t;
+#define TQUEUE_TYPE(q) (((tqueue_t *) (q)) -> type)
+
+extern tqueue_t * OS2_scheme_tqueue;
+extern qid_t OS2_interrupt_qid;
+
+extern void OS2_make_qid_pair (qid_t *, qid_t *);
+extern void OS2_open_qid (qid_t, tqueue_t *);
+extern int OS2_qid_openp (qid_t);
+extern void OS2_close_qid (qid_t);
+extern msg_length_t OS2_message_type_length (msg_type_t);
+extern void OS2_set_message_type_length (msg_type_t, msg_length_t);
+extern msg_t * OS2_create_message (msg_type_t);
+extern void OS2_destroy_message (msg_t *);
+extern void OS2_send_message (qid_t, msg_t *);
+extern msg_t * OS2_receive_message (qid_t, int);
+extern tqueue_t * OS2_make_std_tqueue (void);
+
+#define MSG_LENGTH(m) (OS2_message_type_length (MSG_TYPE (m)))
+
+#define SET_MSG_TYPE_LENGTH(t, s) \
+ OS2_set_message_type_length ((t), (sizeof (s)))
+
+typedef struct
+{
+ DECLARE_MSG_HEADER_FIELDS;
+ int code;
+} sm_console_interrupt_t;
+#define SM_CONSOLE_INTERRUPT_CODE(m) (((sm_console_interrupt_t *) (m)) -> code)
+
+typedef msg_t sm_timer_event_t;
+
+#endif /* SCM_OS2MSG_H */
--- /dev/null
+/* -*-C-*-
+
+$Id: os2pipe.c,v 1.1 1994/11/28 03:42:59 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+
+static void input_pipe_operator
+ (Tchannel, chop_t, choparg_t, choparg_t, choparg_t);
+static void input_pipe_thread (void *);
+\f
+void
+OS_make_pipe (Tchannel * readerp, Tchannel * writerp)
+{
+ HFILE hread;
+ HFILE hwrite;
+ STD_API_CALL (dos_create_pipe, ((&hread), (&hwrite), 4096));
+ transaction_begin ();
+ OS2_handle_close_on_abort (hwrite);
+ (*readerp) = (OS2_make_channel (hread, CHANNEL_READ));
+ transaction_commit ();
+ transaction_begin ();
+ OS_channel_close_on_abort (*readerp);
+ (*writerp) = (OS2_make_channel (hwrite, CHANNEL_WRITE));
+ transaction_commit ();
+}
+\f
+void
+OS2_initialize_pipe_channel (Tchannel channel)
+{
+ if (CHANNEL_INPUTP (channel))
+ {
+ channel_context_t * context = (OS2_make_channel_context ());
+ (CHANNEL_OPERATOR_CONTEXT (channel)) = context;
+ OS2_open_qid ((CHANNEL_CONTEXT_READER_QID (context)), OS2_scheme_tqueue);
+ (void) OS2_beginthread
+ (input_pipe_thread, (CHANNEL_POINTER (channel)), 0);
+ (CHANNEL_OPERATOR (channel)) = input_pipe_operator;
+ }
+}
+
+static void
+input_pipe_operator (Tchannel channel, chop_t operation,
+ choparg_t arg1, choparg_t arg2, choparg_t arg3)
+{
+ switch (operation)
+ {
+ case chop_read:
+ (* ((long *) arg3))
+ = (channel_thread_read (channel, ((char *) arg1), ((size_t) arg2)));
+ break;
+ case chop_close:
+ channel_thread_close (channel);
+ break;
+ default:
+ OS2_logic_error ("Unknown operation for input pipe.");
+ break;
+ }
+}
+
+static void
+input_pipe_thread (void * arg)
+{
+ Tchannel channel = (* ((Tchannel *) arg));
+ LHANDLE handle = (CHANNEL_HANDLE (channel));
+ channel_context_t * context = (CHANNEL_OPERATOR_CONTEXT (channel));
+ qid_t qid = (CHANNEL_CONTEXT_WRITER_QID (context));
+ OS2_open_qid (qid, (OS2_make_std_tqueue ()));
+ (void) OS2_thread_initialize (qid);
+ while (1)
+ {
+ msg_t * message = (OS2_make_readahead ());
+ APIRET rc
+ = (dos_read (handle,
+ (SM_READAHEAD_DATA (message)),
+ (sizeof (SM_READAHEAD_DATA (message))),
+ (& (SM_READAHEAD_SIZE (message)))));
+ int eofp;
+ if (rc == NO_ERROR)
+ eofp = ((SM_READAHEAD_SIZE (message)) == 0);
+ else
+ {
+ OS2_destroy_message (message);
+ if (rc == ERROR_INVALID_HANDLE)
+ /* Handle was closed on us -- no need to do anything else. */
+ break;
+ message = (OS2_make_syscall_error (rc, syscall_dos_read));
+ eofp = (rc == ERROR_BROKEN_PIPE);
+ }
+ OS2_send_message (qid, message);
+ if (eofp)
+ break;
+ OS2_wait_for_readahead_ack (qid);
+ }
+ OS2_endthread ();
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2term.c,v 1.1 1994/11/28 03:43:00 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+\f
+unsigned int
+OS_terminal_get_ispeed (Tchannel channel)
+{
+ return (9600);
+}
+
+unsigned int
+OS_terminal_get_ospeed (Tchannel channel)
+{
+ return (9600);
+}
+
+void
+OS_terminal_set_ispeed (Tchannel channel, unsigned int baud)
+{
+}
+
+void
+OS_terminal_set_ospeed (Tchannel channel, unsigned int baud)
+{
+}
+
+unsigned int
+arg_baud_index (unsigned int argument)
+{
+ return (arg_nonnegative_integer (argument));
+}
+
+unsigned int
+OS_baud_index_to_rate (unsigned int index)
+{
+ return (index);
+}
+
+int
+OS_baud_rate_to_index (unsigned int rate)
+{
+ return (rate);
+}
+
+unsigned int
+OS_terminal_state_size (void)
+{
+ return (0);
+}
+
+void
+OS_terminal_get_state (Tchannel channel, PTR statep)
+{
+}
+
+void
+OS_terminal_set_state (Tchannel channel, PTR statep)
+{
+}
+\f
+int
+OS_terminal_cooked_output_p (Tchannel channel)
+{
+ int flag;
+ OS2_channel_operation (channel, chop_output_cooked,
+ ((choparg_t) (-1)), ((choparg_t) (&flag)), 0);
+ return (flag);
+}
+
+void
+OS_terminal_raw_output (Tchannel channel)
+{
+ OS2_channel_operation (channel, chop_output_cooked, ((choparg_t) 0), 0, 0);
+}
+
+void
+OS_terminal_cooked_output (Tchannel channel)
+{
+ OS2_channel_operation (channel, chop_output_cooked, ((choparg_t) 1), 0, 0);
+}
+
+int
+OS_terminal_buffered_p (Tchannel channel)
+{
+ int flag;
+ OS2_channel_operation (channel, chop_input_buffered,
+ ((choparg_t) (-1)), ((choparg_t) (&flag)), 0);
+ return (flag);
+}
+
+void
+OS_terminal_buffered (Tchannel channel)
+{
+ OS2_channel_operation (channel, chop_input_buffered, ((choparg_t) 0), 0, 0);
+}
+
+void
+OS_terminal_nonbuffered (Tchannel channel)
+{
+ OS2_channel_operation (channel, chop_input_buffered, ((choparg_t) 1), 0, 0);
+}
+
+void
+OS_terminal_flush_input (Tchannel channel)
+{
+ OS2_channel_operation (channel, chop_input_flush, 0, 0, 0);
+}
+
+void
+OS_terminal_flush_output (Tchannel channel)
+{
+ OS2_channel_operation (channel, chop_output_flush, 0, 0, 0);
+}
+
+void
+OS_terminal_drain_output (Tchannel channel)
+{
+ OS2_channel_operation (channel, chop_output_drain, 0, 0, 0);
+}
+
+int
+OS_job_control_p (void)
+{
+ return (0);
+}
+
+int
+OS_have_ptys_p (void)
+{
+ return (0);
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2thrd.c,v 1.1 1994/11/28 03:43:00 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+#include "prims.h"
+#include "errors.h"
+\f
+TID
+OS2_beginthread (thread_procedure_t procedure,
+ void * argument,
+ unsigned int stack_size)
+{
+ ULONG ss
+ = ((stack_size < 0x2000)
+ ? 0x2000
+ : ((stack_size + 0xfff) & (~0xfff)));
+#ifdef __IBMC__
+ int result = (_beginthread (procedure, 0, ss, argument));
+ if (result < 0)
+ OS2_error_system_call (ERROR_MAX_THRDS_REACHED, syscall_beginthread);
+ return (result);
+#else /* not __IBMC__ */
+ TID tid;
+ STD_API_CALL (dos_create_thread,
+ ((&tid), ((PFNTHREAD) procedure), ((ULONG) argument), 0, ss));
+ return (tid);
+#endif /* not __IBMC__ */
+}
+
+void
+OS2_endthread (void)
+{
+#ifdef __IBMC__
+ _endthread ();
+#else
+ dos_exit (EXIT_THREAD, 0);
+#endif
+}
+
+void
+OS2_kill_thread (TID tid)
+{
+ STD_API_CALL (dos_kill_thread, (tid));
+}
+
+#ifndef __IBMC__
+#define MAX_TID 999
+static thread_store_t * thread_store_array [MAX_TID + 1];
+
+thread_store_t **
+OS2_threadstore (void)
+{
+ PTIB ptib;
+ PPIB ppib;
+ TID tid;
+ STD_API_CALL (dos_get_info_blocks, ((&ptib), (&ppib)));
+ tid = (ptib -> tib_ptib2 -> tib2_ultid);
+ if (tid > MAX_TID)
+ OS2_logic_error ("Unexpectedly large TID.");
+ return (& (thread_store_array [tid]));
+}
+#endif
+\f
+PID OS2_scheme_pid;
+TID OS2_scheme_tid;
+
+static void thread_initialize_1 (qid_t);
+static int thread_initialize_error_hook (void);
+static void restore_errors (void *);
+static void signal_error (msg_t *);
+static void ignore_error (msg_t *);
+static void send_error (msg_t *);
+
+void
+OS2_initialize_scheme_thread (void)
+{
+ SET_MSG_TYPE_LENGTH (mt_syscall_error, sm_syscall_error_t);
+ SET_MSG_TYPE_LENGTH (mt_error, sm_error_t);
+ SET_MSG_TYPE_LENGTH (mt_kill_request, sm_kill_request_t);
+ {
+ PTIB ptib;
+ PPIB ppib;
+ STD_API_CALL (dos_get_info_blocks, ((&ptib), (&ppib)));
+ OS2_scheme_pid = (ppib -> pib_ulpid);
+ OS2_scheme_tid = (ptib -> tib_ptib2 -> tib2_ultid);
+ }
+ thread_initialize_1 (QID_NONE);
+ (THREAD_ERROR_HOOK ()) = signal_error;
+}
+
+int
+OS2_thread_initialize (qid_t error_qid)
+{
+ thread_initialize_1 (error_qid);
+ return (thread_initialize_error_hook ());
+}
+
+static void
+thread_initialize_1 (qid_t error_qid)
+{
+ (* (OS2_threadstore ())) = (OS_malloc (sizeof (thread_store_t)));
+ (THREAD_ERROR_QUEUE ()) = error_qid;
+}
+
+static int
+thread_initialize_error_hook (void)
+{
+ (THREAD_ERROR_HOOK ()) = send_error;
+ return (setjmp (THREAD_ERROR_RESTART ()));
+}
+\f
+int
+OS2_error_message_p (msg_t * message)
+{
+ msg_type_t type = (MSG_TYPE (message));
+ return ((type == mt_syscall_error) || (type == mt_error));
+}
+
+void
+OS2_handle_error_message (msg_t * message)
+{
+ (* (THREAD_ERROR_HOOK ())) (message);
+}
+
+void
+OS2_ignore_errors (void)
+{
+ error_hook_t * hp = (dstack_alloc (sizeof (error_hook_t)));
+ (*hp) = (THREAD_ERROR_HOOK ());
+ transaction_record_action (tat_always, restore_errors, hp);
+ (THREAD_ERROR_HOOK ()) = ignore_error;
+}
+
+static void
+restore_errors (void * hp)
+{
+ (THREAD_ERROR_HOOK ()) = (* ((error_hook_t *) hp));
+}
+
+void
+OS2_error_system_call (int code, enum syscall_names name)
+{
+ OS2_handle_error_message (OS2_make_syscall_error (code, name));
+}
+
+void
+OS2_error_anonymous (void)
+{
+ OS2_handle_error_message (OS2_make_error (ERR_EXTERNAL_RETURN));
+}
+
+void
+OS2_error_unimplemented_primitive (void)
+{
+ OS2_handle_error_message (OS2_make_error (ERR_UNDEFINED_PRIMITIVE));
+}
+
+void
+OS2_error_out_of_channels (void)
+{
+ OS2_handle_error_message (OS2_make_error (ERR_OUT_OF_FILE_HANDLES));
+}
+\f
+static void
+signal_error (msg_t * message)
+{
+ switch (MSG_TYPE (message))
+ {
+ case mt_syscall_error:
+ {
+ int code = (SM_SYSCALL_ERROR_CODE (message));
+ enum syscall_names name = (SM_SYSCALL_ERROR_NAME (message));
+ OS2_destroy_message (message);
+ error_system_call (code, name);
+ }
+ break;
+ case mt_error:
+ {
+ long code = (SM_ERROR_CODE (message));
+ OS2_destroy_message (message);
+ signal_error_from_primitive (code);
+ }
+ break;
+ default:
+ OS2_logic_error ("Non-error message passed to signal_error.");
+ break;
+ }
+}
+
+static void
+ignore_error (msg_t * message)
+{
+}
+
+static void
+send_error (msg_t * message)
+{
+ if ((THREAD_ERROR_QUEUE ()) == QID_NONE)
+ OS2_logic_error ("send_error called when no error queue defined.");
+ OS2_send_message ((THREAD_ERROR_QUEUE ()), message);
+ longjmp ((THREAD_ERROR_RESTART ()), 1);
+}
+
+msg_t *
+OS2_make_syscall_error (int code, enum syscall_names name)
+{
+ msg_t * message = (OS2_create_message (mt_syscall_error));
+ (SM_SYSCALL_ERROR_CODE (message)) = code;
+ (SM_SYSCALL_ERROR_NAME (message)) = name;
+ return (message);
+}
+
+msg_t *
+OS2_make_error (long code)
+{
+ msg_t * message = (OS2_create_message (mt_error));
+ (SM_ERROR_CODE (message)) = code;
+ return (message);
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2thrd.h,v 1.1 1994/11/28 03:43:01 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_OS2THRD_H
+#define SCM_OS2THRD_H
+\f
+typedef void (* thread_procedure_t) (void *);
+typedef void (* error_hook_t) (msg_t *);
+
+typedef struct
+{
+ error_hook_t error_hook;
+ jmp_buf error_restart;
+ qid_t error_queue;
+} thread_store_t;
+#define THREAD_ERROR_HOOK() ((* (OS2_threadstore ())) -> error_hook)
+#define THREAD_ERROR_RESTART() ((* (OS2_threadstore ())) -> error_restart)
+#define THREAD_ERROR_QUEUE() ((* (OS2_threadstore ())) -> error_queue)
+
+typedef struct
+{
+ DECLARE_MSG_HEADER_FIELDS;
+ int code;
+ enum syscall_names name;
+} sm_syscall_error_t;
+#define SM_SYSCALL_ERROR_CODE(m) (((sm_syscall_error_t *) (m)) -> code)
+#define SM_SYSCALL_ERROR_NAME(m) (((sm_syscall_error_t *) (m)) -> name)
+
+typedef struct
+{
+ DECLARE_MSG_HEADER_FIELDS;
+ long code;
+} sm_error_t;
+#define SM_ERROR_CODE(m) (((sm_error_t *) (m)) -> code)
+
+typedef msg_t sm_kill_request_t;
+#define OS2_make_kill_request() OS2_create_message (mt_kill_request)
+
+extern TID OS2_beginthread (thread_procedure_t, void *, unsigned int);
+extern void OS2_endthread (void);
+extern void OS2_kill_thread (TID);
+
+#ifdef __IBMC__
+#define OS2_threadstore() ((thread_store_t **) (_threadstore ()))
+#else
+extern thread_store_t ** OS2_threadstore (void);
+#endif
+
+extern PID OS2_scheme_pid;
+extern TID OS2_scheme_tid;
+
+extern int OS2_thread_initialize (qid_t);
+extern int OS2_error_message_p (msg_t *);
+extern void OS2_handle_error_message (msg_t *);
+extern void OS2_ignore_errors (void);
+extern void OS2_error_system_call (int, enum syscall_names);
+extern void OS2_error_anonymous (void);
+extern void OS2_error_unimplemented_primitive (void);
+extern void OS2_error_out_of_channels (void);
+extern msg_t * OS2_make_syscall_error (int, enum syscall_names);
+extern msg_t * OS2_make_error (long);
+
+#endif /* SCM_OS2THRD_H */
--- /dev/null
+/* -*-C-*-
+
+$Id: os2top.c,v 1.1 1994/11/28 03:43:01 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+#include "ostop.h"
+#include "option.h"
+
+extern void OS2_initialize_channels (void);
+extern void OS2_initialize_channel_thread_messages (void);
+extern void OS2_initialize_console (void);
+extern void OS2_initialize_directory_reader (void);
+extern void OS2_initialize_environment (void);
+extern void OS2_initialize_keyboard_interrupts (void);
+extern void OS2_initialize_message_queues (void);
+extern void OS2_initialize_scheme_thread (void);
+extern void OS2_initialize_tty (void);
+
+extern const char * OS_Name;
+extern const char * OS_Variant;
+
+static const char * OS2_version_string (void);
+static void initialize_locks (void);
+\f
+int
+OS_under_emacs_p (void)
+{
+ return (option_emacs_subprocess);
+}
+
+void
+OS_initialize (void)
+{
+ transaction_initialize ();
+ initialize_locks ();
+ OS2_initialize_message_queues ();
+ OS2_initialize_scheme_thread ();
+ OS2_initialize_channels ();
+ OS2_initialize_channel_thread_messages ();
+ OS2_initialize_keyboard_interrupts ();
+ OS2_initialize_console ();
+ OS2_initialize_environment ();
+ OS2_initialize_directory_reader ();
+ OS2_initialize_tty ();
+ OS_Name = "OS/2";
+ {
+ const char * version = (OS2_version_string ());
+ OS_Variant = (OS_malloc ((strlen (OS_Name)) + (strlen (version)) + 2));
+ sprintf (((char *) OS_Variant), "%s %s", OS_Name, version);
+ }
+ outf_console ("MIT Scheme running under %s\n", OS_Variant);
+ outf_flush_console ();
+}
+
+static const char *
+OS2_version_string (void)
+{
+ ULONG major = (OS2_system_variable (QSV_VERSION_MAJOR));
+ ULONG minor = (OS2_system_variable (QSV_VERSION_MINOR));
+ char revision = (OS2_system_variable (QSV_VERSION_REVISION));
+ static char result [64];
+ char sminor [16];
+ char srev [2];
+ if ((major == 20) && (minor == 30))
+ {
+ major = 30;
+ minor = 0;
+ }
+ if ((minor < 10) && (minor != 0))
+ sprintf (sminor, "0%d", minor);
+ else
+ sprintf (sminor, "%d",
+ (((minor < 100) && ((minor % 10) == 0)) ? (minor / 10) : minor));
+ if (revision == '\0')
+ sprintf (srev, "");
+ else
+ sprintf (srev, "%c", revision);
+ sprintf (result, "%d.%s%s", (major / 10), sminor, srev);
+ return (result);
+}
+
+void
+OS2_exit_scheme (int value)
+{
+ extern void OS2_kill_timer_thread (void);
+ OS2_kill_timer_thread ();
+ OS2_channel_close_all_noerror ();
+ exit (value);
+}
+
+void
+OS_reset (void)
+{
+ execute_reload_cleanups ();
+}
+\f
+void
+OS_quit (int code, int abnormal_p)
+{
+ outf_flush_console ();
+ OS_restore_external_state ();
+}
+
+void
+OS_save_external_state (void)
+{
+}
+
+void
+OS_save_internal_state (void)
+{
+}
+
+void
+OS_restore_internal_state (void)
+{
+}
+
+void
+OS_restore_external_state (void)
+{
+}
+
+void
+preserve_signal_mask (void)
+{
+}
+
+void
+block_signals (void)
+{
+}
+
+void
+unblock_signals (void)
+{
+}
+
+void
+OS_restartable_exit (void)
+{
+}
+
+long
+OS_set_trap_state (long arg)
+{
+ return (arg);
+}
+
+#ifdef __IBMC__
+void
+bcopy (const char * from, char * to, unsigned int n)
+{
+ FASTCOPY (from, to, n);
+}
+#endif
+\f
+static HMTX interrupt_registers_lock;
+
+static void
+initialize_locks (void)
+{
+ interrupt_registers_lock = (OS2_create_mutex_semaphore ());
+}
+
+void
+OS_grab_interrupt_registers (void)
+{
+ OS2_request_mutex_semaphore (interrupt_registers_lock);
+}
+
+void
+OS_release_interrupt_registers (void)
+{
+ OS2_release_mutex_semaphore (interrupt_registers_lock);
+}
+\f
+/* Machine-generated procedure, do not edit: */
+enum syserr_names
+OS_error_code_to_syserr (int code)
+{
+ switch (code)
+ {
+ case ERROR_INVALID_FUNCTION: return (syserr_invalid_function);
+ case ERROR_FILE_NOT_FOUND: return (syserr_file_not_found);
+ case ERROR_PATH_NOT_FOUND: return (syserr_path_not_found);
+ case ERROR_TOO_MANY_OPEN_FILES: return (syserr_too_many_open_files);
+ case ERROR_ACCESS_DENIED: return (syserr_access_denied);
+ case ERROR_INVALID_HANDLE: return (syserr_invalid_handle);
+ case ERROR_ARENA_TRASHED: return (syserr_arena_trashed);
+ case ERROR_NOT_ENOUGH_MEMORY: return (syserr_not_enough_memory);
+ case ERROR_INVALID_BLOCK: return (syserr_invalid_block);
+ case ERROR_BAD_ENVIRONMENT: return (syserr_bad_environment);
+ case ERROR_BAD_FORMAT: return (syserr_bad_format);
+ case ERROR_INVALID_ACCESS: return (syserr_invalid_access);
+ case ERROR_INVALID_DATA: return (syserr_invalid_data);
+ case ERROR_INVALID_DRIVE: return (syserr_invalid_drive);
+ case ERROR_CURRENT_DIRECTORY: return (syserr_current_directory);
+ case ERROR_NOT_SAME_DEVICE: return (syserr_not_same_device);
+ case ERROR_NO_MORE_FILES: return (syserr_no_more_files);
+ case ERROR_WRITE_PROTECT: return (syserr_write_protect);
+ case ERROR_BAD_UNIT: return (syserr_bad_unit);
+ case ERROR_NOT_READY: return (syserr_not_ready);
+ case ERROR_BAD_COMMAND: return (syserr_bad_command);
+ case ERROR_CRC: return (syserr_crc);
+ case ERROR_BAD_LENGTH: return (syserr_bad_length);
+ case ERROR_SEEK: return (syserr_seek);
+ case ERROR_NOT_DOS_DISK: return (syserr_not_dos_disk);
+ case ERROR_SECTOR_NOT_FOUND: return (syserr_sector_not_found);
+ case ERROR_OUT_OF_PAPER: return (syserr_out_of_paper);
+ case ERROR_WRITE_FAULT: return (syserr_write_fault);
+ case ERROR_READ_FAULT: return (syserr_read_fault);
+ case ERROR_GEN_FAILURE: return (syserr_gen_failure);
+ case ERROR_SHARING_VIOLATION: return (syserr_sharing_violation);
+ case ERROR_LOCK_VIOLATION: return (syserr_lock_violation);
+ case ERROR_WRONG_DISK: return (syserr_wrong_disk);
+ case ERROR_FCB_UNAVAILABLE: return (syserr_fcb_unavailable);
+ case ERROR_SHARING_BUFFER_EXCEEDED: return (syserr_sharing_buffer_exceeded);
+ case ERROR_CODE_PAGE_MISMATCHED: return (syserr_code_page_mismatched);
+ case ERROR_HANDLE_EOF: return (syserr_handle_eof);
+ case ERROR_HANDLE_DISK_FULL: return (syserr_handle_disk_full);
+ case ERROR_NOT_SUPPORTED: return (syserr_not_supported);
+ case ERROR_REM_NOT_LIST: return (syserr_rem_not_list);
+ case ERROR_DUP_NAME: return (syserr_dup_name);
+ case ERROR_BAD_NETPATH: return (syserr_bad_netpath);
+ case ERROR_NETWORK_BUSY: return (syserr_network_busy);
+ case ERROR_DEV_NOT_EXIST: return (syserr_dev_not_exist);
+ case ERROR_TOO_MANY_CMDS: return (syserr_too_many_cmds);
+ case ERROR_ADAP_HDW_ERR: return (syserr_adap_hdw_err);
+ case ERROR_BAD_NET_RESP: return (syserr_bad_net_resp);
+ case ERROR_UNEXP_NET_ERR: return (syserr_unexp_net_err);
+ case ERROR_BAD_REM_ADAP: return (syserr_bad_rem_adap);
+ case ERROR_PRINTQ_FULL: return (syserr_printq_full);
+ case ERROR_NO_SPOOL_SPACE: return (syserr_no_spool_space);
+ case ERROR_PRINT_CANCELLED: return (syserr_print_cancelled);
+ case ERROR_NETNAME_DELETED: return (syserr_netname_deleted);
+ case ERROR_NETWORK_ACCESS_DENIED: return (syserr_network_access_denied);
+ case ERROR_BAD_DEV_TYPE: return (syserr_bad_dev_type);
+ case ERROR_BAD_NET_NAME: return (syserr_bad_net_name);
+ case ERROR_TOO_MANY_NAMES: return (syserr_too_many_names);
+ case ERROR_TOO_MANY_SESS: return (syserr_too_many_sess);
+ case ERROR_SHARING_PAUSED: return (syserr_sharing_paused);
+ case ERROR_REQ_NOT_ACCEP: return (syserr_req_not_accep);
+ case ERROR_REDIR_PAUSED: return (syserr_redir_paused);
+ case ERROR_SBCS_ATT_WRITE_PROT: return (syserr_sbcs_att_write_prot);
+ case ERROR_SBCS_GENERAL_FAILURE: return (syserr_sbcs_general_failure);
+ case ERROR_XGA_OUT_MEMORY: return (syserr_xga_out_memory);
+ case ERROR_FILE_EXISTS: return (syserr_file_exists);
+ case ERROR_DUP_FCB: return (syserr_dup_fcb);
+ case ERROR_CANNOT_MAKE: return (syserr_cannot_make);
+ case ERROR_FAIL_I24: return (syserr_fail_i24);
+ case ERROR_OUT_OF_STRUCTURES: return (syserr_out_of_structures);
+ case ERROR_ALREADY_ASSIGNED: return (syserr_already_assigned);
+ case ERROR_INVALID_PASSWORD: return (syserr_invalid_password);
+ case ERROR_INVALID_PARAMETER: return (syserr_invalid_parameter);
+ case ERROR_NET_WRITE_FAULT: return (syserr_net_write_fault);
+ case ERROR_NO_PROC_SLOTS: return (syserr_no_proc_slots);
+ case ERROR_NOT_FROZEN: return (syserr_not_frozen);
+ case ERR_TSTOVFL: return (syserr_tstovfl);
+ case ERR_TSTDUP: return (syserr_tstdup);
+ case ERROR_NO_ITEMS: return (syserr_no_items);
+ case ERROR_INTERRUPT: return (syserr_interrupt);
+ case ERROR_DEVICE_IN_USE: return (syserr_device_in_use);
+ case ERROR_TOO_MANY_SEMAPHORES: return (syserr_too_many_semaphores);
+ case ERROR_EXCL_SEM_ALREADY_OWNED: return (syserr_excl_sem_already_owned);
+ case ERROR_SEM_IS_SET: return (syserr_sem_is_set);
+ case ERROR_TOO_MANY_SEM_REQUESTS: return (syserr_too_many_sem_requests);
+ case ERROR_INVALID_AT_INTERRUPT_TIME: return (syserr_invalid_at_interrupt_time);
+ case ERROR_SEM_OWNER_DIED: return (syserr_sem_owner_died);
+ case ERROR_SEM_USER_LIMIT: return (syserr_sem_user_limit);
+ case ERROR_DISK_CHANGE: return (syserr_disk_change);
+ case ERROR_DRIVE_LOCKED: return (syserr_drive_locked);
+ case ERROR_BROKEN_PIPE: return (syserr_broken_pipe);
+ case ERROR_OPEN_FAILED: return (syserr_open_failed);
+ case ERROR_BUFFER_OVERFLOW: return (syserr_buffer_overflow);
+ case ERROR_DISK_FULL: return (syserr_disk_full);
+ case ERROR_NO_MORE_SEARCH_HANDLES: return (syserr_no_more_search_handles);
+ case ERROR_INVALID_TARGET_HANDLE: return (syserr_invalid_target_handle);
+ case ERROR_PROTECTION_VIOLATION: return (syserr_protection_violation);
+ case ERROR_VIOKBD_REQUEST: return (syserr_viokbd_request);
+ case ERROR_INVALID_CATEGORY: return (syserr_invalid_category);
+ case ERROR_INVALID_VERIFY_SWITCH: return (syserr_invalid_verify_switch);
+ case ERROR_BAD_DRIVER_LEVEL: return (syserr_bad_driver_level);
+ case ERROR_CALL_NOT_IMPLEMENTED: return (syserr_call_not_implemented);
+ case ERROR_SEM_TIMEOUT: return (syserr_sem_timeout);
+ case ERROR_INSUFFICIENT_BUFFER: return (syserr_insufficient_buffer);
+ case ERROR_INVALID_NAME: return (syserr_invalid_name);
+ case ERROR_INVALID_LEVEL: return (syserr_invalid_level);
+ case ERROR_NO_VOLUME_LABEL: return (syserr_no_volume_label);
+ case ERROR_MOD_NOT_FOUND: return (syserr_mod_not_found);
+ case ERROR_PROC_NOT_FOUND: return (syserr_proc_not_found);
+ case ERROR_WAIT_NO_CHILDREN: return (syserr_wait_no_children);
+ case ERROR_CHILD_NOT_COMPLETE: return (syserr_child_not_complete);
+ case ERROR_DIRECT_ACCESS_HANDLE: return (syserr_direct_access_handle);
+ case ERROR_NEGATIVE_SEEK: return (syserr_negative_seek);
+ case ERROR_SEEK_ON_DEVICE: return (syserr_seek_on_device);
+ case ERROR_IS_JOIN_TARGET: return (syserr_is_join_target);
+ case ERROR_IS_JOINED: return (syserr_is_joined);
+ case ERROR_IS_SUBSTED: return (syserr_is_substed);
+ case ERROR_NOT_JOINED: return (syserr_not_joined);
+ case ERROR_NOT_SUBSTED: return (syserr_not_substed);
+ case ERROR_JOIN_TO_JOIN: return (syserr_join_to_join);
+ case ERROR_SUBST_TO_SUBST: return (syserr_subst_to_subst);
+ case ERROR_JOIN_TO_SUBST: return (syserr_join_to_subst);
+ case ERROR_SUBST_TO_JOIN: return (syserr_subst_to_join);
+ case ERROR_BUSY_DRIVE: return (syserr_busy_drive);
+ case ERROR_SAME_DRIVE: return (syserr_same_drive);
+ case ERROR_DIR_NOT_ROOT: return (syserr_dir_not_root);
+ case ERROR_DIR_NOT_EMPTY: return (syserr_dir_not_empty);
+ case ERROR_IS_SUBST_PATH: return (syserr_is_subst_path);
+ case ERROR_IS_JOIN_PATH: return (syserr_is_join_path);
+ case ERROR_PATH_BUSY: return (syserr_path_busy);
+ case ERROR_IS_SUBST_TARGET: return (syserr_is_subst_target);
+ case ERROR_SYSTEM_TRACE: return (syserr_system_trace);
+ case ERROR_INVALID_EVENT_COUNT: return (syserr_invalid_event_count);
+ case ERROR_TOO_MANY_MUXWAITERS: return (syserr_too_many_muxwaiters);
+ case ERROR_INVALID_LIST_FORMAT: return (syserr_invalid_list_format);
+ case ERROR_LABEL_TOO_LONG: return (syserr_label_too_long);
+ case ERROR_TOO_MANY_TCBS: return (syserr_too_many_tcbs);
+ case ERROR_SIGNAL_REFUSED: return (syserr_signal_refused);
+ case ERROR_DISCARDED: return (syserr_discarded);
+ case ERROR_NOT_LOCKED: return (syserr_not_locked);
+ case ERROR_BAD_THREADID_ADDR: return (syserr_bad_threadid_addr);
+ case ERROR_BAD_ARGUMENTS: return (syserr_bad_arguments);
+ case ERROR_BAD_PATHNAME: return (syserr_bad_pathname);
+ case ERROR_SIGNAL_PENDING: return (syserr_signal_pending);
+ case ERROR_UNCERTAIN_MEDIA: return (syserr_uncertain_media);
+ case ERROR_MAX_THRDS_REACHED: return (syserr_max_thrds_reached);
+ case ERROR_MONITORS_NOT_SUPPORTED: return (syserr_monitors_not_supported);
+ case ERROR_UNC_DRIVER_NOT_INSTALLED: return (syserr_unc_driver_not_installed);
+ case ERROR_LOCK_FAILED: return (syserr_lock_failed);
+ case ERROR_SWAPIO_FAILED: return (syserr_swapio_failed);
+ case ERROR_SWAPIN_FAILED: return (syserr_swapin_failed);
+ case ERROR_BUSY: return (syserr_busy);
+ case ERROR_CANCEL_VIOLATION: return (syserr_cancel_violation);
+ case ERROR_ATOMIC_LOCK_NOT_SUPPORTED: return (syserr_atomic_lock_not_supported);
+ case ERROR_READ_LOCKS_NOT_SUPPORTED: return (syserr_read_locks_not_supported);
+ case ERROR_INVALID_SEGMENT_NUMBER: return (syserr_invalid_segment_number);
+ case ERROR_INVALID_CALLGATE: return (syserr_invalid_callgate);
+ case ERROR_INVALID_ORDINAL: return (syserr_invalid_ordinal);
+ case ERROR_ALREADY_EXISTS: return (syserr_already_exists);
+ case ERROR_NO_CHILD_PROCESS: return (syserr_no_child_process);
+ case ERROR_CHILD_ALIVE_NOWAIT: return (syserr_child_alive_nowait);
+ case ERROR_INVALID_FLAG_NUMBER: return (syserr_invalid_flag_number);
+ case ERROR_SEM_NOT_FOUND: return (syserr_sem_not_found);
+ case ERROR_INVALID_STARTING_CODESEG: return (syserr_invalid_starting_codeseg);
+ case ERROR_INVALID_STACKSEG: return (syserr_invalid_stackseg);
+ case ERROR_INVALID_MODULETYPE: return (syserr_invalid_moduletype);
+ case ERROR_INVALID_EXE_SIGNATURE: return (syserr_invalid_exe_signature);
+ case ERROR_EXE_MARKED_INVALID: return (syserr_exe_marked_invalid);
+ case ERROR_BAD_EXE_FORMAT: return (syserr_bad_exe_format);
+ case ERROR_ITERATED_DATA_EXCEEDS_64k: return (syserr_iterated_data_exceeds_64k);
+ case ERROR_INVALID_MINALLOCSIZE: return (syserr_invalid_minallocsize);
+ case ERROR_DYNLINK_FROM_INVALID_RING: return (syserr_dynlink_from_invalid_ring);
+ case ERROR_IOPL_NOT_ENABLED: return (syserr_iopl_not_enabled);
+ case ERROR_INVALID_SEGDPL: return (syserr_invalid_segdpl);
+ case ERROR_AUTODATASEG_EXCEEDS_64k: return (syserr_autodataseg_exceeds_64k);
+ case ERROR_RING2SEG_MUST_BE_MOVABLE: return (syserr_ring2seg_must_be_movable);
+ case ERROR_RELOC_CHAIN_XEEDS_SEGLIM: return (syserr_reloc_chain_xeeds_seglim);
+ case ERROR_INFLOOP_IN_RELOC_CHAIN: return (syserr_infloop_in_reloc_chain);
+ case ERROR_ENVVAR_NOT_FOUND: return (syserr_envvar_not_found);
+ case ERROR_NOT_CURRENT_CTRY: return (syserr_not_current_ctry);
+ case ERROR_NO_SIGNAL_SENT: return (syserr_no_signal_sent);
+ case ERROR_FILENAME_EXCED_RANGE: return (syserr_filename_exced_range);
+ case ERROR_RING2_STACK_IN_USE: return (syserr_ring2_stack_in_use);
+ case ERROR_META_EXPANSION_TOO_LONG: return (syserr_meta_expansion_too_long);
+ case ERROR_INVALID_SIGNAL_NUMBER: return (syserr_invalid_signal_number);
+ case ERROR_THREAD_1_INACTIVE: return (syserr_thread_1_inactive);
+ case ERROR_INFO_NOT_AVAIL: return (syserr_info_not_avail);
+ case ERROR_LOCKED: return (syserr_locked);
+ case ERROR_BAD_DYNALINK: return (syserr_bad_dynalink);
+ case ERROR_TOO_MANY_MODULES: return (syserr_too_many_modules);
+ case ERROR_NESTING_NOT_ALLOWED: return (syserr_nesting_not_allowed);
+ case ERROR_CANNOT_SHRINK: return (syserr_cannot_shrink);
+ case ERROR_ZOMBIE_PROCESS: return (syserr_zombie_process);
+ case ERROR_STACK_IN_HIGH_MEMORY: return (syserr_stack_in_high_memory);
+ case ERROR_INVALID_EXITROUTINE_RING: return (syserr_invalid_exitroutine_ring);
+ case ERROR_GETBUF_FAILED: return (syserr_getbuf_failed);
+ case ERROR_FLUSHBUF_FAILED: return (syserr_flushbuf_failed);
+ case ERROR_TRANSFER_TOO_LONG: return (syserr_transfer_too_long);
+ case ERROR_FORCENOSWAP_FAILED: return (syserr_forcenoswap_failed);
+ case ERROR_SMG_NO_TARGET_WINDOW: return (syserr_smg_no_target_window);
+ case ERROR_NO_CHILDREN: return (syserr_no_children);
+ case ERROR_INVALID_SCREEN_GROUP: return (syserr_invalid_screen_group);
+ case ERROR_BAD_PIPE: return (syserr_bad_pipe);
+ case ERROR_PIPE_BUSY: return (syserr_pipe_busy);
+ case ERROR_NO_DATA: return (syserr_no_data);
+ case ERROR_PIPE_NOT_CONNECTED: return (syserr_pipe_not_connected);
+ case ERROR_MORE_DATA: return (syserr_more_data);
+ case ERROR_VC_DISCONNECTED: return (syserr_vc_disconnected);
+ case ERROR_CIRCULARITY_REQUESTED: return (syserr_circularity_requested);
+ case ERROR_DIRECTORY_IN_CDS: return (syserr_directory_in_cds);
+ case ERROR_INVALID_FSD_NAME: return (syserr_invalid_fsd_name);
+ case ERROR_INVALID_PATH: return (syserr_invalid_path);
+ case ERROR_INVALID_EA_NAME: return (syserr_invalid_ea_name);
+ case ERROR_EA_LIST_INCONSISTENT: return (syserr_ea_list_inconsistent);
+ case ERROR_EA_LIST_TOO_LONG: return (syserr_ea_list_too_long);
+ case ERROR_NO_META_MATCH: return (syserr_no_meta_match);
+ case ERROR_FINDNOTIFY_TIMEOUT: return (syserr_findnotify_timeout);
+ case ERROR_NO_MORE_ITEMS: return (syserr_no_more_items);
+ case ERROR_SEARCH_STRUC_REUSED: return (syserr_search_struc_reused);
+ case ERROR_CHAR_NOT_FOUND: return (syserr_char_not_found);
+ case ERROR_TOO_MUCH_STACK: return (syserr_too_much_stack);
+ case ERROR_INVALID_ATTR: return (syserr_invalid_attr);
+ case ERROR_INVALID_STARTING_RING: return (syserr_invalid_starting_ring);
+ case ERROR_INVALID_DLL_INIT_RING: return (syserr_invalid_dll_init_ring);
+ case ERROR_CANNOT_COPY: return (syserr_cannot_copy);
+ case ERROR_DIRECTORY: return (syserr_directory);
+ case ERROR_OPLOCKED_FILE: return (syserr_oplocked_file);
+ case ERROR_OPLOCK_THREAD_EXISTS: return (syserr_oplock_thread_exists);
+ case ERROR_VOLUME_CHANGED: return (syserr_volume_changed);
+ case ERROR_FINDNOTIFY_HANDLE_IN_USE: return (syserr_findnotify_handle_in_use);
+ case ERROR_FINDNOTIFY_HANDLE_CLOSED: return (syserr_findnotify_handle_closed);
+ case ERROR_NOTIFY_OBJECT_REMOVED: return (syserr_notify_object_removed);
+ case ERROR_ALREADY_SHUTDOWN: return (syserr_already_shutdown);
+ case ERROR_EAS_DIDNT_FIT: return (syserr_eas_didnt_fit);
+ case ERROR_EA_FILE_CORRUPT: return (syserr_ea_file_corrupt);
+ case ERROR_EA_TABLE_FULL: return (syserr_ea_table_full);
+ case ERROR_INVALID_EA_HANDLE: return (syserr_invalid_ea_handle);
+ case ERROR_NO_CLUSTER: return (syserr_no_cluster);
+ case ERROR_CREATE_EA_FILE: return (syserr_create_ea_file);
+ case ERROR_CANNOT_OPEN_EA_FILE: return (syserr_cannot_open_ea_file);
+ case ERROR_EAS_NOT_SUPPORTED: return (syserr_eas_not_supported);
+ case ERROR_NEED_EAS_FOUND: return (syserr_need_eas_found);
+ case ERROR_DUPLICATE_HANDLE: return (syserr_duplicate_handle);
+ case ERROR_DUPLICATE_NAME: return (syserr_duplicate_name);
+ case ERROR_EMPTY_MUXWAIT: return (syserr_empty_muxwait);
+ case ERROR_MUTEX_OWNED: return (syserr_mutex_owned);
+ case ERROR_NOT_OWNER: return (syserr_not_owner);
+ case ERROR_PARAM_TOO_SMALL: return (syserr_param_too_small);
+ case ERROR_TOO_MANY_HANDLES: return (syserr_too_many_handles);
+ case ERROR_TOO_MANY_OPENS: return (syserr_too_many_opens);
+ case ERROR_WRONG_TYPE: return (syserr_wrong_type);
+ case ERROR_UNUSED_CODE: return (syserr_unused_code);
+ case ERROR_THREAD_NOT_TERMINATED: return (syserr_thread_not_terminated);
+ case ERROR_INIT_ROUTINE_FAILED: return (syserr_init_routine_failed);
+ case ERROR_MODULE_IN_USE: return (syserr_module_in_use);
+ case ERROR_NOT_ENOUGH_WATCHPOINTS: return (syserr_not_enough_watchpoints);
+ case ERROR_TOO_MANY_POSTS: return (syserr_too_many_posts);
+ case ERROR_ALREADY_POSTED: return (syserr_already_posted);
+ case ERROR_ALREADY_RESET: return (syserr_already_reset);
+ case ERROR_SEM_BUSY: return (syserr_sem_busy);
+ case ERROR_INVALID_PROCID: return (syserr_invalid_procid);
+ case ERROR_INVALID_PDELTA: return (syserr_invalid_pdelta);
+ case ERROR_NOT_DESCENDANT: return (syserr_not_descendant);
+ case ERROR_NOT_SESSION_MANAGER: return (syserr_not_session_manager);
+ case ERROR_INVALID_PCLASS: return (syserr_invalid_pclass);
+ case ERROR_INVALID_SCOPE: return (syserr_invalid_scope);
+ case ERROR_INVALID_THREADID: return (syserr_invalid_threadid);
+ case ERROR_DOSSUB_SHRINK: return (syserr_dossub_shrink);
+ case ERROR_DOSSUB_NOMEM: return (syserr_dossub_nomem);
+ case ERROR_DOSSUB_OVERLAP: return (syserr_dossub_overlap);
+ case ERROR_DOSSUB_BADSIZE: return (syserr_dossub_badsize);
+ case ERROR_DOSSUB_BADFLAG: return (syserr_dossub_badflag);
+ case ERROR_DOSSUB_BADSELECTOR: return (syserr_dossub_badselector);
+ case ERROR_MR_MSG_TOO_LONG: return (syserr_mr_msg_too_long);
+ case ERROR_MR_MID_NOT_FOUND: return (syserr_mr_mid_not_found);
+ case ERROR_MR_UN_ACC_MSGF: return (syserr_mr_un_acc_msgf);
+ case ERROR_MR_INV_MSGF_FORMAT: return (syserr_mr_inv_msgf_format);
+ case ERROR_MR_INV_IVCOUNT: return (syserr_mr_inv_ivcount);
+ case ERROR_MR_UN_PERFORM: return (syserr_mr_un_perform);
+ case ERROR_TS_WAKEUP: return (syserr_ts_wakeup);
+ case ERROR_TS_SEMHANDLE: return (syserr_ts_semhandle);
+ case ERROR_TS_NOTIMER: return (syserr_ts_notimer);
+ case ERROR_TS_HANDLE: return (syserr_ts_handle);
+ case ERROR_TS_DATETIME: return (syserr_ts_datetime);
+ case ERROR_SYS_INTERNAL: return (syserr_sys_internal);
+ case ERROR_QUE_CURRENT_NAME: return (syserr_que_current_name);
+ case ERROR_QUE_PROC_NOT_OWNED: return (syserr_que_proc_not_owned);
+ case ERROR_QUE_PROC_OWNED: return (syserr_que_proc_owned);
+ case ERROR_QUE_DUPLICATE: return (syserr_que_duplicate);
+ case ERROR_QUE_ELEMENT_NOT_EXIST: return (syserr_que_element_not_exist);
+ case ERROR_QUE_NO_MEMORY: return (syserr_que_no_memory);
+ case ERROR_QUE_INVALID_NAME: return (syserr_que_invalid_name);
+ case ERROR_QUE_INVALID_PRIORITY: return (syserr_que_invalid_priority);
+ case ERROR_QUE_INVALID_HANDLE: return (syserr_que_invalid_handle);
+ case ERROR_QUE_LINK_NOT_FOUND: return (syserr_que_link_not_found);
+ case ERROR_QUE_MEMORY_ERROR: return (syserr_que_memory_error);
+ case ERROR_QUE_PREV_AT_END: return (syserr_que_prev_at_end);
+ case ERROR_QUE_PROC_NO_ACCESS: return (syserr_que_proc_no_access);
+ case ERROR_QUE_EMPTY: return (syserr_que_empty);
+ case ERROR_QUE_NAME_NOT_EXIST: return (syserr_que_name_not_exist);
+ case ERROR_QUE_NOT_INITIALIZED: return (syserr_que_not_initialized);
+ case ERROR_QUE_UNABLE_TO_ACCESS: return (syserr_que_unable_to_access);
+ case ERROR_QUE_UNABLE_TO_ADD: return (syserr_que_unable_to_add);
+ case ERROR_QUE_UNABLE_TO_INIT: return (syserr_que_unable_to_init);
+ case ERROR_VIO_INVALID_MASK: return (syserr_vio_invalid_mask);
+ case ERROR_VIO_PTR: return (syserr_vio_ptr);
+ case ERROR_VIO_APTR: return (syserr_vio_aptr);
+ case ERROR_VIO_RPTR: return (syserr_vio_rptr);
+ case ERROR_VIO_CPTR: return (syserr_vio_cptr);
+ case ERROR_VIO_LPTR: return (syserr_vio_lptr);
+ case ERROR_VIO_MODE: return (syserr_vio_mode);
+ case ERROR_VIO_WIDTH: return (syserr_vio_width);
+ case ERROR_VIO_ATTR: return (syserr_vio_attr);
+ case ERROR_VIO_ROW: return (syserr_vio_row);
+ case ERROR_VIO_COL: return (syserr_vio_col);
+ case ERROR_VIO_TOPROW: return (syserr_vio_toprow);
+ case ERROR_VIO_BOTROW: return (syserr_vio_botrow);
+ case ERROR_VIO_RIGHTCOL: return (syserr_vio_rightcol);
+ case ERROR_VIO_LEFTCOL: return (syserr_vio_leftcol);
+ case ERROR_SCS_CALL: return (syserr_scs_call);
+ case ERROR_SCS_VALUE: return (syserr_scs_value);
+ case ERROR_VIO_WAIT_FLAG: return (syserr_vio_wait_flag);
+ case ERROR_VIO_UNLOCK: return (syserr_vio_unlock);
+ case ERROR_SGS_NOT_SESSION_MGR: return (syserr_sgs_not_session_mgr);
+ case ERROR_SMG_INVALID_SESSION_ID: return (syserr_smg_invalid_session_id);
+ case ERROR_SMG_NO_SESSIONS: return (syserr_smg_no_sessions);
+ case ERROR_SMG_SESSION_NOT_FOUND: return (syserr_smg_session_not_found);
+ case ERROR_SMG_SET_TITLE: return (syserr_smg_set_title);
+ case ERROR_KBD_PARAMETER: return (syserr_kbd_parameter);
+ case ERROR_KBD_NO_DEVICE: return (syserr_kbd_no_device);
+ case ERROR_KBD_INVALID_IOWAIT: return (syserr_kbd_invalid_iowait);
+ case ERROR_KBD_INVALID_LENGTH: return (syserr_kbd_invalid_length);
+ case ERROR_KBD_INVALID_ECHO_MASK: return (syserr_kbd_invalid_echo_mask);
+ case ERROR_KBD_INVALID_INPUT_MASK: return (syserr_kbd_invalid_input_mask);
+ case ERROR_MON_INVALID_PARMS: return (syserr_mon_invalid_parms);
+ case ERROR_MON_INVALID_DEVNAME: return (syserr_mon_invalid_devname);
+ case ERROR_MON_INVALID_HANDLE: return (syserr_mon_invalid_handle);
+ case ERROR_MON_BUFFER_TOO_SMALL: return (syserr_mon_buffer_too_small);
+ case ERROR_MON_BUFFER_EMPTY: return (syserr_mon_buffer_empty);
+ case ERROR_MON_DATA_TOO_LARGE: return (syserr_mon_data_too_large);
+ case ERROR_MOUSE_NO_DEVICE: return (syserr_mouse_no_device);
+ case ERROR_MOUSE_INV_HANDLE: return (syserr_mouse_inv_handle);
+ case ERROR_MOUSE_INV_PARMS: return (syserr_mouse_inv_parms);
+ case ERROR_MOUSE_CANT_RESET: return (syserr_mouse_cant_reset);
+ case ERROR_MOUSE_DISPLAY_PARMS: return (syserr_mouse_display_parms);
+ case ERROR_MOUSE_INV_MODULE: return (syserr_mouse_inv_module);
+ case ERROR_MOUSE_INV_ENTRY_PT: return (syserr_mouse_inv_entry_pt);
+ case ERROR_MOUSE_INV_MASK: return (syserr_mouse_inv_mask);
+ case NO_ERROR_MOUSE_NO_DATA: return (syserr_mouse_no_data);
+ case NO_ERROR_MOUSE_PTR_DRAWN: return (syserr_mouse_ptr_drawn);
+ case ERROR_INVALID_FREQUENCY: return (syserr_invalid_frequency);
+ case ERROR_NLS_NO_COUNTRY_FILE: return (syserr_nls_no_country_file);
+ case ERROR_NLS_OPEN_FAILED: return (syserr_nls_open_failed);
+ case ERROR_NO_COUNTRY_OR_CODEPAGE: return (syserr_no_country_or_codepage);
+ case ERROR_NLS_TABLE_TRUNCATED: return (syserr_nls_table_truncated);
+ case ERROR_NLS_BAD_TYPE: return (syserr_nls_bad_type);
+ case ERROR_NLS_TYPE_NOT_FOUND: return (syserr_nls_type_not_found);
+ case ERROR_VIO_SMG_ONLY: return (syserr_vio_smg_only);
+ case ERROR_VIO_INVALID_ASCIIZ: return (syserr_vio_invalid_asciiz);
+ case ERROR_VIO_DEREGISTER: return (syserr_vio_deregister);
+ case ERROR_VIO_NO_POPUP: return (syserr_vio_no_popup);
+ case ERROR_VIO_EXISTING_POPUP: return (syserr_vio_existing_popup);
+ case ERROR_KBD_SMG_ONLY: return (syserr_kbd_smg_only);
+ case ERROR_KBD_INVALID_ASCIIZ: return (syserr_kbd_invalid_asciiz);
+ case ERROR_KBD_INVALID_MASK: return (syserr_kbd_invalid_mask);
+ case ERROR_KBD_REGISTER: return (syserr_kbd_register);
+ case ERROR_KBD_DEREGISTER: return (syserr_kbd_deregister);
+ case ERROR_MOUSE_SMG_ONLY: return (syserr_mouse_smg_only);
+ case ERROR_MOUSE_INVALID_ASCIIZ: return (syserr_mouse_invalid_asciiz);
+ case ERROR_MOUSE_INVALID_MASK: return (syserr_mouse_invalid_mask);
+ case ERROR_MOUSE_REGISTER: return (syserr_mouse_register);
+ case ERROR_MOUSE_DEREGISTER: return (syserr_mouse_deregister);
+ case ERROR_SMG_BAD_ACTION: return (syserr_smg_bad_action);
+ case ERROR_SMG_INVALID_CALL: return (syserr_smg_invalid_call);
+ case ERROR_SCS_SG_NOTFOUND: return (syserr_scs_sg_notfound);
+ case ERROR_SCS_NOT_SHELL: return (syserr_scs_not_shell);
+ case ERROR_VIO_INVALID_PARMS: return (syserr_vio_invalid_parms);
+ case ERROR_VIO_FUNCTION_OWNED: return (syserr_vio_function_owned);
+ case ERROR_VIO_RETURN: return (syserr_vio_return);
+ case ERROR_SCS_INVALID_FUNCTION: return (syserr_scs_invalid_function);
+ case ERROR_SCS_NOT_SESSION_MGR: return (syserr_scs_not_session_mgr);
+ case ERROR_VIO_REGISTER: return (syserr_vio_register);
+ case ERROR_VIO_NO_MODE_THREAD: return (syserr_vio_no_mode_thread);
+ case ERROR_VIO_NO_SAVE_RESTORE_THD: return (syserr_vio_no_save_restore_thd);
+ case ERROR_VIO_IN_BG: return (syserr_vio_in_bg);
+ case ERROR_VIO_ILLEGAL_DURING_POPUP: return (syserr_vio_illegal_during_popup);
+ case ERROR_SMG_NOT_BASESHELL: return (syserr_smg_not_baseshell);
+ case ERROR_SMG_BAD_STATUSREQ: return (syserr_smg_bad_statusreq);
+ case ERROR_QUE_INVALID_WAIT: return (syserr_que_invalid_wait);
+ case ERROR_VIO_LOCK: return (syserr_vio_lock);
+ case ERROR_MOUSE_INVALID_IOWAIT: return (syserr_mouse_invalid_iowait);
+ case ERROR_VIO_INVALID_HANDLE: return (syserr_vio_invalid_handle);
+ case ERROR_VIO_ILLEGAL_DURING_LOCK: return (syserr_vio_illegal_during_lock);
+ case ERROR_VIO_INVALID_LENGTH: return (syserr_vio_invalid_length);
+ case ERROR_KBD_INVALID_HANDLE: return (syserr_kbd_invalid_handle);
+ case ERROR_KBD_NO_MORE_HANDLE: return (syserr_kbd_no_more_handle);
+ case ERROR_KBD_CANNOT_CREATE_KCB: return (syserr_kbd_cannot_create_kcb);
+ case ERROR_KBD_CODEPAGE_LOAD_INCOMPL: return (syserr_kbd_codepage_load_incompl);
+ case ERROR_KBD_INVALID_CODEPAGE_ID: return (syserr_kbd_invalid_codepage_id);
+ case ERROR_KBD_NO_CODEPAGE_SUPPORT: return (syserr_kbd_no_codepage_support);
+ case ERROR_KBD_FOCUS_REQUIRED: return (syserr_kbd_focus_required);
+ case ERROR_KBD_FOCUS_ALREADY_ACTIVE: return (syserr_kbd_focus_already_active);
+ case ERROR_KBD_KEYBOARD_BUSY: return (syserr_kbd_keyboard_busy);
+ case ERROR_KBD_INVALID_CODEPAGE: return (syserr_kbd_invalid_codepage);
+ case ERROR_KBD_UNABLE_TO_FOCUS: return (syserr_kbd_unable_to_focus);
+ case ERROR_SMG_SESSION_NON_SELECT: return (syserr_smg_session_non_select);
+ case ERROR_SMG_SESSION_NOT_FOREGRND: return (syserr_smg_session_not_foregrnd);
+ case ERROR_SMG_SESSION_NOT_PARENT: return (syserr_smg_session_not_parent);
+ case ERROR_SMG_INVALID_START_MODE: return (syserr_smg_invalid_start_mode);
+ case ERROR_SMG_INVALID_RELATED_OPT: return (syserr_smg_invalid_related_opt);
+ case ERROR_SMG_INVALID_BOND_OPTION: return (syserr_smg_invalid_bond_option);
+ case ERROR_SMG_INVALID_SELECT_OPT: return (syserr_smg_invalid_select_opt);
+ case ERROR_SMG_START_IN_BACKGROUND: return (syserr_smg_start_in_background);
+ case ERROR_SMG_INVALID_STOP_OPTION: return (syserr_smg_invalid_stop_option);
+ case ERROR_SMG_BAD_RESERVE: return (syserr_smg_bad_reserve);
+ case ERROR_SMG_PROCESS_NOT_PARENT: return (syserr_smg_process_not_parent);
+ case ERROR_SMG_INVALID_DATA_LENGTH: return (syserr_smg_invalid_data_length);
+ case ERROR_SMG_NOT_BOUND: return (syserr_smg_not_bound);
+ case ERROR_SMG_RETRY_SUB_ALLOC: return (syserr_smg_retry_sub_alloc);
+ case ERROR_KBD_DETACHED: return (syserr_kbd_detached);
+ case ERROR_VIO_DETACHED: return (syserr_vio_detached);
+ case ERROR_MOU_DETACHED: return (syserr_mou_detached);
+ case ERROR_VIO_FONT: return (syserr_vio_font);
+ case ERROR_VIO_USER_FONT: return (syserr_vio_user_font);
+ case ERROR_VIO_BAD_CP: return (syserr_vio_bad_cp);
+ case ERROR_VIO_NO_CP: return (syserr_vio_no_cp);
+ case ERROR_VIO_NA_CP: return (syserr_vio_na_cp);
+ case ERROR_INVALID_CODE_PAGE: return (syserr_invalid_code_page);
+ case ERROR_CPLIST_TOO_SMALL: return (syserr_cplist_too_small);
+ case ERROR_CP_NOT_MOVED: return (syserr_cp_not_moved);
+ case ERROR_MODE_SWITCH_INIT: return (syserr_mode_switch_init);
+ case ERROR_CODE_PAGE_NOT_FOUND: return (syserr_code_page_not_found);
+ case ERROR_UNEXPECTED_SLOT_RETURNED: return (syserr_unexpected_slot_returned);
+ case ERROR_SMG_INVALID_TRACE_OPTION: return (syserr_smg_invalid_trace_option);
+ case ERROR_VIO_INTERNAL_RESOURCE: return (syserr_vio_internal_resource);
+ case ERROR_VIO_SHELL_INIT: return (syserr_vio_shell_init);
+ case ERROR_SMG_NO_HARD_ERRORS: return (syserr_smg_no_hard_errors);
+ case ERROR_CP_SWITCH_INCOMPLETE: return (syserr_cp_switch_incomplete);
+ case ERROR_VIO_TRANSPARENT_POPUP: return (syserr_vio_transparent_popup);
+ case ERROR_CRITSEC_OVERFLOW: return (syserr_critsec_overflow);
+ case ERROR_CRITSEC_UNDERFLOW: return (syserr_critsec_underflow);
+ case ERROR_VIO_BAD_RESERVE: return (syserr_vio_bad_reserve);
+ case ERROR_INVALID_ADDRESS: return (syserr_invalid_address);
+ case ERROR_ZERO_SELECTORS_REQUESTED: return (syserr_zero_selectors_requested);
+ case ERROR_NOT_ENOUGH_SELECTORS_AVA: return (syserr_not_enough_selectors_ava);
+ case ERROR_INVALID_SELECTOR: return (syserr_invalid_selector);
+ case ERROR_SMG_INVALID_PROGRAM_TYPE: return (syserr_smg_invalid_program_type);
+ case ERROR_SMG_INVALID_PGM_CONTROL: return (syserr_smg_invalid_pgm_control);
+ case ERROR_SMG_INVALID_INHERIT_OPT: return (syserr_smg_invalid_inherit_opt);
+ case ERROR_VIO_EXTENDED_SG: return (syserr_vio_extended_sg);
+ case ERROR_VIO_NOT_PRES_MGR_SG: return (syserr_vio_not_pres_mgr_sg);
+ case ERROR_VIO_SHIELD_OWNED: return (syserr_vio_shield_owned);
+ case ERROR_VIO_NO_MORE_HANDLES: return (syserr_vio_no_more_handles);
+ case ERROR_VIO_SEE_ERROR_LOG: return (syserr_vio_see_error_log);
+ case ERROR_VIO_ASSOCIATED_DC: return (syserr_vio_associated_dc);
+ case ERROR_KBD_NO_CONSOLE: return (syserr_kbd_no_console);
+ case ERROR_MOUSE_NO_CONSOLE: return (syserr_mouse_no_console);
+ case ERROR_MOUSE_INVALID_HANDLE: return (syserr_mouse_invalid_handle);
+ case ERROR_SMG_INVALID_DEBUG_PARMS: return (syserr_smg_invalid_debug_parms);
+ case ERROR_KBD_EXTENDED_SG: return (syserr_kbd_extended_sg);
+ case ERROR_MOU_EXTENDED_SG: return (syserr_mou_extended_sg);
+ case ERROR_SMG_INVALID_ICON_FILE: return (syserr_smg_invalid_icon_file);
+ case ERROR_TRC_PID_NON_EXISTENT: return (syserr_trc_pid_non_existent);
+ case ERROR_TRC_COUNT_ACTIVE: return (syserr_trc_count_active);
+ case ERROR_TRC_SUSPENDED_BY_COUNT: return (syserr_trc_suspended_by_count);
+ case ERROR_TRC_COUNT_INACTIVE: return (syserr_trc_count_inactive);
+ case ERROR_TRC_COUNT_REACHED: return (syserr_trc_count_reached);
+ case ERROR_NO_MC_TRACE: return (syserr_no_mc_trace);
+ case ERROR_MC_TRACE: return (syserr_mc_trace);
+ case ERROR_TRC_COUNT_ZERO: return (syserr_trc_count_zero);
+ case ERROR_SMG_TOO_MANY_DDS: return (syserr_smg_too_many_dds);
+ case ERROR_SMG_INVALID_NOTIFICATION: return (syserr_smg_invalid_notification);
+ case ERROR_LF_INVALID_FUNCTION: return (syserr_lf_invalid_function);
+ case ERROR_LF_NOT_AVAIL: return (syserr_lf_not_avail);
+ case ERROR_LF_SUSPENDED: return (syserr_lf_suspended);
+ case ERROR_LF_BUF_TOO_SMALL: return (syserr_lf_buf_too_small);
+ case ERROR_LF_BUFFER_FULL: return (syserr_lf_buffer_full);
+ case ERROR_LF_INVALID_RECORD: return (syserr_lf_invalid_record);
+ case ERROR_LF_INVALID_SERVICE: return (syserr_lf_invalid_service);
+ case ERROR_LF_GENERAL_FAILURE: return (syserr_lf_general_failure);
+ case ERROR_LF_INVALID_ID: return (syserr_lf_invalid_id);
+ case ERROR_LF_INVALID_HANDLE: return (syserr_lf_invalid_handle);
+ case ERROR_LF_NO_ID_AVAIL: return (syserr_lf_no_id_avail);
+ case ERROR_LF_TEMPLATE_AREA_FULL: return (syserr_lf_template_area_full);
+ case ERROR_LF_ID_IN_USE: return (syserr_lf_id_in_use);
+ case ERROR_MOU_NOT_INITIALIZED: return (syserr_mou_not_initialized);
+ case ERROR_MOUINITREAL_DONE: return (syserr_mouinitreal_done);
+ case ERROR_DOSSUB_CORRUPTED: return (syserr_dossub_corrupted);
+ case ERROR_MOUSE_CALLER_NOT_SUBSYS: return (syserr_mouse_caller_not_subsys);
+ case ERROR_ARITHMETIC_OVERFLOW: return (syserr_arithmetic_overflow);
+ case ERROR_TMR_NO_DEVICE: return (syserr_tmr_no_device);
+ case ERROR_TMR_INVALID_TIME: return (syserr_tmr_invalid_time);
+ case ERROR_PVW_INVALID_ENTITY: return (syserr_pvw_invalid_entity);
+ case ERROR_PVW_INVALID_ENTITY_TYPE: return (syserr_pvw_invalid_entity_type);
+ case ERROR_PVW_INVALID_SPEC: return (syserr_pvw_invalid_spec);
+ case ERROR_PVW_INVALID_RANGE_TYPE: return (syserr_pvw_invalid_range_type);
+ case ERROR_PVW_INVALID_COUNTER_BLK: return (syserr_pvw_invalid_counter_blk);
+ case ERROR_PVW_INVALID_TEXT_BLK: return (syserr_pvw_invalid_text_blk);
+ case ERROR_PRF_NOT_INITIALIZED: return (syserr_prf_not_initialized);
+ case ERROR_PRF_ALREADY_INITIALIZED: return (syserr_prf_already_initialized);
+ case ERROR_PRF_NOT_STARTED: return (syserr_prf_not_started);
+ case ERROR_PRF_ALREADY_STARTED: return (syserr_prf_already_started);
+ case ERROR_PRF_TIMER_OUT_OF_RANGE: return (syserr_prf_timer_out_of_range);
+ case ERROR_PRF_TIMER_RESET: return (syserr_prf_timer_reset);
+ case ERROR_VDD_LOCK_USEAGE_DENIED: return (syserr_vdd_lock_useage_denied);
+ case ERROR_TIMEOUT: return (syserr_timeout);
+ case ERROR_VDM_DOWN: return (syserr_vdm_down);
+ case ERROR_VDM_LIMIT: return (syserr_vdm_limit);
+ case ERROR_VDD_NOT_FOUND: return (syserr_vdd_not_found);
+ case ERROR_INVALID_CALLER: return (syserr_invalid_caller);
+ case ERROR_PID_MISMATCH: return (syserr_pid_mismatch);
+ case ERROR_INVALID_VDD_HANDLE: return (syserr_invalid_vdd_handle);
+ case ERROR_VLPT_NO_SPOOLER: return (syserr_vlpt_no_spooler);
+ case ERROR_VCOM_DEVICE_BUSY: return (syserr_vcom_device_busy);
+ case ERROR_VLPT_DEVICE_BUSY: return (syserr_vlpt_device_busy);
+ case ERROR_NESTING_TOO_DEEP: return (syserr_nesting_too_deep);
+ case ERROR_VDD_MISSING: return (syserr_vdd_missing);
+ case ERROR_BIDI_INVALID_LENGTH: return (syserr_bidi_invalid_length);
+ case ERROR_BIDI_INVALID_INCREMENT: return (syserr_bidi_invalid_increment);
+ case ERROR_BIDI_INVALID_COMBINATION: return (syserr_bidi_invalid_combination);
+ case ERROR_BIDI_INVALID_RESERVED: return (syserr_bidi_invalid_reserved);
+ case ERROR_BIDI_INVALID_EFFECT: return (syserr_bidi_invalid_effect);
+ case ERROR_BIDI_INVALID_CSDREC: return (syserr_bidi_invalid_csdrec);
+ case ERROR_BIDI_INVALID_CSDSTATE: return (syserr_bidi_invalid_csdstate);
+ case ERROR_BIDI_INVALID_LEVEL: return (syserr_bidi_invalid_level);
+ case ERROR_BIDI_INVALID_TYPE_SUPPORT: return (syserr_bidi_invalid_type_support);
+ case ERROR_BIDI_INVALID_ORIENTATION: return (syserr_bidi_invalid_orientation);
+ case ERROR_BIDI_INVALID_NUM_SHAPE: return (syserr_bidi_invalid_num_shape);
+ case ERROR_BIDI_INVALID_CSD: return (syserr_bidi_invalid_csd);
+ case ERROR_BIDI_NO_SUPPORT: return (syserr_bidi_no_support);
+ case NO_ERROR_BIDI_RW_INCOMPLETE: return (syserr_bidi_rw_incomplete);
+ case ERROR_IMP_INVALID_PARM: return (syserr_imp_invalid_parm);
+ case ERROR_IMP_INVALID_LENGTH: return (syserr_imp_invalid_length);
+ case MSG_HPFS_DISK_ERROR_WARN: return (syserr_hpfs_disk_error_warn);
+ case ERROR_MON_BAD_BUFFER: return (syserr_mon_bad_buffer);
+ case ERROR_MODULE_CORRUPTED: return (syserr_module_corrupted);
+ case ERROR_SM_OUTOF_SWAPFILE: return (syserr_sm_outof_swapfile);
+ case ERROR_LF_TIMEOUT: return (syserr_lf_timeout);
+ case ERROR_LF_SUSPEND_SUCCESS: return (syserr_lf_suspend_success);
+ case ERROR_LF_RESUME_SUCCESS: return (syserr_lf_resume_success);
+ case ERROR_LF_REDIRECT_SUCCESS: return (syserr_lf_redirect_success);
+ case ERROR_LF_REDIRECT_FAILURE: return (syserr_lf_redirect_failure);
+ case ERROR_SWAPPER_NOT_ACTIVE: return (syserr_swapper_not_active);
+ case ERROR_INVALID_SWAPID: return (syserr_invalid_swapid);
+ case ERROR_IOERR_SWAP_FILE: return (syserr_ioerr_swap_file);
+ case ERROR_SWAP_TABLE_FULL: return (syserr_swap_table_full);
+ case ERROR_SWAP_FILE_FULL: return (syserr_swap_file_full);
+ case ERROR_CANT_INIT_SWAPPER: return (syserr_cant_init_swapper);
+ case ERROR_SWAPPER_ALREADY_INIT: return (syserr_swapper_already_init);
+ case ERROR_PMM_INSUFFICIENT_MEMORY: return (syserr_pmm_insufficient_memory);
+ case ERROR_PMM_INVALID_FLAGS: return (syserr_pmm_invalid_flags);
+ case ERROR_PMM_INVALID_ADDRESS: return (syserr_pmm_invalid_address);
+ case ERROR_PMM_LOCK_FAILED: return (syserr_pmm_lock_failed);
+ case ERROR_PMM_UNLOCK_FAILED: return (syserr_pmm_unlock_failed);
+ case ERROR_PMM_MOVE_INCOMPLETE: return (syserr_pmm_move_incomplete);
+ case ERROR_UCOM_DRIVE_RENAMED: return (syserr_ucom_drive_renamed);
+ case ERROR_UCOM_FILENAME_TRUNCATED: return (syserr_ucom_filename_truncated);
+ case ERROR_UCOM_BUFFER_LENGTH: return (syserr_ucom_buffer_length);
+ case ERROR_MON_CHAIN_HANDLE: return (syserr_mon_chain_handle);
+ case ERROR_MON_NOT_REGISTERED: return (syserr_mon_not_registered);
+ case ERROR_SMG_ALREADY_TOP: return (syserr_smg_already_top);
+ case ERROR_PMM_ARENA_MODIFIED: return (syserr_pmm_arena_modified);
+ case ERROR_SMG_PRINTER_OPEN: return (syserr_smg_printer_open);
+ case ERROR_PMM_SET_FLAGS_FAILED: return (syserr_pmm_set_flags_failed);
+ case ERROR_INVALID_DOS_DD: return (syserr_invalid_dos_dd);
+ case ERROR_BLOCKED: return (syserr_blocked);
+ case ERROR_NOBLOCK: return (syserr_noblock);
+ case ERROR_INSTANCE_SHARED: return (syserr_instance_shared);
+ case ERROR_NO_OBJECT: return (syserr_no_object);
+ case ERROR_PARTIAL_ATTACH: return (syserr_partial_attach);
+ case ERROR_INCACHE: return (syserr_incache);
+ case ERROR_SWAP_IO_PROBLEMS: return (syserr_swap_io_problems);
+ case ERROR_CROSSES_OBJECT_BOUNDARY: return (syserr_crosses_object_boundary);
+ case ERROR_LONGLOCK: return (syserr_longlock);
+ case ERROR_SHORTLOCK: return (syserr_shortlock);
+ case ERROR_UVIRTLOCK: return (syserr_uvirtlock);
+ case ERROR_ALIASLOCK: return (syserr_aliaslock);
+ case ERROR_ALIAS: return (syserr_alias);
+ case ERROR_NO_MORE_HANDLES: return (syserr_no_more_handles);
+ case ERROR_SCAN_TERMINATED: return (syserr_scan_terminated);
+ case ERROR_TERMINATOR_NOT_FOUND: return (syserr_terminator_not_found);
+ case ERROR_NOT_DIRECT_CHILD: return (syserr_not_direct_child);
+ case ERROR_DELAY_FREE: return (syserr_delay_free);
+ case ERROR_GUARDPAGE: return (syserr_guardpage);
+ case ERROR_SWAPERROR: return (syserr_swaperror);
+ case ERROR_LDRERROR: return (syserr_ldrerror);
+ case ERROR_NOMEMORY: return (syserr_nomemory);
+ case ERROR_NOACCESS: return (syserr_noaccess);
+ case ERROR_NO_DLL_TERM: return (syserr_no_dll_term);
+ case ERROR_CPSIO_CODE_PAGE_INVALID: return (syserr_cpsio_code_page_invalid);
+ case ERROR_CPSIO_NO_SPOOLER: return (syserr_cpsio_no_spooler);
+ case ERROR_CPSIO_FONT_ID_INVALID: return (syserr_cpsio_font_id_invalid);
+ case ERROR_CPSIO_INTERNAL_ERROR: return (syserr_cpsio_internal_error);
+ case ERROR_CPSIO_INVALID_PTR_NAME: return (syserr_cpsio_invalid_ptr_name);
+ case ERROR_CPSIO_NOT_ACTIVE: return (syserr_cpsio_not_active);
+ case ERROR_CPSIO_PID_FULL: return (syserr_cpsio_pid_full);
+ case ERROR_CPSIO_PID_NOT_FOUND: return (syserr_cpsio_pid_not_found);
+ case ERROR_CPSIO_READ_CTL_SEQ: return (syserr_cpsio_read_ctl_seq);
+ case ERROR_CPSIO_READ_FNT_DEF: return (syserr_cpsio_read_fnt_def);
+ case ERROR_CPSIO_WRITE_ERROR: return (syserr_cpsio_write_error);
+ case ERROR_CPSIO_WRITE_FULL_ERROR: return (syserr_cpsio_write_full_error);
+ case ERROR_CPSIO_WRITE_HANDLE_BAD: return (syserr_cpsio_write_handle_bad);
+ case ERROR_CPSIO_SWIT_LOAD: return (syserr_cpsio_swit_load);
+ case ERROR_CPSIO_INV_COMMAND: return (syserr_cpsio_inv_command);
+ case ERROR_CPSIO_NO_FONT_SWIT: return (syserr_cpsio_no_font_swit);
+ case ERROR_ENTRY_IS_CALLGATE: return (syserr_entry_is_callgate);
+ default: return (syserr_unknown);
+ }
+}
+\f
+#ifdef __GCC2__
+/* Grumble... stupid linking bug. */
+#define dos_error_message(rc) 0
+#else /* not __GCC2__ */
+
+static const char *
+dos_error_message (APIRET rc)
+{
+ unsigned int blength_increment = 64;
+ unsigned int blength = blength_increment;
+ char * buffer = (malloc (blength));
+ ULONG mlength;
+
+ if (buffer == 0)
+ return (0);
+ while (1)
+ {
+ if ((dos_get_message
+ (0, 0, buffer, blength, rc, "OSO001.MSG", (&mlength)))
+ != NO_ERROR)
+ {
+ free (buffer);
+ return (0);
+ }
+ if (mlength < blength)
+ {
+ while ((mlength > 0) && (isspace (buffer [mlength - 1])))
+ mlength -= 1;
+ buffer = (realloc (buffer, (mlength + 1)));
+ if (buffer != 0)
+ (buffer[mlength]) = '\0';
+ return (buffer);
+ }
+ blength += blength_increment;
+ buffer = (realloc (buffer, (blength)));
+ if (buffer == 0)
+ return (0);
+ }
+}
+
+#endif /* not __GCC2__ */
+
+const char *
+OS_error_code_to_message (unsigned int syserr)
+{
+ static const char * last_message = 0;
+ if (last_message != 0)
+ free ((void *) last_message);
+ last_message = (dos_error_message (syserr));
+ return (last_message);
+}
+\f
+static char * syscall_names_table [] =
+{
+ "dos-async-timer",
+ "dos-close",
+ "dos-close-event-sem",
+ "dos-close-mutex-sem",
+ "dos-close-queue",
+ "dos-create-dir",
+ "dos-create-event-sem",
+ "dos-create-mutex-sem",
+ "dos-create-pipe",
+ "dos-create-queue",
+ "dos-create-thread",
+ "dos-delete",
+ "dos-delete-dir",
+ "dos-exit",
+ "dos-find-close",
+ "dos-find-first",
+ "dos-find-next",
+ "dos-get-info-blocks",
+ "dos-get-message",
+ "dos-kill-thread",
+ "dos-move",
+ "dos-open",
+ "dos-post-event-sem",
+ "dos-query-current-dir",
+ "dos-query-current-disk",
+ "dos-query-file-info",
+ "dos-query-h-type",
+ "dos-query-n-p-h-state",
+ "dos-query-path-info",
+ "dos-query-sys-info",
+ "dos-read",
+ "dos-read-queue",
+ "dos-release-mutex-sem",
+ "dos-request-mutex-sem",
+ "dos-reset-event-sem",
+ "dos-scan-env",
+ "dos-set-current-dir",
+ "dos-set-default-disk",
+ "dos-set-file-ptr",
+ "dos-set-file-size",
+ "dos-set-path-info",
+ "dos-start-timer",
+ "dos-stop-timer",
+ "dos-wait-event-sem",
+ "dos-write",
+ "dos-write-queue",
+ "beginthread",
+ "kbd-char-in",
+ "localtime",
+ "malloc",
+ "mktime",
+ "realloc",
+ "time",
+ "vio-wrt-tty"
+};
+
+void
+OS_syscall_names (unsigned int * length, unsigned char *** names)
+{
+ (*length) = ((sizeof (syscall_names_table)) / (sizeof (char *)));
+ (*names) = ((unsigned char **) syscall_names_table);
+}
+\f
+/* Machine-generated table, do not edit: */
+static char * syserr_names_table [] =
+{
+ "INVALID-FUNCTION",
+ "FILE-NOT-FOUND",
+ "PATH-NOT-FOUND",
+ "TOO-MANY-OPEN-FILES",
+ "ACCESS-DENIED",
+ "INVALID-HANDLE",
+ "ARENA-TRASHED",
+ "NOT-ENOUGH-MEMORY",
+ "INVALID-BLOCK",
+ "BAD-ENVIRONMENT",
+ "BAD-FORMAT",
+ "INVALID-ACCESS",
+ "INVALID-DATA",
+ "INVALID-DRIVE",
+ "CURRENT-DIRECTORY",
+ "NOT-SAME-DEVICE",
+ "NO-MORE-FILES",
+ "WRITE-PROTECT",
+ "BAD-UNIT",
+ "NOT-READY",
+ "BAD-COMMAND",
+ "CRC",
+ "BAD-LENGTH",
+ "SEEK",
+ "NOT-DOS-DISK",
+ "SECTOR-NOT-FOUND",
+ "OUT-OF-PAPER",
+ "WRITE-FAULT",
+ "READ-FAULT",
+ "GEN-FAILURE",
+ "SHARING-VIOLATION",
+ "LOCK-VIOLATION",
+ "WRONG-DISK",
+ "FCB-UNAVAILABLE",
+ "SHARING-BUFFER-EXCEEDED",
+ "CODE-PAGE-MISMATCHED",
+ "HANDLE-EOF",
+ "HANDLE-DISK-FULL",
+ "NOT-SUPPORTED",
+ "REM-NOT-LIST",
+ "DUP-NAME",
+ "BAD-NETPATH",
+ "NETWORK-BUSY",
+ "DEV-NOT-EXIST",
+ "TOO-MANY-CMDS",
+ "ADAP-HDW-ERR",
+ "BAD-NET-RESP",
+ "UNEXP-NET-ERR",
+ "BAD-REM-ADAP",
+ "PRINTQ-FULL",
+ "NO-SPOOL-SPACE",
+ "PRINT-CANCELLED",
+ "NETNAME-DELETED",
+ "NETWORK-ACCESS-DENIED",
+ "BAD-DEV-TYPE",
+ "BAD-NET-NAME",
+ "TOO-MANY-NAMES",
+ "TOO-MANY-SESS",
+ "SHARING-PAUSED",
+ "REQ-NOT-ACCEP",
+ "REDIR-PAUSED",
+ "SBCS-ATT-WRITE-PROT",
+ "SBCS-GENERAL-FAILURE",
+ "XGA-OUT-MEMORY",
+ "FILE-EXISTS",
+ "DUP-FCB",
+ "CANNOT-MAKE",
+ "FAIL-I24",
+ "OUT-OF-STRUCTURES",
+ "ALREADY-ASSIGNED",
+ "INVALID-PASSWORD",
+ "INVALID-PARAMETER",
+ "NET-WRITE-FAULT",
+ "NO-PROC-SLOTS",
+ "NOT-FROZEN",
+ "SYS-COMP-NOT-LOADED",
+ "TSTOVFL",
+ "TSTDUP",
+ "NO-ITEMS",
+ "INTERRUPT",
+ "DEVICE-IN-USE",
+ "TOO-MANY-SEMAPHORES",
+ "EXCL-SEM-ALREADY-OWNED",
+ "SEM-IS-SET",
+ "TOO-MANY-SEM-REQUESTS",
+ "INVALID-AT-INTERRUPT-TIME",
+ "SEM-OWNER-DIED",
+ "SEM-USER-LIMIT",
+ "DISK-CHANGE",
+ "DRIVE-LOCKED",
+ "BROKEN-PIPE",
+ "OPEN-FAILED",
+ "BUFFER-OVERFLOW",
+ "DISK-FULL",
+ "NO-MORE-SEARCH-HANDLES",
+ "INVALID-TARGET-HANDLE",
+ "PROTECTION-VIOLATION",
+ "VIOKBD-REQUEST",
+ "INVALID-CATEGORY",
+ "INVALID-VERIFY-SWITCH",
+ "BAD-DRIVER-LEVEL",
+ "CALL-NOT-IMPLEMENTED",
+ "SEM-TIMEOUT",
+ "INSUFFICIENT-BUFFER",
+ "INVALID-NAME",
+ "INVALID-LEVEL",
+ "NO-VOLUME-LABEL",
+ "MOD-NOT-FOUND",
+ "PROC-NOT-FOUND",
+ "WAIT-NO-CHILDREN",
+ "CHILD-NOT-COMPLETE",
+ "DIRECT-ACCESS-HANDLE",
+ "NEGATIVE-SEEK",
+ "SEEK-ON-DEVICE",
+ "IS-JOIN-TARGET",
+ "IS-JOINED",
+ "IS-SUBSTED",
+ "NOT-JOINED",
+ "NOT-SUBSTED",
+ "JOIN-TO-JOIN",
+ "SUBST-TO-SUBST",
+ "JOIN-TO-SUBST",
+ "SUBST-TO-JOIN",
+ "BUSY-DRIVE",
+ "SAME-DRIVE",
+ "DIR-NOT-ROOT",
+ "DIR-NOT-EMPTY",
+ "IS-SUBST-PATH",
+ "IS-JOIN-PATH",
+ "PATH-BUSY",
+ "IS-SUBST-TARGET",
+ "SYSTEM-TRACE",
+ "INVALID-EVENT-COUNT",
+ "TOO-MANY-MUXWAITERS",
+ "INVALID-LIST-FORMAT",
+ "LABEL-TOO-LONG",
+ "TOO-MANY-TCBS",
+ "SIGNAL-REFUSED",
+ "DISCARDED",
+ "NOT-LOCKED",
+ "BAD-THREADID-ADDR",
+ "BAD-ARGUMENTS",
+ "BAD-PATHNAME",
+ "SIGNAL-PENDING",
+ "UNCERTAIN-MEDIA",
+ "MAX-THRDS-REACHED",
+ "MONITORS-NOT-SUPPORTED",
+ "UNC-DRIVER-NOT-INSTALLED",
+ "LOCK-FAILED",
+ "SWAPIO-FAILED",
+ "SWAPIN-FAILED",
+ "BUSY",
+ "CANCEL-VIOLATION",
+ "ATOMIC-LOCK-NOT-SUPPORTED",
+ "READ-LOCKS-NOT-SUPPORTED",
+ "INVALID-SEGMENT-NUMBER",
+ "INVALID-CALLGATE",
+ "INVALID-ORDINAL",
+ "ALREADY-EXISTS",
+ "NO-CHILD-PROCESS",
+ "CHILD-ALIVE-NOWAIT",
+ "INVALID-FLAG-NUMBER",
+ "SEM-NOT-FOUND",
+ "INVALID-STARTING-CODESEG",
+ "INVALID-STACKSEG",
+ "INVALID-MODULETYPE",
+ "INVALID-EXE-SIGNATURE",
+ "EXE-MARKED-INVALID",
+ "BAD-EXE-FORMAT",
+ "ITERATED-DATA-EXCEEDS-64K",
+ "INVALID-MINALLOCSIZE",
+ "DYNLINK-FROM-INVALID-RING",
+ "IOPL-NOT-ENABLED",
+ "INVALID-SEGDPL",
+ "AUTODATASEG-EXCEEDS-64K",
+ "RING2SEG-MUST-BE-MOVABLE",
+ "RELOC-CHAIN-XEEDS-SEGLIM",
+ "INFLOOP-IN-RELOC-CHAIN",
+ "ENVVAR-NOT-FOUND",
+ "NOT-CURRENT-CTRY",
+ "NO-SIGNAL-SENT",
+ "FILENAME-EXCED-RANGE",
+ "RING2-STACK-IN-USE",
+ "META-EXPANSION-TOO-LONG",
+ "INVALID-SIGNAL-NUMBER",
+ "THREAD-1-INACTIVE",
+ "INFO-NOT-AVAIL",
+ "LOCKED",
+ "BAD-DYNALINK",
+ "TOO-MANY-MODULES",
+ "NESTING-NOT-ALLOWED",
+ "CANNOT-SHRINK",
+ "ZOMBIE-PROCESS",
+ "STACK-IN-HIGH-MEMORY",
+ "INVALID-EXITROUTINE-RING",
+ "GETBUF-FAILED",
+ "FLUSHBUF-FAILED",
+ "TRANSFER-TOO-LONG",
+ "FORCENOSWAP-FAILED",
+ "SMG-NO-TARGET-WINDOW",
+ "NO-CHILDREN",
+ "INVALID-SCREEN-GROUP",
+ "BAD-PIPE",
+ "PIPE-BUSY",
+ "NO-DATA",
+ "PIPE-NOT-CONNECTED",
+ "MORE-DATA",
+ "VC-DISCONNECTED",
+ "CIRCULARITY-REQUESTED",
+ "DIRECTORY-IN-CDS",
+ "INVALID-FSD-NAME",
+ "INVALID-PATH",
+ "INVALID-EA-NAME",
+ "EA-LIST-INCONSISTENT",
+ "EA-LIST-TOO-LONG",
+ "NO-META-MATCH",
+ "FINDNOTIFY-TIMEOUT",
+ "NO-MORE-ITEMS",
+ "SEARCH-STRUC-REUSED",
+ "CHAR-NOT-FOUND",
+ "TOO-MUCH-STACK",
+ "INVALID-ATTR",
+ "INVALID-STARTING-RING",
+ "INVALID-DLL-INIT-RING",
+ "CANNOT-COPY",
+ "DIRECTORY",
+ "OPLOCKED-FILE",
+ "OPLOCK-THREAD-EXISTS",
+ "VOLUME-CHANGED",
+ "FINDNOTIFY-HANDLE-IN-USE",
+ "FINDNOTIFY-HANDLE-CLOSED",
+ "NOTIFY-OBJECT-REMOVED",
+ "ALREADY-SHUTDOWN",
+ "EAS-DIDNT-FIT",
+ "EA-FILE-CORRUPT",
+ "EA-TABLE-FULL",
+ "INVALID-EA-HANDLE",
+ "NO-CLUSTER",
+ "CREATE-EA-FILE",
+ "CANNOT-OPEN-EA-FILE",
+ "EAS-NOT-SUPPORTED",
+ "NEED-EAS-FOUND",
+ "DUPLICATE-HANDLE",
+ "DUPLICATE-NAME",
+ "EMPTY-MUXWAIT",
+ "MUTEX-OWNED",
+ "NOT-OWNER",
+ "PARAM-TOO-SMALL",
+ "TOO-MANY-HANDLES",
+ "TOO-MANY-OPENS",
+ "WRONG-TYPE",
+ "UNUSED-CODE",
+ "THREAD-NOT-TERMINATED",
+ "INIT-ROUTINE-FAILED",
+ "MODULE-IN-USE",
+ "NOT-ENOUGH-WATCHPOINTS",
+ "TOO-MANY-POSTS",
+ "ALREADY-POSTED",
+ "ALREADY-RESET",
+ "SEM-BUSY",
+ "INVALID-PROCID",
+ "INVALID-PDELTA",
+ "NOT-DESCENDANT",
+ "NOT-SESSION-MANAGER",
+ "INVALID-PCLASS",
+ "INVALID-SCOPE",
+ "INVALID-THREADID",
+ "DOSSUB-SHRINK",
+ "DOSSUB-NOMEM",
+ "DOSSUB-OVERLAP",
+ "DOSSUB-BADSIZE",
+ "DOSSUB-BADFLAG",
+ "DOSSUB-BADSELECTOR",
+ "MR-MSG-TOO-LONG",
+ "MR-MID-NOT-FOUND",
+ "MR-UN-ACC-MSGF",
+ "MR-INV-MSGF-FORMAT",
+ "MR-INV-IVCOUNT",
+ "MR-UN-PERFORM",
+ "TS-WAKEUP",
+ "TS-SEMHANDLE",
+ "TS-NOTIMER",
+ "TS-HANDLE",
+ "TS-DATETIME",
+ "SYS-INTERNAL",
+ "QUE-CURRENT-NAME",
+ "QUE-PROC-NOT-OWNED",
+ "QUE-PROC-OWNED",
+ "QUE-DUPLICATE",
+ "QUE-ELEMENT-NOT-EXIST",
+ "QUE-NO-MEMORY",
+ "QUE-INVALID-NAME",
+ "QUE-INVALID-PRIORITY",
+ "QUE-INVALID-HANDLE",
+ "QUE-LINK-NOT-FOUND",
+ "QUE-MEMORY-ERROR",
+ "QUE-PREV-AT-END",
+ "QUE-PROC-NO-ACCESS",
+ "QUE-EMPTY",
+ "QUE-NAME-NOT-EXIST",
+ "QUE-NOT-INITIALIZED",
+ "QUE-UNABLE-TO-ACCESS",
+ "QUE-UNABLE-TO-ADD",
+ "QUE-UNABLE-TO-INIT",
+ "VIO-INVALID-MASK",
+ "VIO-PTR",
+ "VIO-APTR",
+ "VIO-RPTR",
+ "VIO-CPTR",
+ "VIO-LPTR",
+ "VIO-MODE",
+ "VIO-WIDTH",
+ "VIO-ATTR",
+ "VIO-ROW",
+ "VIO-COL",
+ "VIO-TOPROW",
+ "VIO-BOTROW",
+ "VIO-RIGHTCOL",
+ "VIO-LEFTCOL",
+ "SCS-CALL",
+ "SCS-VALUE",
+ "VIO-WAIT-FLAG",
+ "VIO-UNLOCK",
+ "SGS-NOT-SESSION-MGR",
+ "SMG-INVALID-SESSION-ID",
+ "SMG-NO-SESSIONS",
+ "SMG-SESSION-NOT-FOUND",
+ "SMG-SET-TITLE",
+ "KBD-PARAMETER",
+ "KBD-NO-DEVICE",
+ "KBD-INVALID-IOWAIT",
+ "KBD-INVALID-LENGTH",
+ "KBD-INVALID-ECHO-MASK",
+ "KBD-INVALID-INPUT-MASK",
+ "MON-INVALID-PARMS",
+ "MON-INVALID-DEVNAME",
+ "MON-INVALID-HANDLE",
+ "MON-BUFFER-TOO-SMALL",
+ "MON-BUFFER-EMPTY",
+ "MON-DATA-TOO-LARGE",
+ "MOUSE-NO-DEVICE",
+ "MOUSE-INV-HANDLE",
+ "MOUSE-INV-PARMS",
+ "MOUSE-CANT-RESET",
+ "MOUSE-DISPLAY-PARMS",
+ "MOUSE-INV-MODULE",
+ "MOUSE-INV-ENTRY-PT",
+ "MOUSE-INV-MASK",
+ "MOUSE-NO-DATA",
+ "MOUSE-PTR-DRAWN",
+ "INVALID-FREQUENCY",
+ "NLS-NO-COUNTRY-FILE",
+ "NLS-OPEN-FAILED",
+ "NO-COUNTRY-OR-CODEPAGE",
+ "NLS-TABLE-TRUNCATED",
+ "NLS-BAD-TYPE",
+ "NLS-TYPE-NOT-FOUND",
+ "VIO-SMG-ONLY",
+ "VIO-INVALID-ASCIIZ",
+ "VIO-DEREGISTER",
+ "VIO-NO-POPUP",
+ "VIO-EXISTING-POPUP",
+ "KBD-SMG-ONLY",
+ "KBD-INVALID-ASCIIZ",
+ "KBD-INVALID-MASK",
+ "KBD-REGISTER",
+ "KBD-DEREGISTER",
+ "MOUSE-SMG-ONLY",
+ "MOUSE-INVALID-ASCIIZ",
+ "MOUSE-INVALID-MASK",
+ "MOUSE-REGISTER",
+ "MOUSE-DEREGISTER",
+ "SMG-BAD-ACTION",
+ "SMG-INVALID-CALL",
+ "SCS-SG-NOTFOUND",
+ "SCS-NOT-SHELL",
+ "VIO-INVALID-PARMS",
+ "VIO-FUNCTION-OWNED",
+ "VIO-RETURN",
+ "SCS-INVALID-FUNCTION",
+ "SCS-NOT-SESSION-MGR",
+ "VIO-REGISTER",
+ "VIO-NO-MODE-THREAD",
+ "VIO-NO-SAVE-RESTORE-THD",
+ "VIO-IN-BG",
+ "VIO-ILLEGAL-DURING-POPUP",
+ "SMG-NOT-BASESHELL",
+ "SMG-BAD-STATUSREQ",
+ "QUE-INVALID-WAIT",
+ "VIO-LOCK",
+ "MOUSE-INVALID-IOWAIT",
+ "VIO-INVALID-HANDLE",
+ "VIO-ILLEGAL-DURING-LOCK",
+ "VIO-INVALID-LENGTH",
+ "KBD-INVALID-HANDLE",
+ "KBD-NO-MORE-HANDLE",
+ "KBD-CANNOT-CREATE-KCB",
+ "KBD-CODEPAGE-LOAD-INCOMPL",
+ "KBD-INVALID-CODEPAGE-ID",
+ "KBD-NO-CODEPAGE-SUPPORT",
+ "KBD-FOCUS-REQUIRED",
+ "KBD-FOCUS-ALREADY-ACTIVE",
+ "KBD-KEYBOARD-BUSY",
+ "KBD-INVALID-CODEPAGE",
+ "KBD-UNABLE-TO-FOCUS",
+ "SMG-SESSION-NON-SELECT",
+ "SMG-SESSION-NOT-FOREGRND",
+ "SMG-SESSION-NOT-PARENT",
+ "SMG-INVALID-START-MODE",
+ "SMG-INVALID-RELATED-OPT",
+ "SMG-INVALID-BOND-OPTION",
+ "SMG-INVALID-SELECT-OPT",
+ "SMG-START-IN-BACKGROUND",
+ "SMG-INVALID-STOP-OPTION",
+ "SMG-BAD-RESERVE",
+ "SMG-PROCESS-NOT-PARENT",
+ "SMG-INVALID-DATA-LENGTH",
+ "SMG-NOT-BOUND",
+ "SMG-RETRY-SUB-ALLOC",
+ "KBD-DETACHED",
+ "VIO-DETACHED",
+ "MOU-DETACHED",
+ "VIO-FONT",
+ "VIO-USER-FONT",
+ "VIO-BAD-CP",
+ "VIO-NO-CP",
+ "VIO-NA-CP",
+ "INVALID-CODE-PAGE",
+ "CPLIST-TOO-SMALL",
+ "CP-NOT-MOVED",
+ "MODE-SWITCH-INIT",
+ "CODE-PAGE-NOT-FOUND",
+ "UNEXPECTED-SLOT-RETURNED",
+ "SMG-INVALID-TRACE-OPTION",
+ "VIO-INTERNAL-RESOURCE",
+ "VIO-SHELL-INIT",
+ "SMG-NO-HARD-ERRORS",
+ "CP-SWITCH-INCOMPLETE",
+ "VIO-TRANSPARENT-POPUP",
+ "CRITSEC-OVERFLOW",
+ "CRITSEC-UNDERFLOW",
+ "VIO-BAD-RESERVE",
+ "INVALID-ADDRESS",
+ "ZERO-SELECTORS-REQUESTED",
+ "NOT-ENOUGH-SELECTORS-AVA",
+ "INVALID-SELECTOR",
+ "SMG-INVALID-PROGRAM-TYPE",
+ "SMG-INVALID-PGM-CONTROL",
+ "SMG-INVALID-INHERIT-OPT",
+ "VIO-EXTENDED-SG",
+ "VIO-NOT-PRES-MGR-SG",
+ "VIO-SHIELD-OWNED",
+ "VIO-NO-MORE-HANDLES",
+ "VIO-SEE-ERROR-LOG",
+ "VIO-ASSOCIATED-DC",
+ "KBD-NO-CONSOLE",
+ "MOUSE-NO-CONSOLE",
+ "MOUSE-INVALID-HANDLE",
+ "SMG-INVALID-DEBUG-PARMS",
+ "KBD-EXTENDED-SG",
+ "MOU-EXTENDED-SG",
+ "SMG-INVALID-ICON-FILE",
+ "TRC-PID-NON-EXISTENT",
+ "TRC-COUNT-ACTIVE",
+ "TRC-SUSPENDED-BY-COUNT",
+ "TRC-COUNT-INACTIVE",
+ "TRC-COUNT-REACHED",
+ "NO-MC-TRACE",
+ "MC-TRACE",
+ "TRC-COUNT-ZERO",
+ "SMG-TOO-MANY-DDS",
+ "SMG-INVALID-NOTIFICATION",
+ "LF-INVALID-FUNCTION",
+ "LF-NOT-AVAIL",
+ "LF-SUSPENDED",
+ "LF-BUF-TOO-SMALL",
+ "LF-BUFFER-FULL",
+ "LF-INVALID-RECORD",
+ "LF-INVALID-SERVICE",
+ "LF-GENERAL-FAILURE",
+ "LF-INVALID-ID",
+ "LF-INVALID-HANDLE",
+ "LF-NO-ID-AVAIL",
+ "LF-TEMPLATE-AREA-FULL",
+ "LF-ID-IN-USE",
+ "MOU-NOT-INITIALIZED",
+ "MOUINITREAL-DONE",
+ "DOSSUB-CORRUPTED",
+ "MOUSE-CALLER-NOT-SUBSYS",
+ "ARITHMETIC-OVERFLOW",
+ "TMR-NO-DEVICE",
+ "TMR-INVALID-TIME",
+ "PVW-INVALID-ENTITY",
+ "PVW-INVALID-ENTITY-TYPE",
+ "PVW-INVALID-SPEC",
+ "PVW-INVALID-RANGE-TYPE",
+ "PVW-INVALID-COUNTER-BLK",
+ "PVW-INVALID-TEXT-BLK",
+ "PRF-NOT-INITIALIZED",
+ "PRF-ALREADY-INITIALIZED",
+ "PRF-NOT-STARTED",
+ "PRF-ALREADY-STARTED",
+ "PRF-TIMER-OUT-OF-RANGE",
+ "PRF-TIMER-RESET",
+ "VDD-LOCK-USEAGE-DENIED",
+ "TIMEOUT",
+ "VDM-DOWN",
+ "VDM-LIMIT",
+ "VDD-NOT-FOUND",
+ "INVALID-CALLER",
+ "PID-MISMATCH",
+ "INVALID-VDD-HANDLE",
+ "VLPT-NO-SPOOLER",
+ "VCOM-DEVICE-BUSY",
+ "VLPT-DEVICE-BUSY",
+ "NESTING-TOO-DEEP",
+ "VDD-MISSING",
+ "BIDI-INVALID-LENGTH",
+ "BIDI-INVALID-INCREMENT",
+ "BIDI-INVALID-COMBINATION",
+ "BIDI-INVALID-RESERVED",
+ "BIDI-INVALID-EFFECT",
+ "BIDI-INVALID-CSDREC",
+ "BIDI-INVALID-CSDSTATE",
+ "BIDI-INVALID-LEVEL",
+ "BIDI-INVALID-TYPE-SUPPORT",
+ "BIDI-INVALID-ORIENTATION",
+ "BIDI-INVALID-NUM-SHAPE",
+ "BIDI-INVALID-CSD",
+ "BIDI-NO-SUPPORT",
+ "BIDI-RW-INCOMPLETE",
+ "IMP-INVALID-PARM",
+ "IMP-INVALID-LENGTH",
+ "HPFS-DISK-ERROR-WARN",
+ "MON-BAD-BUFFER",
+ "MODULE-CORRUPTED",
+ "SM-OUTOF-SWAPFILE",
+ "LF-TIMEOUT",
+ "LF-SUSPEND-SUCCESS",
+ "LF-RESUME-SUCCESS",
+ "LF-REDIRECT-SUCCESS",
+ "LF-REDIRECT-FAILURE",
+ "SWAPPER-NOT-ACTIVE",
+ "INVALID-SWAPID",
+ "IOERR-SWAP-FILE",
+ "SWAP-TABLE-FULL",
+ "SWAP-FILE-FULL",
+ "CANT-INIT-SWAPPER",
+ "SWAPPER-ALREADY-INIT",
+ "PMM-INSUFFICIENT-MEMORY",
+ "PMM-INVALID-FLAGS",
+ "PMM-INVALID-ADDRESS",
+ "PMM-LOCK-FAILED",
+ "PMM-UNLOCK-FAILED",
+ "PMM-MOVE-INCOMPLETE",
+ "UCOM-DRIVE-RENAMED",
+ "UCOM-FILENAME-TRUNCATED",
+ "UCOM-BUFFER-LENGTH",
+ "MON-CHAIN-HANDLE",
+ "MON-NOT-REGISTERED",
+ "SMG-ALREADY-TOP",
+ "PMM-ARENA-MODIFIED",
+ "SMG-PRINTER-OPEN",
+ "PMM-SET-FLAGS-FAILED",
+ "INVALID-DOS-DD",
+ "BLOCKED",
+ "NOBLOCK",
+ "INSTANCE-SHARED",
+ "NO-OBJECT",
+ "PARTIAL-ATTACH",
+ "INCACHE",
+ "SWAP-IO-PROBLEMS",
+ "CROSSES-OBJECT-BOUNDARY",
+ "LONGLOCK",
+ "SHORTLOCK",
+ "UVIRTLOCK",
+ "ALIASLOCK",
+ "ALIAS",
+ "NO-MORE-HANDLES",
+ "SCAN-TERMINATED",
+ "TERMINATOR-NOT-FOUND",
+ "NOT-DIRECT-CHILD",
+ "DELAY-FREE",
+ "GUARDPAGE",
+ "SWAPERROR",
+ "LDRERROR",
+ "NOMEMORY",
+ "NOACCESS",
+ "NO-DLL-TERM",
+ "CPSIO-CODE-PAGE-INVALID",
+ "CPSIO-NO-SPOOLER",
+ "CPSIO-FONT-ID-INVALID",
+ "CPSIO-INTERNAL-ERROR",
+ "CPSIO-INVALID-PTR-NAME",
+ "CPSIO-NOT-ACTIVE",
+ "CPSIO-PID-FULL",
+ "CPSIO-PID-NOT-FOUND",
+ "CPSIO-READ-CTL-SEQ",
+ "CPSIO-READ-FNT-DEF",
+ "CPSIO-WRITE-ERROR",
+ "CPSIO-WRITE-FULL-ERROR",
+ "CPSIO-WRITE-HANDLE-BAD",
+ "CPSIO-SWIT-LOAD",
+ "CPSIO-INV-COMMAND",
+ "CPSIO-NO-FONT-SWIT",
+ "ENTRY-IS-CALLGATE",
+ "UNKNOWN"
+};
+
+void
+OS_syserr_names (unsigned int * length, unsigned char *** names)
+{
+ (*length) = ((sizeof (syserr_names_table)) / (sizeof (char *)));
+ (*names) = ((unsigned char **) syserr_names_table);
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: os2tty.c,v 1.1 1994/11/28 03:43:02 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "os2.h"
+#include "ostty.h"
+#ifdef USE_PMIO
+#include <pmio.h>
+#endif
+\f
+static Tchannel input_channel;
+static Tchannel output_channel;
+
+void
+OS2_initialize_tty (void)
+{
+ extern Tchannel EXFUN (OS_open_fd, (int fd));
+ input_channel = (OS2_make_channel (0, CHANNEL_READ));
+ (CHANNEL_INTERNAL (input_channel)) = 1;
+ output_channel = (OS2_make_channel (1, CHANNEL_WRITE));
+ (CHANNEL_INTERNAL (output_channel)) = 1;
+}
+
+Tchannel
+OS_tty_input_channel (void)
+{
+ return (input_channel);
+}
+
+Tchannel
+OS_tty_output_channel (void)
+{
+ return (output_channel);
+}
+
+unsigned int
+OS_tty_x_size (void)
+{
+#ifdef USE_PMIO
+ return (get_screen_width ());
+#else
+ return (80);
+#endif
+}
+
+unsigned int
+OS_tty_y_size (void)
+{
+#ifdef USE_PMIO
+ return (get_screen_height ());
+#else
+ return (24);
+#endif
+}
+
+const char *
+OS_tty_command_beep (void)
+{
+ return ("\a");
+}
+
+const char *
+OS_tty_command_clear (void)
+{
+ return ("\f");
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: pros2fs.c,v 1.1 1994/11/28 03:43:02 cph Exp $
+
+Copyright (c) 1994 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "scheme.h"
+#undef END_OF_CHAIN
+#include "prims.h"
+#include "os2.h"
+#include "osfs.h"
+
+extern FILESTATUS3 * OS2_read_file_status (const char *);
+extern void OS2_write_file_status (const char *, FILESTATUS3 *);
+
+#ifndef FILE_TOUCH_OPEN_TRIES
+#define FILE_TOUCH_OPEN_TRIES 5
+#endif
+
+static SCHEME_OBJECT time_to_integer (FDATE *, FTIME *);
+static void integer_to_time (SCHEME_OBJECT, FDATE *, FTIME *);
+static SCHEME_OBJECT file_touch (const char *);
+static void protect_handle (LHANDLE);
+\f
+DEFINE_PRIMITIVE ("FILE-ATTRIBUTES", Prim_file_attributes, 1, 1,
+ "Return attributes of FILE, as an integer.")
+{
+ PRIMITIVE_HEADER (1);
+ {
+ FILESTATUS3 * info = (OS2_read_file_status (STRING_ARG (1)));
+ PRIMITIVE_RETURN
+ ((info == 0)
+ ? SHARP_F
+ : (LONG_TO_UNSIGNED_FIXNUM (info -> attrFile)));
+ }
+}
+
+DEFINE_PRIMITIVE ("SET-FILE-ATTRIBUTES!", Prim_set_file_attributes, 2, 2,
+ "Set the attributes of FILE to ATTRIBUTES.")
+{
+ PRIMITIVE_HEADER (2);
+ {
+ FILESTATUS3 * info = (OS2_read_file_status (STRING_ARG (1)));
+ if (info == 0)
+ error_bad_range_arg (1);
+ (info -> attrFile) = (arg_index_integer (2, 0x10000));
+ OS2_write_file_status ((STRING_ARG (1)), info);
+ PRIMITIVE_RETURN (UNSPECIFIC);
+ }
+}
+
+DEFINE_PRIMITIVE ("FILE-LENGTH", Prim_file_length, 1, 1,
+ "Return attributes of FILE, as an integer.")
+{
+ PRIMITIVE_HEADER (1);
+ {
+ FILESTATUS3 * info = (OS2_read_file_status (STRING_ARG (1)));
+ PRIMITIVE_RETURN
+ ((info == 0)
+ ? SHARP_F
+ : (LONG_TO_UNSIGNED_FIXNUM (info -> cbFile)));
+ }
+}
+
+DEFINE_PRIMITIVE ("GET-ENVIRONMENT-VARIABLE", Prim_get_environment_variable, 1, 1,
+ "Look up the value of a variable in the user's shell environment.\n\
+The argument, a variable name, must be a string.\n\
+The result is either a string (the variable's value),\n\
+ or #F indicating that the variable does not exist.")
+{
+ PRIMITIVE_HEADER (1);
+ {
+ PSZ result;
+ XTD_API_CALL
+ (dos_scan_env, ((STRING_ARG (1)), (& result)),
+ {
+ if (rc == ERROR_ENVVAR_NOT_FOUND)
+ PRIMITIVE_RETURN (SHARP_F);
+ });
+ PRIMITIVE_RETURN (char_pointer_to_string (result));
+ }
+}
+
+DEFINE_PRIMITIVE ("FILE-EQ?", Prim_file_eq_p, 2, 2,
+ "True iff the two file arguments are the same file.")
+{
+ PRIMITIVE_HEADER (2);
+ CHECK_ARG (1, STRING_P);
+ CHECK_ARG (2, STRING_P);
+ {
+ unsigned long length = (STRING_LENGTH (ARG_REF (1)));
+ const char * s1 = (STRING_LOC ((ARG_REF (1)), 0));
+ const char * s2 = (STRING_LOC ((ARG_REF (2)), 0));
+ const char * e1 = (s1 + length);
+ if ((STRING_LENGTH (ARG_REF (2))) != length)
+ PRIMITIVE_RETURN (SHARP_F);
+ while (s1 < e1)
+ if ((char_upcase (*s1++)) != (char_upcase (*s2++)))
+ PRIMITIVE_RETURN (SHARP_F);
+ PRIMITIVE_RETURN (SHARP_T);
+ }
+}
+\f
+DEFINE_PRIMITIVE ("FILE-MOD-TIME", Prim_file_mod_time, 1, 1, 0)
+{
+ PRIMITIVE_HEADER (1);
+ {
+ FILESTATUS3 * info = (OS2_read_file_status (STRING_ARG (1)));
+ PRIMITIVE_RETURN
+ ((info == 0)
+ ? SHARP_F
+ : (time_to_integer ((& (info -> fdateLastWrite)),
+ (& (info -> ftimeLastWrite)))));
+ }
+}
+
+DEFINE_PRIMITIVE ("FILE-ACCESS-TIME", Prim_file_acc_time, 1, 1, 0)
+{
+ PRIMITIVE_HEADER (1);
+ {
+ FILESTATUS3 * info = (OS2_read_file_status (STRING_ARG (1)));
+ PRIMITIVE_RETURN
+ ((info == 0)
+ ? SHARP_F
+ : (time_to_integer ((& (info -> fdateLastAccess)),
+ (& (info -> ftimeLastAccess)))));
+ }
+}
+
+DEFINE_PRIMITIVE ("SET-FILE-TIMES!", Prim_set_file_times, 3, 3,
+ "Change the access and modification times of FILE.\n\
+The second and third arguments are the respective times.\n\
+The file must exist and you must be the owner (or superuser).")
+{
+ PRIMITIVE_HEADER (3);
+ {
+ FILESTATUS3 * info = (OS2_read_file_status (STRING_ARG (1)));
+ SCHEME_OBJECT atime = (ARG_REF (2));
+ SCHEME_OBJECT mtime = (ARG_REF (3));
+ if (info == 0)
+ error_bad_range_arg (1);
+ if (atime != SHARP_F)
+ {
+ if (!INTEGER_P (atime))
+ error_wrong_type_arg (2);
+ if (integer_negative_p (atime))
+ error_bad_range_arg (2);
+ integer_to_time (atime,
+ (& (info -> fdateLastAccess)),
+ (& (info -> ftimeLastAccess)));
+ }
+ if (mtime != SHARP_F)
+ {
+ if (!INTEGER_P (mtime))
+ error_wrong_type_arg (3);
+ if (integer_negative_p (mtime))
+ error_bad_range_arg (3);
+ integer_to_time (mtime,
+ (& (info -> fdateLastWrite)),
+ (& (info -> ftimeLastWrite)));
+ }
+ OS2_write_file_status ((STRING_ARG (1)), info);
+ }
+ PRIMITIVE_RETURN (UNSPECIFIC);
+}
+
+DEFINE_PRIMITIVE ("FILE-TOUCH", Prim_file_touch, 1, 1,
+ "Given a file name, change the times of the file to the current time.\n\
+If the file does not exist, create it.\n\
+Both the access time and modification time are changed.\n\
+Return #F if the file existed and its time was modified.\n\
+Otherwise the file did not exist and it was created.")
+{
+ PRIMITIVE_HEADER (1);
+ PRIMITIVE_RETURN (file_touch ((CONST char *) (STRING_ARG (1))));
+}
+\f
+static SCHEME_OBJECT
+time_to_integer (FDATE * date, FTIME * time)
+{
+ unsigned long id;
+ unsigned long it;
+ id = (date -> year);
+ id = ((id << 4) | (date -> month));
+ id = ((id << 5) | (date -> day));
+ it = (time -> hours);
+ it = ((it << 6) | (time -> minutes));
+ it = ((it << 5) | (time -> twosecs));
+ return
+ (integer_add ((integer_multiply ((LONG_TO_UNSIGNED_FIXNUM (id)),
+ (LONG_TO_UNSIGNED_FIXNUM (0x10000)))),
+ (LONG_TO_UNSIGNED_FIXNUM (it))));
+}
+
+static void
+integer_to_time (SCHEME_OBJECT encoding, FDATE * date, FTIME * time)
+{
+ unsigned long id;
+ unsigned long it;
+ {
+ SCHEME_OBJECT q;
+ SCHEME_OBJECT r;
+ (void) integer_divide
+ (encoding, (LONG_TO_UNSIGNED_FIXNUM (0x10000)), (&q), (&r));
+ it = (UNSIGNED_FIXNUM_TO_LONG (r));
+ /* If encoding is larger than 32 bits, ignore MS bits. */
+ (void) integer_divide
+ (q, (LONG_TO_UNSIGNED_FIXNUM (0x10000)), (&q), (&r));
+ id = (UNSIGNED_FIXNUM_TO_LONG (r));
+ }
+ (date -> day) = (id & 0x1f);
+ id >>= 5;
+ (date -> month) = (id & 0x0f);
+ id >>= 4;
+ (date -> year) = id;
+ (time -> twosecs) = (it & 0x1f);
+ it >>= 5;
+ (time -> minutes) = (it & 0x3f);
+ it >>= 6;
+ (time -> hours) = it;
+}
+\f
+static SCHEME_OBJECT
+file_touch (const char * filename)
+{
+ HFILE handle;
+ ULONG action;
+ APIRET rc;
+ unsigned int count = 0;
+
+ transaction_begin ();
+ while (1)
+ {
+ APIRET rc
+ = (dos_open (((char *) filename),
+ (&handle),
+ (&action),
+ 0,
+ FILE_NORMAL,
+ (OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW),
+ (OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE),
+ 0));
+ if (rc == NO_ERROR)
+ break;
+ if ((rc != NO_ERROR)
+ && (rc != ERROR_FILE_NOT_FOUND)
+ && (rc != ERROR_PATH_NOT_FOUND)
+ && ((++ count) >= FILE_TOUCH_OPEN_TRIES))
+ OS2_error_system_call (rc, syscall_dos_open);
+ }
+ protect_handle (handle);
+ if (action == FILE_CREATED)
+ {
+ transaction_commit ();
+ return (SHARP_T);
+ }
+ /* Existing file -- we'll write something to it to make sure that it
+ has its times updated properly upon close. This was needed for
+ unix implementation, but it is not known whether it is needed in
+ OS/2. In any case, it does no harm to do this. */
+ {
+ FILESTATUS3 info;
+ char buffer [1];
+ ULONG n;
+ STD_API_CALL (dos_query_file_info,
+ (handle, FIL_STANDARD, (& info), (sizeof (info))));
+ if ((info . cbFile) == 0)
+ {
+ /* Zero-length file: write a byte, then reset the length. */
+ (buffer[0]) = '\0';
+ STD_API_CALL (dos_write, (handle, buffer, 1, (& n)));
+ STD_API_CALL (dos_set_file_size, (handle, 0));
+ }
+ else
+ {
+ /* Read the first byte, then write it back in place. */
+ STD_API_CALL (dos_read, (handle, buffer, 1, (&n)));
+ STD_API_CALL (dos_set_file_ptr, (handle, 0, FILE_BEGIN, (& n)));
+ STD_API_CALL (dos_write, (handle, buffer, 1, (& n)));
+ }
+ }
+ transaction_commit ();
+ return (SHARP_F);
+}
+
+static void
+protect_handle_1 (void * hp)
+{
+ (void) dos_close (* ((LHANDLE *) hp));
+}
+
+static void
+protect_handle (LHANDLE h)
+{
+ LHANDLE * hp = (dstack_alloc (sizeof (LHANDLE)));
+ (*hp) = h;
+ transaction_record_action (tat_always, protect_handle_1, hp);
+}
+\f
+DEFINE_PRIMITIVE ("FILE-INFO", Prim_file_info, 1, 1,
+ "Given a file name, return information about the file.\n\
+If the file exists and its information is accessible,\n\
+ the result is a vector of 6 items.\n\
+Otherwise the result is #F.")
+{
+ FILESTATUS3 * info;
+ SCHEME_OBJECT result;
+ SCHEME_OBJECT modes;
+ PRIMITIVE_HEADER (1);
+
+ info = (OS2_read_file_status (STRING_ARG (1)));
+ if (info == 0)
+ PRIMITIVE_RETURN (SHARP_F);
+ result = (allocate_marked_vector (TC_VECTOR, 6, true));
+ modes = (allocate_string (5));
+ VECTOR_SET (result, 0,
+ ((((info -> attrFile) & FILE_DIRECTORY) != 0)
+ ? SHARP_T
+ : SHARP_F));
+ VECTOR_SET (result, 1,
+ (time_to_integer ((& (info -> fdateLastAccess)),
+ (& (info -> ftimeLastAccess)))));
+ VECTOR_SET (result, 2,
+ (time_to_integer ((& (info -> fdateLastWrite)),
+ (& (info -> ftimeLastWrite)))));
+ VECTOR_SET (result, 3,
+ (time_to_integer ((& (info -> fdateCreation)),
+ (& (info -> ftimeCreation)))));
+ VECTOR_SET (result, 4, (long_to_integer (info -> cbFile)));
+ {
+ unsigned int attr = (info -> attrFile);
+ char * s = ((char *) (STRING_LOC (modes, 0)));
+ (s[0]) = (((attr & FILE_READONLY) != 0) ? 'r' : '_');
+ (s[1]) = (((attr & FILE_HIDDEN) != 0) ? 'h' : '_');
+ (s[2]) = (((attr & FILE_SYSTEM) != 0) ? 's' : '_');
+ (s[3]) = (((attr & FILE_ARCHIVED) != 0) ? 'a' : '_');
+ (s[4]) = (((attr & FILE_DIRECTORY) != 0) ? 'd' : '_');
+ }
+ VECTOR_SET (result, 5, modes);
+ PRIMITIVE_RETURN (result);
+}