1*31151Sminshall #define LINT_ARGS 2*31151Sminshall 3*31151Sminshall #include <stdio.h> 4*31151Sminshall #include <dos.h> 5*31151Sminshall #include <stdlib.h> 6*31151Sminshall 7*31151Sminshall #include "../ntn3270/general.h" 8*31151Sminshall 9*31151Sminshall #define PSP_ENVIRONMENT 0x2c 10*31151Sminshall #define PSP_FCB1 0x5c 11*31151Sminshall #define PSP_FCB2 0x6c 12*31151Sminshall 13*31151Sminshall #define INTERRUPT_NUMBER 73 14*31151Sminshall 15*31151Sminshall typedef struct { 16*31151Sminshall int 17*31151Sminshall environment, /* Segment address of environment */ 18*31151Sminshall cmd_ptr_offset, /* Offset of command to execute */ 19*31151Sminshall cmd_ptr_segment, /* Segment where command lives */ 20*31151Sminshall fcb1_ptr_offset, /* Offset of FCB 1 */ 21*31151Sminshall fcb1_ptr_segment, /* Segment of FCB 1 */ 22*31151Sminshall fcb2_ptr_offset, /* Offset of FCB 2 */ 23*31151Sminshall fcb2_ptr_segment; /* Segment of FCB 2 */ 24*31151Sminshall } ExecList; 25*31151Sminshall 26*31151Sminshall typedef struct { 27*31151Sminshall union REGS regs; 28*31151Sminshall struct SREGS sregs; 29*31151Sminshall int int_no; /* Which interrupt to wait on */ 30*31151Sminshall int done; /* Are we done, or just took an interrupt? */ 31*31151Sminshall int rc; /* return code */ 32*31151Sminshall } Spawn; 33*31151Sminshall 34*31151Sminshall 35*31151Sminshall void 36*31151Sminshall do_spawn(command, spawn) 37*31151Sminshall char *command; 38*31151Sminshall Spawn *spawn; 39*31151Sminshall { 40*31151Sminshall ExecList mylist; 41*31151Sminshall char *comspec; 42*31151Sminshall void int_spawn(); 43*31151Sminshall int int_offset, int_segment; 44*31151Sminshall 45*31151Sminshall /* 46*31151Sminshall * Get comspec. 47*31151Sminshall */ 48*31151Sminshall comspec = getenv("COMSPEC"); 49*31151Sminshall if (comspec == 0) { /* Can't find where command.com is */ 50*31151Sminshall fprintf(stderr, "Unable to find COMSPEC in the environment."); 51*31151Sminshall spawn->done = 1; 52*31151Sminshall spawn->rc = 99; /* XXX */ 53*31151Sminshall return; 54*31151Sminshall } 55*31151Sminshall 56*31151Sminshall /* 57*31151Sminshall * Now, hook up our interrupt routine. 58*31151Sminshall */ 59*31151Sminshall 60*31151Sminshall spawn->regs.h.ah = 0x35; 61*31151Sminshall spawn->regs.h.al = spawn->int_no; 62*31151Sminshall intdosx(&spawn->regs, &spawn->regs, &spawn->sregs); 63*31151Sminshall 64*31151Sminshall /* Save old routine */ 65*31151Sminshall int_offset = spawn->regs.x.bx; 66*31151Sminshall int_segment = spawn->sregs.es; 67*31151Sminshall 68*31151Sminshall spawn->regs.h.ah = 0x25; 69*31151Sminshall spawn->regs.h.al = spawn->int_no; 70*31151Sminshall spawn->regs.x.dx = (int) int_spawn; 71*31151Sminshall segread(&spawn->sregs); 72*31151Sminshall spawn->sregs.ds = spawn->sregs.cs; 73*31151Sminshall intdosx(&spawn->regs, &spawn->regs, &spawn->sregs); 74*31151Sminshall 75*31151Sminshall /* 76*31151Sminshall * Read in segment registers. 77*31151Sminshall */ 78*31151Sminshall 79*31151Sminshall segread(&spawn->sregs); 80*31151Sminshall 81*31151Sminshall /* 82*31151Sminshall * Set up registers for the EXEC call. 83*31151Sminshall */ 84*31151Sminshall 85*31151Sminshall spawn->regs.h.ah = 0x4b; 86*31151Sminshall spawn->regs.h.al = 0; 87*31151Sminshall spawn->regs.x.dx = (int) comspec; 88*31151Sminshall spawn->sregs.es = spawn->sregs.ds; /* Superfluous, probably */ 89*31151Sminshall spawn->regs.x.bx = (int) &mylist; 90*31151Sminshall 91*31151Sminshall /* 92*31151Sminshall * Set up EXEC parameter list. 93*31151Sminshall */ 94*31151Sminshall 95*31151Sminshall ClearElement(mylist); 96*31151Sminshall mylist.cmd_ptr_offset = (int) command; 97*31151Sminshall mylist.cmd_ptr_segment = spawn->sregs.ds; 98*31151Sminshall mylist.fcb1_ptr_offset = PSP_FCB1; 99*31151Sminshall mylist.fcb1_ptr_segment = _psp; 100*31151Sminshall mylist.fcb2_ptr_offset = PSP_FCB2; 101*31151Sminshall mylist.fcb2_ptr_segment = _psp; 102*31151Sminshall mylist.environment = *((int far *)(((long)_psp<<16)|PSP_ENVIRONMENT)); 103*31151Sminshall 104*31151Sminshall /* 105*31151Sminshall * Call to assembly language routine to actually set up for 106*31151Sminshall * the spawn. 107*31151Sminshall */ 108*31151Sminshall 109*31151Sminshall start_spawn(spawn); 110*31151Sminshall spawn->done = 1; /* XXX */ 111*31151Sminshall 112*31151Sminshall if (spawn->done == 0) { 113*31151Sminshall return; /* Not done yet */ 114*31151Sminshall } 115*31151Sminshall 116*31151Sminshall if (spawn->regs.x.cflag) { 117*31151Sminshall fprintf(stderr, "0x%x return code from EXEC.\n", spawn->regs.x.ax); 118*31151Sminshall spawn->done = 1; 119*31151Sminshall spawn->rc = 99; 120*31151Sminshall return; 121*31151Sminshall } 122*31151Sminshall 123*31151Sminshall spawn->regs.h.ah = 0x4d; /* Get return code */ 124*31151Sminshall 125*31151Sminshall intdos(&spawn->regs, &spawn->regs); 126*31151Sminshall 127*31151Sminshall spawn->rc = spawn->regs.x.ax; 128*31151Sminshall 129*31151Sminshall /* 130*31151Sminshall * Restore old interrupt handler. 131*31151Sminshall */ 132*31151Sminshall 133*31151Sminshall spawn->regs.h.ah = 0x25; 134*31151Sminshall spawn->regs.h.al = spawn->int_no; 135*31151Sminshall spawn->regs.x.dx = int_offset; 136*31151Sminshall spawn->sregs.ds = int_segment; 137*31151Sminshall intdosx(&spawn->regs, &spawn->regs, &spawn->sregs); 138*31151Sminshall } 139*31151Sminshall 140*31151Sminshall main(argc, argv, envp) 141*31151Sminshall int argc; /* Number of passed arguments */ 142*31151Sminshall char *argv[]; /* Arguments passed */ 143*31151Sminshall char *envp[]; /* Inherited environment */ 144*31151Sminshall { 145*31151Sminshall Spawn spawned; 146*31151Sminshall static char command[256]; 147*31151Sminshall 148*31151Sminshall ClearElement(spawned); 149*31151Sminshall spawned.int_no = INTERRUPT_NUMBER; 150*31151Sminshall if (argc == 1) { 151*31151Sminshall command[0] = 0; 152*31151Sminshall } else { 153*31151Sminshall char *cmdptr; 154*31151Sminshall int length; 155*31151Sminshall 156*31151Sminshall argc--; 157*31151Sminshall argv++; 158*31151Sminshall strcpy(command, " /c"); 159*31151Sminshall cmdptr = command+strlen(command); 160*31151Sminshall while (argc) { 161*31151Sminshall if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) { 162*31151Sminshall fprintf(stderr, "Argument list too long at argument *%s*.\n", 163*31151Sminshall *argv); 164*31151Sminshall return 0; 165*31151Sminshall } 166*31151Sminshall *cmdptr++ = ' '; /* Blank separators */ 167*31151Sminshall strcpy(cmdptr, *argv); 168*31151Sminshall cmdptr += strlen(cmdptr); 169*31151Sminshall argc--; 170*31151Sminshall argv++; 171*31151Sminshall } 172*31151Sminshall length = strlen(command)-1; 173*31151Sminshall if (length < 0) { 174*31151Sminshall length = 0; 175*31151Sminshall } 176*31151Sminshall command[0] = length; 177*31151Sminshall } 178*31151Sminshall 179*31151Sminshall /* 180*31151Sminshall * do_spawn returns when either the command has finished, or when 181*31151Sminshall * the required interrupt comes in. In the latter case, the appropriate 182*31151Sminshall * thing to do is to process the interrupt, and then return to 183*31151Sminshall * the interrupt issuer. 184*31151Sminshall */ 185*31151Sminshall do_spawn(command, &spawned); 186*31151Sminshall if (spawned.done == 0) { 187*31151Sminshall /* Process request */ 188*31151Sminshall switch (spawned.regs.h.ah) { 189*31151Sminshall case 1: /* Add */ 190*31151Sminshall spawned.regs.x.cx += spawned.regs.x.dx; 191*31151Sminshall break; 192*31151Sminshall case 2: /* Subtract */ 193*31151Sminshall spawned.regs.x.cx -= spawned.regs.x.dx; 194*31151Sminshall break; 195*31151Sminshall case 3: /* Multiply */ 196*31151Sminshall spawned.regs.x.cx *= spawned.regs.x.dx; 197*31151Sminshall break; 198*31151Sminshall case 4: /* Divide */ 199*31151Sminshall spawned.regs.x.cx /= spawned.regs.x.dx; 200*31151Sminshall break; 201*31151Sminshall default: 202*31151Sminshall spawned.regs.h.al = -1; /* Error */ 203*31151Sminshall spawned.regs.x.cflag = 1; 204*31151Sminshall break; 205*31151Sminshall } 206*31151Sminshall continue_spawn(&spawned); 207*31151Sminshall /*NOTREACHED*/ 208*31151Sminshall /* continue_spawn() causes an eventual return from do_spawn. */ 209*31151Sminshall } 210*31151Sminshall if (spawned.rc != 0) { 211*31151Sminshall fprintf(stderr, "Process generated a return code of 0x%x.\n", 212*31151Sminshall spawned.rc); 213*31151Sminshall } 214*31151Sminshall } 215