BSD 4_3_Reno release
[unix-history] / usr / src / usr.bin / tn3270 / distribution / sys_dos / spintc.c
index 4f0c9b3..0671f3f 100644 (file)
@@ -1,17 +1,35 @@
-#define        LINT_ARGS
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)spintc.c   4.1 (Berkeley) 12/4/88";
+#endif /* not lint */
 
 #include <stdio.h>
 #include <dos.h>
 #include <stdlib.h>
 
 
 #include <stdio.h>
 #include <dos.h>
 #include <stdlib.h>
 
-#include "../ntn3270/general.h"
+#include "../general/general.h"
+#include "spint.h"
 
 #define        PSP_ENVIRONMENT         0x2c
 #define        PSP_FCB1                0x5c
 #define        PSP_FCB2                0x6c
 
 
 #define        PSP_ENVIRONMENT         0x2c
 #define        PSP_FCB1                0x5c
 #define        PSP_FCB2                0x6c
 
-#define        INTERRUPT_NUMBER        73
-
 typedef struct {
     int
        environment,            /* Segment address of environment */
 typedef struct {
     int
        environment,            /* Segment address of environment */
@@ -23,24 +41,64 @@ typedef struct {
        fcb2_ptr_segment;       /* Segment of FCB 2 */
 } ExecList;
 
        fcb2_ptr_segment;       /* Segment of FCB 2 */
 } ExecList;
 
-typedef struct {
-    union REGS         regs;
-    struct SREGS       sregs;
-    int                        int_no; /* Which interrupt to wait on */
-    int                        done;   /* Are we done, or just took an interrupt? */
-    int                        rc;     /* return code */
-} Spawn;
+
+static int int_offset, int_segment;
+
+
+void
+spint_finish(spint)
+Spint *spint;
+{
+    union REGS regs;
+    struct SREGS sregs;
+
+    if (spint->done == 0) {
+       return;                         /* Not done yet */
+    }
+
+    /*
+     * Restore old interrupt handler.
+     */
+
+    regs.h.ah = 0x25;
+    regs.h.al = spint->int_no;
+    regs.x.dx = int_offset;
+    sregs.ds = int_segment;
+    intdosx(&regs, &regs, &sregs);
+
+    if (spint->regs.x.cflag) {
+       fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax);
+       spint->done = 1;
+       spint->rc = 99;
+       return;
+    }
+
+    regs.h.ah = 0x4d;                  /* Get return code */
+
+    intdos(&regs, &regs);
+
+    spint->rc = regs.x.ax;
+}
+
+void
+spint_continue(spint)
+Spint *spint;
+{
+    _spint_continue(spint);            /* Return to caller */
+    spint_finish(spint);
+}
 
 
 void
 
 
 void
-do_spawn(command, spawn)
+spint_start(command, spint)
 char *command;
 char *command;
