/* -*-C-*-
-$Id: dosx32.c,v 1.2 1992/09/03 07:30:13 jinx Exp $
+$Id: dosx32.c,v 1.3 1992/10/01 18:20:41 jinx Exp $
Copyright (c) 1992 Massachusetts Institute of Technology
#include <int.h>
#include <stdio.h>
#include "ansidecl.h"
+#include "dosio.h"
+#include "dossys.h"
\f
/* Exports */
{
return (lock_unlock (OPERATION_UNLOCK, segment, offset, size));
}
-\f
+
#define ES 0
#define CS 1
#define SS 2
((PTR) &scan_code_tables_end[0])
}
};
-
+\f
#define N_WIRED_AREAS ((sizeof (wired_areas)) / (sizeof (struct wired_area_s)))
int
unsigned iv;
struct save_area * area;
struct save_record * next;
+ void EXFUN ((* handler), (void));
};
static struct save_record
return (((regs.e.flags & 0x1) == 0) ? 0 : -1);
}
-int
-DEFUN (X32_interrupt_restore, (iv), unsigned iv)
+static int
+DEFUN (X32_do_install, (iv, handler),
+ unsigned iv
+ AND void EXFUN ((* handler), (void)))
+{
+ struct SREGS sregs;
+ union REGS regs;
+
+ /* Set real and protected mode handler. */
+
+ segread (&sregs);
+ regs.x.ax = 0x2506;
+ regs.h.cl = iv;
+ regs.e.edx = ((unsigned) handler);
+ sregs.ds = (getCS ());
+ int86x (0x21, ®s, ®s, &sregs);
+ if ((regs.e.flags & 1) != 0)
+ return (-1);
+ return (0);
+}
+\f
+static struct save_record **
+DEFUN (X32_find_interrupt, (iv), unsigned iv)
{
struct save_record ** loc, * this;
loc = &X32_save_areas;
- this = (*loc);
+ this = (* loc);
while (this != ((struct save_record *) NULL))
{
if (this->iv == iv)
- {
- if ((X32_do_restore (iv, this->area)) != 0)
- return (-1);
- *loc = (this->next);
- free (this);
- return (0);
- }
+ break;
loc = &this->next;
this = (*loc);
}
- return (-1);
+ return (loc);
}
-\f
-int
-DEFUN (X32_remember_interrupt, (iv, area),
+
+static int
+DEFUN (X32_remember_interrupt, (iv, area, handler),
unsigned iv
- AND struct save_area * area)
+ AND struct save_area * area
+ AND void EXFUN ((* handler), (void)))
{
struct save_record * this;
this->iv = iv;
this->area = area;
this->next = X32_save_areas;
+ this->handler = handler;
X32_save_areas = this;
return (0);
}
+\f
+int
+DEFUN (X32_interrupt_restore, (iv), unsigned iv)
+{
+ struct save_record ** loc, * this;
+
+ loc = (X32_find_interrupt (iv));
+ this = (* loc);
+ if ((this == ((struct save_record *) NULL))
+ || ((X32_do_restore (iv, this->area)) != 0))
+ return (-1);
+
+ * loc = (this->next);
+ free (this);
+ return (0);
+}
int
DEFUN (X32_int_intercept, (iv, handler, ptr),
area->protected_offset = regs.e.ebx;
}
- /* Set real and protected mode handler. */
+ if ((X32_do_install (iv, handler)) != 0)
+ return (-1);
+ if ((X32_remember_interrupt (iv, area, handler)) != 0)
{
- segread (&sregs);
- regs.x.ax = 0x2506;
- regs.h.cl = iv;
- regs.e.edx = ((unsigned) handler);
- sregs.ds = (getCS ());
- int86x (0x21, ®s, ®s, &sregs);
- if ((regs.e.flags & 1) != 0)
+ (void) X32_do_restore (iv, area);
+ return (-1);
+ }
+ return (0);
+}
+\f
+extern int EXFUN (X32_subprocess, (char *, int, int, int));
+extern int EXFUN (X32_system, (char *));
+extern int EXFUN (system, (char *));
+
+static int
+DEFUN (dummy_system, (command), char * command)
+{
+ return (-1);
+}
+
+static int
+DEFUN (X32_DPMI_system, (command), char * command)
+{
+ /* Plain system does not work in X32 under DPMI
+ in the presence of our timer interrupt handler.
+ Disable the timer interrupt around the call to system.
+ */
+ static struct save_record ** ptimer_record = ((struct save_record **) NULL);
+ struct save_record * timer_record;
+ int result;
+
+ if (ptimer_record == ((struct save_record **) NULL))
+ {
+ ptimer_record = (X32_find_interrupt (DOS_INTVECT_USER_TIMER_TICK));
+ if (ptimer_record == ((struct save_record **) NULL))
return (-1);
}
- if ((X32_remember_interrupt (iv, area)) != 0)
+
+ timer_record = * ptimer_record;
+ if ((X32_do_restore (DOS_INTVECT_USER_TIMER_TICK, timer_record->area))
+ != 0)
+ return (-1);
+
+ result = (system (command));
+
+ if ((X32_do_install (DOS_INTVECT_USER_TIMER_TICK, timer_record->handler))
+ != 0)
{
- (void) X32_do_restore (iv, area);
+ /* We are massively scrod. */
+ * ptimer_record = timer_record->next;
+ return (-2);
+ }
+ return (result);
+}
+
+int EXFUN (which_system, (char *));
+
+static int EXFUN ((* fsystem), (char *)) = which_system;
+
+static int
+DEFUN (which_system, (command), char * command)
+{
+ if (! (under_X32_p ()))
+ fsystem = dummy_system;
+ else if (! (under_DPMI_p ()))
+ fsystem = system;
+ else
+ fsystem = X32_DPMI_system;
+ return ((* fsystem) (command));
+}
+
+int
+DEFUN (X32_system, (command), char * command)
+{
+ return (((* fsystem) (command)));
+}
+\f
+/* values for io specs:
+ -1 => default (console)
+ >= 0 => channel number.
+ */
+
+static int
+DEFUN (swap_io_handle, (handle, spec),
+ int handle AND int spec)
+{
+ if ((spec == -1) || ((CHANNEL_DESCRIPTOR (spec)) == handle))
return (-1);
+ else
+ {
+ int saved = (dup (handle));
+ if (saved == -1)
+ return (-3);
+ if ((dup2 ((CHANNEL_DESCRIPTOR (spec)), handle)) != 0)
+ {
+ close (saved);
+ return (-4);
+ }
+ return (saved);
}
+}
+
+static int
+DEFUN (restore_io_handle, (handle, saved_handle),
+ int handle AND int saved_handle)
+{
+ if (saved_handle < 0)
+ return (0);
+ else if ((dup2 (saved_handle, handle)) != 0)
+ return (-1);
+ close (saved_handle);
return (0);
}
+
+#define SWAPPING_HANDLE(h, spec, code) do \
+{ \
+ int saved_handle = (swap_io_handle ((h), (spec))); \
+ if (saved_handle < -1) \
+ result = saved_handle; \
+ else \
+ { \
+ code; \
+ restore_io_handle ((h), saved_handle); \
+ } \
+} while (0)
+
+int
+DEFUN (X32_subprocess, (command, in_spec, out_spec, err_spec),
+ char * command
+ AND int in_spec
+ AND int out_spec
+ AND int err_spec)
+{
+ int result;
+
+ SWAPPING_HANDLE (0, in_spec,
+ SWAPPING_HANDLE (1, out_spec,
+ SWAPPING_HANDLE (2, err_spec,
+ (result = ((* fsystem)
+ (command))))));
+ return (result);
+}
/* -*-C-*-
-$Id: prdosenv.c,v 1.4 1992/09/30 19:32:25 jinx Exp $
+$Id: prdosenv.c,v 1.5 1992/10/01 18:18:05 jinx Exp $
Copyright (c) 1992 Massachusetts Institute of Technology
#include "scheme.h"
#include "prims.h"
#include "msdos.h"
+#include "dosio.h"
\f
DEFINE_PRIMITIVE ("CURRENT-FILE-TIME", Prim_current_file_time, 0, 0,
"Return the current file system time stamp.\n\
"Invoke COMMAND.COM on the string argument.\n\
Wait until the command terminates, returning its exit status as an integer.")
{
- static int state = 0;
- extern int EXFUN (under_X32_p, (void));
- extern int EXFUN (under_DPMI_p, (void));
+ int result;
+ extern int EXFUN (X32_system, (char *));
PRIMITIVE_HEADER (1);
-
- while (1)
- switch (state)
- {
- case 0:
- state = (((under_X32_p ()) && (! (under_DPMI_p ()))) ? 1 : -1);
- break;
-
- case 1:
- PRIMITIVE_RETURN (long_to_integer (DOS_system (STRING_ARG (1))));
-
- case -1:
- PRIMITIVE_RETURN (long_to_integer (-1));
- }
+
+ result = (X32_system (STRING_ARG (1)));
+ if (result < -1)
+ error_external_return ();
+ PRIMITIVE_RETURN (long_to_integer ((long) result));
}
-DEFINE_PRIMITIVE ("UNIX-ENVIRONMENT", Prim_unix_environment_alist, 0, 0,
- "Copy the unix environment and return it as a vector of strings.")
-{
- PRIMITIVE_HEADER (0);
- PRIMITIVE_RETURN (SHARP_F);
-}
+/* values for io specs:
+ -1 => default (console)
+ >= 0 => channel number.
+ */
-DEFINE_PRIMITIVE ("FULL-HOSTNAME", Prim_full_hostname, 0, 0,
- "Returns the full hostname (including domain if available) as a string.")
+static int
+DEFUN (arg_io_spec, (arg_no), int arg_no)
{
- PRIMITIVE_HEADER (0);
- PRIMITIVE_RETURN
- (char_pointer_to_string ((unsigned char *) "PC"));
+ int arg = (arg_integer (arg_no));
+
+ if ((arg < -1)
+ || (arg >= ((int) OS_channel_table_size))
+ || ((arg >= 0)
+ && (! (OS_channel_open_p ((Tchannel) arg)))))
+ error_bad_range_arg (arg_no);
+ return (arg);
}
-DEFINE_PRIMITIVE ("HOSTNAME", Prim_hostname, 0, 0,
- "Returns the hostname of the machine as a string.")
+DEFINE_PRIMITIVE ("RUN-SUBPROCESS", Prim_run_subprocess, 4, 4,
+ "Invoke COMMAND.COM on STRING with I/O as specified by other arguments.\n\
+Wait until the command terminates, returning its exit status as an integer.")
{
- PRIMITIVE_HEADER (0);
- PRIMITIVE_RETURN
- (char_pointer_to_string ((unsigned char *) "IBMPC"));
+ int result;
+ extern int EXFUN (X32_subprocess, (char *, int, int, int));
+ PRIMITIVE_HEADER (3);
+
+ result = (X32_subprocess ((STRING_ARG (1)),
+ (arg_io_spec (2)),
+ (arg_io_spec (3)),
+ (arg_io_spec (4))));
+ if (result < -1)
+ error_external_return ();
+ PRIMITIVE_RETURN ((long) result);
}
-
+\f
DEFINE_PRIMITIVE ("DOS-SET-KEYBOARD-MODIFIER-MASK!", Prim_dos_set_kbd_mod_mask,
1, 1,
"Set the keyboard modifier mask")