Add rudimentary (synchronous) subprocesses.
authorGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Thu, 1 Oct 1992 18:20:41 +0000 (18:20 +0000)
committerGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Thu, 1 Oct 1992 18:20:41 +0000 (18:20 +0000)
v7/src/microcode/dosx32.c
v7/src/microcode/prdosenv.c

index 5c42ce2b1c6c85db64ac67e2b425e9e5a9006edb..8acb30cb8d7f67f7e75db21fd2dbea04c3c01e8b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-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
 
@@ -35,6 +35,8 @@ MIT in each case. */
 #include <int.h>
 #include <stdio.h>
 #include "ansidecl.h"
+#include "dosio.h"
+#include "dossys.h"
 \f
 /* Exports */
 
@@ -116,7 +118,7 @@ DEFUN (unlock_region, (segment, offset, size),
 {
   return (lock_unlock (OPERATION_UNLOCK, segment, offset, size));
 }
-\f
+
 #define ES     0
 #define CS     1
 #define SS     2
@@ -154,7 +156,7 @@ static struct wired_area_s wired_areas[] =
     ((PTR) &scan_code_tables_end[0])
   }
 };
-
+\f
 #define N_WIRED_AREAS ((sizeof (wired_areas)) / (sizeof (struct wired_area_s)))
 
 int
@@ -201,6 +203,7 @@ struct save_record
   unsigned iv;
   struct save_area * area;
   struct save_record * next;
+  void EXFUN ((* handler), (void));
 };
 
 static struct save_record
@@ -224,33 +227,49 @@ DEFUN (X32_do_restore, (iv, area),
   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, &regs, &regs, &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;
 
@@ -260,9 +279,26 @@ DEFUN (X32_remember_interrupt, (iv, area),
   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),
@@ -299,22 +335,146 @@ 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, &regs, &regs, &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);
+}
index 55401db9d316b9b4d5f7271949648272a9b20429..1a35a827a91e558249067b43caba48196d894664 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-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
 
@@ -38,6 +38,7 @@ MIT in each case. */
 #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\
@@ -103,49 +104,51 @@ DEFINE_PRIMITIVE ("SYSTEM", Prim_system, 1, 1,
   "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")