-Spawn *spawn;
+Spint *spint;
 {
     ExecList mylist;
     char *comspec;
 {
     ExecList mylist;
     char *comspec;
-    void int_spawn();
-    int int_offset, int_segment;
+    void _spint_int();
+    union REGS regs;
+    struct SREGS sregs;
 
     /*
      * Get comspec.
 
     /*
      * Get comspec.
@@ -48,8 +106,8 @@ Spawn *spawn;
     comspec = getenv("COMSPEC");
     if (comspec == 0) {                        /* Can't find where command.com is */
        fprintf(stderr, "Unable to find COMSPEC in the environment.");
     comspec = getenv("COMSPEC");
     if (comspec == 0) {                        /* Can't find where command.com is */
        fprintf(stderr, "Unable to find COMSPEC in the environment.");
-       spawn->done = 1;
-       spawn->rc = 99; /* XXX */
+       spint->done = 1;
+       spint->rc = 99; /* XXX */
        return;
     }
 
        return;
     }
 
@@ -57,36 +115,36 @@ Spawn *spawn;
      * Now, hook up our interrupt routine.
      */
 
      * Now, hook up our interrupt routine.
      */
 
-    spawn->regs.h.ah = 0x35;
-    spawn->regs.h.al = spawn->int_no;
-    intdosx(&spawn->regs, &spawn->regs, &spawn->sregs);
+    regs.h.ah = 0x35;
+    regs.h.al = spint->int_no;
+    intdosx(&regs, &regs, &sregs);
 
     /* Save old routine */
 
     /* Save old routine */
-    int_offset = spawn->regs.x.bx;
-    int_segment = spawn->sregs.es;
+    int_offset = regs.x.bx;
+    int_segment = sregs.es;
 
 
-    spawn->regs.h.ah = 0x25;
-    spawn->regs.h.al = spawn->int_no;
-    spawn->regs.x.dx = (int) int_spawn;
-    segread(&spawn->sregs);
-    spawn->sregs.ds = spawn->sregs.cs;
-    intdosx(&spawn->regs, &spawn->regs, &spawn->sregs);
+    regs.h.ah = 0x25;
+    regs.h.al = spint->int_no;
+    regs.x.dx = (int) _spint_int;
+    segread(&sregs);
+    sregs.ds = sregs.cs;
+    intdosx(&regs, &regs, &sregs);
 
     /*
      * Read in segment registers.
      */
 
 
     /*
      * Read in segment registers.
      */
 
-    segread(&spawn->sregs);
+    segread(&spint->sregs);
 
     /*
      * Set up registers for the EXEC call.
      */
 
 
     /*
      * Set up registers for the EXEC call.
      */
 
-    spawn->regs.h.ah = 0x4b;
-    spawn->regs.h.al = 0;
-    spawn->regs.x.dx = (int) comspec;
-    spawn->sregs.es = spawn->sregs.ds;         /* Superfluous, probably */
-    spawn->regs.x.bx = (int) &mylist;
+    spint->regs.h.ah = 0x4b;
+    spint->regs.h.al = 0;
+    spint->regs.x.dx = (int) comspec;
+    spint->sregs.es = spint->sregs.ds;         /* Superfluous, probably */
+    spint->regs.x.bx = (int) &mylist;
 
     /*
      * Set up EXEC parameter list.
 
     /*
      * Set up EXEC parameter list.
@@ -94,7 +152,7 @@ Spawn *spawn;
 
     ClearElement(mylist);
     mylist.cmd_ptr_offset = (int) command;
 
     ClearElement(mylist);
     mylist.cmd_ptr_offset = (int) command;
-    mylist.cmd_ptr_segment = spawn->sregs.ds;
+    mylist.cmd_ptr_segment = spint->sregs.ds;
     mylist.fcb1_ptr_offset = PSP_FCB1;
     mylist.fcb1_ptr_segment = _psp;
     mylist.fcb2_ptr_offset = PSP_FCB2;
     mylist.fcb1_ptr_offset = PSP_FCB1;
     mylist.fcb1_ptr_segment = _psp;
     mylist.fcb2_ptr_offset = PSP_FCB2;
@@ -103,112 +161,10 @@ Spawn *spawn;
 
     /*
      * Call to assembly language routine to actually set up for
 
     /*
      * Call to assembly language routine to actually set up for
-     * the spawn.
-     */
-
-    start_spawn(spawn);
-    spawn->done = 1;                   /* XXX */
-
-    if (spawn->done == 0) {
-       return;                         /* Not done yet */
-    }
-
-    if (spawn->regs.x.cflag) {
-       fprintf(stderr, "0x%x return code from EXEC.\n", spawn->regs.x.ax);
-       spawn->done = 1;
-       spawn->rc = 99;
-       return;
-    }
-
-    spawn->regs.h.ah = 0x4d;                   /* Get return code */
-
-    intdos(&spawn->regs, &spawn->regs);
-
-    spawn->rc = spawn->regs.x.ax;
-
-    /*
-     * Restore old interrupt handler.
+     * the spint.
      */
 
      */
 
-    spawn->regs.h.ah = 0x25;
-    spawn->regs.h.al = spawn->int_no;
-    spawn->regs.x.dx = int_offset;
-    spawn->sregs.ds = int_segment;
-    intdosx(&spawn->regs, &spawn->regs, &spawn->sregs);
-}
-
-main(argc, argv, envp)
-int    argc;                           /* Number of passed arguments */
-char   *argv[];                        /* Arguments passed */
-char   *envp[];                        /* Inherited environment */
-{
-    Spawn spawned;
-    static char command[256];
-
-    ClearElement(spawned);
-    spawned.int_no = INTERRUPT_NUMBER;
-    if (argc == 1) {
-       command[0] = 0;
-    } else {
-       char *cmdptr;
-       int length;
-
-       argc--;
-       argv++;
-       strcpy(command, " /c");
-       cmdptr = command+strlen(command);
-       while (argc) {
-           if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) {
-               fprintf(stderr, "Argument list too long at argument *%s*.\n",
-                           *argv);
-               return 0;
-           }
-           *cmdptr++ = ' ';            /* Blank separators */
-           strcpy(cmdptr, *argv);
-           cmdptr += strlen(cmdptr);
-           argc--;
-           argv++;
-       }
-       length = strlen(command)-1;
-       if (length < 0) {
-           length = 0;
-       }
-       command[0] = length;
-    }
+    _spint_start(spint);
 
 
-    /*
-     * do_spawn returns when either the command has finished, or when
-     * the required interrupt comes in.  In the latter case, the appropriate
-     * thing to do is to process the interrupt, and then return to
-     * the interrupt issuer.
-     */
-    do_spawn(command, &spawned);
-    if (spawned.done == 0) {
-       /* Process request */
-       switch (spawned.regs.h.ah) {
-       case 1:                 /* Add */
-           spawned.regs.x.cx += spawned.regs.x.dx;
-           break;
-       case 2:                 /* Subtract */
-           spawned.regs.x.cx -= spawned.regs.x.dx;
-           break;
-       case 3:                 /* Multiply */
-           spawned.regs.x.cx *= spawned.regs.x.dx;
-           break;
-       case 4:                 /* Divide */
-           spawned.regs.x.cx /= spawned.regs.x.dx;
-           break;
-       default:
-           spawned.regs.h.al = -1;     /* Error */
-           spawned.regs.x.cflag = 1;
-           break;
-       }
-       continue_spawn(&spawned);
-       /*NOTREACHED*/
-       /* continue_spawn() causes an eventual return from do_spawn. */
-    }
-    if (spawned.rc != 0) {
-       fprintf(stderr, "Process generated a return code of 0x%x.\n",
-                                                               spawned.rc);
-    }
+    spint_finish(spint);
 }
 }