home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / SH162_2X.ZIP / PATCHES.OS2 < prev    next >
Text File  |  1990-08-17  |  70KB  |  2,848 lines

  1. Only in sh-os2: newfiles.os2
  2. Only in sh-os2: patches.os2
  3. Only in sh-os2: changes.h
  4. Only in sh-os2: dir.h
  5. Only in sh-os2: dir_os2.c
  6. Only in sh-os2: jobs.c
  7. Only in sh-os2: sh.cs
  8. Only in sh-os2: sh.def
  9. diff -cbBw sh-dos/sh.h sh-os2/sh.h
  10. *** sh-dos/sh.h    Thu Jul 05 19:50:16 1990
  11. --- sh-os2/sh.h    Sat Aug 04 17:41:46 1990
  12. ***************
  13. *** 81,91 ****
  14.    */
  15.   
  16.   #define PATCHLEVEL    6
  17. ! #define    LINE_MAX    1000    /* Command line length            */
  18.   #define HISTORY_MAX    100    /* History array length            */
  19.                   /* Space for full file name        */
  20.   #define FFNAME_MAX    (PATH_MAX + NAME_MAX + 4)
  21. ! #define CMD_LINE_MAX    127    /* Max command line length        */
  22.   #define SSAVE_IO_SIZE    4    /* Save IO array malloc increment    */
  23.   
  24.   #define    NPUSH        8    /* limit to input nesting        */
  25. --- 81,91 ----
  26.    */
  27.   
  28.   #define PATCHLEVEL    6
  29. ! #define    LINE_MAX    1024    /* Command line length            */
  30.   #define HISTORY_MAX    100    /* History array length            */
  31.                   /* Space for full file name        */
  32.   #define FFNAME_MAX    (PATH_MAX + NAME_MAX + 4)
  33. ! #define CMD_LINE_MAX    2048    /* Max command line length        */
  34.   #define SSAVE_IO_SIZE    4    /* Save IO array malloc increment    */
  35.   
  36.   #define    NPUSH        8    /* limit to input nesting        */
  37. ***************
  38. *** 98,103 ****
  39. --- 98,105 ----
  40.   #define SP        ' '
  41.   #define    NOT        '^'
  42.   
  43. + #define BATCHEXT        ".cmd"
  44.   /* Here we introduce a new boolean value - MAYBE.  This is required for
  45.    * a special case of the grave function
  46.    */
  47. ***************
  48. *** 171,216 ****
  49.   
  50.   #define    FEXEC        0x0001    /* execute without forking        */
  51.   
  52. - /* MSDOS Memory Control Block chain structure */
  53. - #pragma pack (1)
  54. - struct MCB_list    {
  55. -     char        MCB_type;    /* M or Z            */
  56. -     unsigned int    MCB_pid;    /* Process ID            */
  57. -     unsigned int    MCB_len;    /* MCB length            */
  58. - };
  59. - #pragma pack ()
  60. - #define MCB_CON        'M'        /* More MCB's            */
  61. - #define MCB_END        'Z'        /* Last MCB's            */
  62. - /* Externs for Swapper assembler function */
  63. - extern char        cmd_line[];    /* Command line            */
  64. - extern char        path_line[];    /* Process path            */
  65.   extern unsigned int    SW_intr;    /* interrupt pending        */
  66. - extern unsigned int    SW_Blocks;    /* Number of blocks to read    */
  67. - extern unsigned int    SW_SBlocks;    /* Short Number of blocks to    */
  68. -                     /* read                */
  69. - extern int        SW_fp;        /* File or EMS Handler        */
  70. - extern int        SW_Pwrite;    /* Partial write to disk?    */
  71. - extern unsigned long    SW_EMstart;    /* Start addr of extend mem    */
  72. - extern unsigned int    SW_Mode;    /* Type of swapping to do    */
  73. -                     /* 1 - disk            */
  74. -                     /* 2 - Extended    memory        */
  75. -                     /* 3 - EMS Driver        */
  76. -                     /* 4 - XMS Driver        */
  77. - extern unsigned int    SW_EMSFrame;    /* EMS Frame segment        */
  78. - extern unsigned int    etext;        /* End of text segment        */
  79. - extern int        Swap_Mode;    /* Swapping mode        */
  80. - /* If you change these values, change sh7, swap_device as well */
  81. - #define SWAP_OFF    0x0000        /* No swapping            */
  82. - #define SWAP_DISK    0x0001        /* Disk only            */
  83. - #define SWAP_EXTEND    0x0002        /* Extended memory        */
  84. - #define SWAP_EXPAND    0x0004        /* Expanded memory        */
  85.   
  86.   /*
  87.    * flags to control evaluation of words
  88. --- 173,179 ----
  89. ***************
  90. *** 569,574 ****
  91. --- 532,538 ----
  92.   extern bool    eqname (char *, char *);
  93.   extern bool    any (char, char *);
  94.   extern int    (*inbuilt (char *))();
  95. + extern char     *cmd_internal(char *s);
  96.   extern char    *path_append (char *, char *, char *);
  97.   extern void    unset (char *, bool);
  98.   extern int    S_open (bool, char *, int, ...);
  99. ***************
  100. *** 621,641 ****
  101.   extern void    Clear_Extended_File (void);
  102.   extern void    Print_Version (int);
  103.   extern bool    anys (char *, char *);
  104. - extern void    Clear_Swap_File (void);
  105. - /*
  106. -  * Interrupt handling
  107. -  */
  108. - extern void interrupt    SW_Int24 (void);    /* Int 24 New address    */
  109. - extern void (interrupt far *SW_I0_V) (void);    /* Int 0 address    */
  110. - extern void (interrupt far *SW_I23_V) (void);    /* Int 23 address    */
  111. - /*
  112. -  * XMS Driver functions
  113. -  */
  114. - extern void (far *SW_XMS_Driver) (void);    /* XMS Driver Interface    */
  115. - extern int        SW_XMS_Gversion (void);
  116. - extern int        SW_XMS_Allocate (unsigned int);
  117. - extern int        SW_XMS_Free (int);
  118. --- 585,587 ----
  119. diff -cbBw sh-dos/sh1.c sh-os2/sh1.c
  120. *** sh-dos/sh1.c    Thu Jul 05 19:50:22 1990
  121. --- sh-os2/sh1.c    Sat Aug 04 13:47:40 1990
  122. ***************
  123. *** 87,92 ****
  124. --- 87,97 ----
  125.   #include <time.h>
  126.   #include "sh.h"
  127.   
  128. + #define INCL_NOPM
  129. + #define INCL_DOSPROCESS
  130. + #define INCL_DOSERRORS
  131. + #include <os2.h>
  132.   /*
  133.    * Structure of Malloced space to allow release of space nolonger required
  134.    * without having to know about it.
  135. ***************
  136. *** 109,116 ****
  137.   static char    *Path       = "PATH";
  138.                   /* Entry directory            */
  139.   static char    *Start_directory = (char *)NULL;
  140. -                     /* Original Interrupt 24 address */
  141. - static void    (interrupt far *Orig_I24_V) (void);
  142.   #ifdef SIGQUIT
  143.   static void    (*qflag)(int) = SIG_IGN;
  144.   #endif
  145. --- 114,119 ----
  146. ***************
  147. *** 128,133 ****
  148. --- 131,139 ----
  149.   static void    Convert_Backslashes (char *);
  150.   static void    Load_profiles (void);
  151.   static void    U2D_Path (void);
  152. + static void     dowaits(int);
  153. + unsigned int SW_intr;
  154.   
  155.   /*
  156.    * The main program starts here
  157. ***************
  158. *** 307,312 ****
  159. --- 313,320 ----
  160.       }
  161.   
  162.       onecommand ();
  163. +         dowaits(0);  /* wait for ending async. processes */
  164.       }
  165.   }
  166.   
  167. ***************
  168. *** 460,465 ****
  169. --- 468,524 ----
  170.       }
  171.   }
  172.   
  173. + /*
  174. +  * look for any ending childs
  175. +  */
  176. + static void dowaits(int mode)
  177. + {
  178. +   RESULTCODES rc;
  179. +   PID pid;
  180. +   char buffer[32];
  181. +   USHORT res;
  182. +   USHORT wmode = DCWW_NOWAIT;
  183. +   for (;;)
  184. +   {
  185. +     res = DosCwait(DCWA_PROCESS, wmode, &rc, &pid, 0);
  186. +     if ( mode && (res == ERROR_CHILD_NOT_COMPLETE) )
  187. +     {
  188. +       S_puts("(Waiting for childs)\n");
  189. +       wmode = DCWW_WAIT;
  190. +       continue;
  191. +     }
  192. +     else
  193. +       if ( res )
  194. +         break;
  195. +     sprintf(buffer, "[%u] ", pid);
  196. +     S_puts(buffer);
  197. +     switch (rc.codeTerminate)
  198. +     {
  199. +     case TC_EXIT:
  200. +       sprintf(buffer, "Done (%u)\n", rc.codeResult);
  201. +       S_puts(buffer);
  202. +       break;
  203. +     case TC_HARDERROR:
  204. +       S_puts("Terminated\n");
  205. +       break;
  206. +     case TC_TRAP:
  207. +       sprintf(buffer, "Trap %d\n", rc.codeResult);
  208. +       S_puts(buffer);
  209. +       break;
  210. +     case TC_KILLPROCESS:
  211. +       S_puts("Killed\n");
  212. +       break;
  213. +     }
  214. +   }
  215. + }
  216.   /*
  217.    * Terminate current environment with an error
  218.    */
  219. ***************
  220. *** 480,490 ****
  221. --- 539,551 ----
  222.       if (execflg)
  223.       fail ();
  224.   
  225. + #if 0
  226.       if (Orig_I24_V == (void (far *)())NULL)
  227.       {
  228.       S_puts ("sh: ignoring attempt to leave lowest level shell\n");
  229.       fail ();
  230.       }
  231. + #endif
  232.   
  233.   /* Clean up */
  234.   
  235. ***************
  236. *** 495,500 ****
  237. --- 556,565 ----
  238.   
  239.       runtrap (0);
  240.   
  241. + /* wait for running bg processes */
  242. +     dowaits(1);
  243.   /* Dump history on exit */
  244.   
  245.   #ifndef NO_HISTORY
  246. ***************
  247. *** 504,513 ****
  248.   
  249.       closeall ();
  250.   
  251. - /* Clear swap file if necessary */
  252. -     Clear_Swap_File ();
  253.   /* If this is a command only - restore the directory because DOS doesn't
  254.    * and the user might expect it
  255.    */
  256. --- 569,574 ----
  257. ***************
  258. *** 1439,1453 ****
  259.   void    put_prompt (s)
  260.   char    *s;
  261.   {
  262. !     struct dosdate_t     d_date;
  263. !     struct dostime_t    d_time;
  264.       int            i;
  265.       char        buf[PATH_MAX + 4];
  266.   
  267.       last_prompt = s;        /* Save the Last prompt output        */
  268.   
  269. !     _dos_gettime (&d_time);    /* Get the date and time in case    */
  270. !     _dos_getdate (&d_date);
  271.   
  272.       while (*s)
  273.       {
  274. --- 1500,1514 ----
  275.   void    put_prompt (s)
  276.   char    *s;
  277.   {
  278. !     time_t ti;
  279. !     struct tm *tl;
  280.       int    i;
  281.       char buf[PATH_MAX + 4];
  282.   
  283.       last_prompt = s;        /* Save the Last prompt output        */
  284.   
  285. !     time(&ti);
  286. !     tl = localtime(&ti);
  287.   
  288.       while (*s)
  289.       {
  290. ***************
  291. *** 1475,1487 ****
  292.               break;
  293.   
  294.               case 't':            /* time        */
  295. !             sprintf (buf,"%.2d:%.2d", d_time.hour, d_time.minute);
  296.               break;
  297.   
  298.               case 'd':            /* date        */
  299.               sprintf (buf, "%.3s %.2d-%.2d-%.2d",
  300. !                  &"SunMonTueWedThuFriSat"[d_date.dayofweek * 3],
  301. !                  d_date.day, d_date.month, d_date.year % 100);
  302.               break;
  303.   
  304.               case 'p':            /* directory    */
  305. --- 1536,1548 ----
  306.               break;
  307.   
  308.               case 't':            /* time        */
  309. !             sprintf (buf,"%.2d:%.2d", tl -> tm_hour, tl -> tm_min);
  310.               break;
  311.   
  312.               case 'd':            /* date        */
  313.               sprintf (buf, "%.3s %.2d-%.2d-%.2d",
  314. !                  &"SunMonTueWedThuFriSat"[tl -> tm_wday * 3],
  315. !                  tl -> tm_mday, tl -> tm_mon, tl -> tm_year % 100);
  316.               break;
  317.   
  318.               case 'p':            /* directory    */
  319. ***************
  320. *** 1494,1500 ****
  321.               break;
  322.   
  323.               case 'v':            /* version        */
  324. !             sprintf (buf, "MS-DOS %.2d:%.2d", _osmajor, _osminor);
  325.               break;
  326.           }
  327.   
  328. --- 1555,1561 ----
  329.               break;
  330.   
  331.               case 'v':            /* version        */
  332. !             sprintf (buf, "%.2d.%.2d", _osmajor, _osminor);
  333.               break;
  334.           }
  335.   
  336. ***************
  337. *** 1552,1558 ****
  338.   {
  339.       register char    *s, *s1;
  340.       char        **ap;
  341. !     Var_List        *lset;
  342.       bool        l_rflag = FALSE;
  343.   
  344.   /* Patch the ctype table as a cheat */
  345. --- 1613,1619 ----
  346.   {
  347.       register char    *s, *s1;
  348.       char        **ap;
  349. !     Var_List        *lset, *init;
  350.       bool        l_rflag = FALSE;
  351.   
  352.   /* Patch the ctype table as a cheat */
  353. ***************
  354. *** 1563,1571 ****
  355.    * address
  356.    */
  357.   
  358. -     Orig_I24_V = _dos_getvect (0x24);
  359. -     _dos_setvect (0x24, SW_Int24);
  360.   /* Load the environment into our structures */
  361.   
  362.       if ((ap = environ) != (char **)NULL)
  363. --- 1624,1629 ----
  364. ***************
  365. *** 1642,1647 ****
  366. --- 1700,1708 ----
  367.   /* Set up home directory */
  368.   
  369.       if ((lset = lookup (home, TRUE))->value == null)
  370. +       if ((init = lookup ("INIT", TRUE))->value != null)
  371. +     setval (lset, init->value);
  372. +       else
  373.       setval (lset, C_dir->value);
  374.   
  375.       s_vstatus (lset, EXPORT);
  376. ***************
  377. *** 1663,1669 ****
  378.       setval (ifs, " \t\n");
  379.   
  380.       if (ps1->value == null)
  381. !     setval (ps1, "$ ");
  382.   
  383.       if (ps2->value == null)
  384.       setval (ps2, "> ");
  385. --- 1724,1730 ----
  386.       setval (ifs, " \t\n");
  387.   
  388.       if (ps1->value == null)
  389. !     setval (ps1, "%e$ ");
  390.   
  391.       if (ps2->value == null)
  392.       setval (ps2, "> ");
  393. ***************
  394. *** 1765,1772 ****
  395.   static void    Pre_Process_Argv (argv)
  396.   char        **argv;
  397.   {
  398. !     char    *ocl = (char far *)((((long)_psp) << 16) + 0x081L);
  399.   
  400.   
  401.   /* Check for these options */
  402.   
  403. --- 1826,1836 ----
  404.   static void    Pre_Process_Argv (argv)
  405.   char        **argv;
  406.   {
  407. !     extern      char far *_pgmptr;
  408. !     char    *ocl = _pgmptr;
  409.   
  410. +     ocl = strchr(ocl, 0) + 1;
  411. +     ocl = strchr(ocl, 0) + 1;
  412.   
  413.   /* Check for these options */
  414.   
  415. ***************
  416. *** 1834,1839 ****
  417. --- 1898,1904 ----
  418.   {
  419.       char    *name;
  420.       int        f;
  421. +     char        prof[128], *env;
  422.   
  423.   /* Set up home profile */
  424.   
  425. ***************
  426. *** 1852,1857 ****
  427. --- 1917,1936 ----
  428.       {
  429.       PUSHIO (afile, remap (f), filechar);
  430.       }
  431. +     if ( (env = getenv("INIT")) != NULL )
  432. +       if ((f = O_for_execute (strcat(strcpy(prof, env), "/profile"),
  433. +                               (char **)NULL, (int *)NULL)) >= 0)
  434. +       {
  435. +           PUSHIO (afile, remap (f), filechar);
  436. +       }
  437. +     if ( (env = getenv("HOME")) != NULL )
  438. +       if ((f = O_for_execute (strcat(strcpy(prof, env), "/profile"),
  439. +                               (char **)NULL, (int *)NULL)) >= 0)
  440. +       {
  441. +           PUSHIO (afile, remap (f), filechar);
  442. +       }
  443.   }
  444.   
  445.   /*
  446. diff -cbBw sh-dos/sh2.c sh-os2/sh2.c
  447. *** sh-dos/sh2.c    Mon May 21 20:12:06 1990
  448. --- sh-os2/sh2.c    Thu Jul 05 19:55:04 1990
  449. ***************
  450. *** 36,41 ****
  451. --- 36,42 ----
  452.   
  453.   #include <sys/types.h>
  454.   #include <stddef.h>
  455. + #include <stdio.h>
  456.   #include <signal.h>
  457.   #include <errno.h>
  458.   #include <setjmp.h>
  459. diff -cbBw sh-dos/sh3.c sh-os2/sh3.c
  460. *** sh-dos/sh3.c    Thu Jul 05 19:50:26 1990
  461. --- sh-os2/sh3.c    Sat Aug 04 18:29:58 1990
  462. ***************
  463. *** 97,103 ****
  464.   #include <sys/stat.h>
  465.   #include <stdio.h>
  466.   #include <process.h>
  467. - #include <dos.h>
  468.   #include <signal.h>
  469.   #include <errno.h>
  470.   #include <setjmp.h>
  471. --- 97,102 ----
  472. ***************
  473. *** 107,117 ****
  474.   #include <stdlib.h>
  475.   #include <fcntl.h>
  476.   #include <limits.h>
  477. ! #include <dirent.h>
  478.   #include <ctype.h>
  479.   
  480.   #include "sh.h"
  481.   
  482.   /* static Function and string declarations */
  483.   
  484.   static int    forkexec (C_Op *, int, int, int, char **);
  485. --- 106,120 ----
  486.   #include <stdlib.h>
  487.   #include <fcntl.h>
  488.   #include <limits.h>
  489. ! #include <dir.h>
  490.   #include <ctype.h>
  491.   
  492.   #include "sh.h"
  493.   
  494. + #define INCL_NOPM
  495. + #define INCL_DOS
  496. + #include <os2.h>
  497.   /* static Function and string declarations */
  498.   
  499.   static int    forkexec (C_Op *, int, int, int, char **);
  500. ***************
  501. *** 122,133 ****
  502.   static int    rexecve (char *, char **, char **, bool);
  503.   static int    Execute_program (char *, char **, char **, bool);
  504.   static int    S_spawnve (char *, char **, char **);
  505. - static bool    Get_EMS_Driver (void);
  506. - static bool    Get_XMS_Driver (void);
  507. - static bool    EMS_error (char *, int);
  508. - static int    EMS_Close (void);
  509. - static bool    XMS_error (char *, int);
  510. - static int    XMS_Close (void);
  511.   static int    build_command_line (char *, char **, char **);
  512.   static int    setstatus (int);
  513.   static bool    Check_for_bat_file (char *);
  514. --- 125,130 ----
  515. ***************
  516. *** 134,145 ****
  517.   static size_t    white_space_len (char *, bool *);
  518.   static char    *Gen_Full_Path_Name (char *);
  519.   
  520.   static char    *AE2big = "arg/env list too big";
  521. - static char    *EMS_emsg = "Warning: EMS Error (%x)\n";
  522. - static char    *XMS_emsg = "Warning: XMS Error (%x)\n";
  523.               /* Extended Command line processing file name    */
  524.   static char        *Extend_file = (char *)NULL;
  525. - static char        *Swap_File = (char *)NULL;    /* Swap file    */
  526.   
  527.   /*
  528.    * execute tree recursively
  529. --- 131,141 ----
  530.   static size_t    white_space_len (char *, bool *);
  531.   static char    *Gen_Full_Path_Name (char *);
  532.   
  533. + static int      spawnmode = P_WAIT;
  534.   static char    *AE2big = "arg/env list too big";
  535.               /* Extended Command line processing file name    */
  536.   static char        *Extend_file = (char *)NULL;
  537.   
  538.   /*
  539.    * execute tree recursively
  540. ***************
  541. *** 163,168 ****
  542. --- 159,165 ----
  543.       int            Local_depth;        /* Save local values    */
  544.       int            Local_areanum;
  545.       int            rv = 0;
  546. +     int                 readp, writep;
  547.   
  548.   /* End of tree ? */
  549.   
  550. ***************
  551. *** 213,219 ****
  552.           Break_List  = (Break_C *)NULL;
  553.           bc.nextlev  = SShell_List;
  554.           SShell_List = &bc;
  555. !         rv = forkexec (t, pin, pout, act, wp);
  556.           }
  557.   
  558.   /* Restore the original environment */
  559. --- 210,217 ----
  560.           Break_List  = (Break_C *)NULL;
  561.           bc.nextlev  = SShell_List;
  562.           SShell_List = &bc;
  563. !         /* rv = forkexec (t, pin, pout, act, wp); wrong! */
  564. !         rv = execute (t->left, pin, pout, act);
  565.           }
  566.   
  567.   /* Restore the original environment */
  568. ***************
  569. *** 234,251 ****
  570.           break;
  571.   
  572.       case TPIPE:            /* Pipe processing        */
  573. -         if ((rv = openpipe ()) < 0)
  574. -         break;
  575.   
  576.   /* Create pipe, execute command, reset pipe, execute the other side, close
  577.    * the pipe and fini
  578.    */
  579.           localpipe = remap (rv);
  580.           execute (t->left, pin, localpipe, 0);
  581.           lseek (localpipe, 0L, SEEK_SET);
  582.           rv = execute (t->right, localpipe, pout, 0);
  583.           closepipe (localpipe);
  584.           break;
  585.   
  586.       case TLIST:            /* Entries in a for statement    */
  587. --- 232,280 ----
  588.           break;
  589.   
  590.       case TPIPE:            /* Pipe processing        */
  591.   
  592.   /* Create pipe, execute command, reset pipe, execute the other side, close
  593.    * the pipe and fini
  594.    */
  595. !      /* old DOS version:
  596. !             if ((rv = openpipe ()) < 0)
  597. !         break;
  598.           localpipe = remap (rv);
  599.           execute (t->left, pin, localpipe, 0);
  600.           lseek (localpipe, 0L, SEEK_SET);
  601.           rv = execute (t->right, localpipe, pout, 0);
  602.           closepipe (localpipe);
  603. +          */
  604. +             if (DosMakePipe((PHFILE) &readp, (PHFILE) &writep, 0))
  605. +                 break;
  606. +         readp = remap (readp);
  607. +         writep = remap (writep);
  608. +             DosSetFHandState(readp, OPEN_FLAGS_NOINHERIT);
  609. +         DosSetFHandState(writep, OPEN_FLAGS_NOINHERIT);
  610. +             if ( spawnmode == P_WAIT )
  611. +             {
  612. +               spawnmode = P_NOWAITO;
  613. +           execute (t->left, pin, writep, 0);
  614. +               close(writep);
  615. +               spawnmode = P_NOWAIT;
  616. +           rv = execute (t->right, readp, pout, 0);
  617. +               close(readp);
  618. +               spawnmode = P_WAIT;
  619. +               cwait(&rv, rv, WAIT_GRANDCHILD);
  620. +             }
  621. +             else
  622. +             {
  623. +               rv = spawnmode;
  624. +               spawnmode = P_NOWAITO;
  625. +           execute (t->left, pin, writep, 0);
  626. +               close(writep);
  627. +               spawnmode = rv;
  628. +           rv = execute (t->right, readp, pout, 0);
  629. +               close(readp);
  630. +             }
  631.           break;
  632.   
  633.       case TLIST:            /* Entries in a for statement    */
  634. ***************
  635. *** 253,262 ****
  636.           rv = execute (t->right, pin, pout, 0);
  637.           break;
  638.   
  639. !     case TASYNC:            /* Async - not supported    */
  640. !         rv = -1;
  641.           S_puts ("sh: Async commands not supported\n");
  642.           setstatus (rv);
  643.           break;
  644.   
  645.       case TOR:            /* || and &&            */
  646. --- 282,299 ----
  647.           rv = execute (t->right, pin, pout, 0);
  648.           break;
  649.   
  650. !     case TASYNC:
  651. !      /* rv = -1;
  652.           S_puts ("sh: Async commands not supported\n");
  653.           setstatus (rv);
  654. +          */
  655. +             spawnmode = P_NOWAIT;
  656. +         rv = execute (t->left, pin, pout, 0);
  657. +             spawnmode = P_WAIT;
  658. +             S_puts("[");
  659. +             S_puts(putn(rv));
  660. +             S_puts("]\n");
  661. +             setval (lookup ("!", TRUE), putn (rv));
  662.           break;
  663.   
  664.       case TOR:            /* || and &&            */
  665. ***************
  666. *** 439,445 ****
  667.   {
  668.       unsigned int    dummy;
  669.   
  670. !     _dos_setdrive (tolower(*path) - 'a' + 1, &dummy);
  671.   
  672.       if (chdir (&path[2]) != 0)
  673.       {
  674. --- 476,482 ----
  675.   {
  676.       unsigned int    dummy;
  677.   
  678. !     DosSelectDisk(tolower(*path) - 'a' + 1);
  679.   
  680.       if (chdir (&path[2]) != 0)
  681.       {
  682. ***************
  683. *** 469,474 ****
  684. --- 506,512 ----
  685.       char    **owp = wp;
  686.       bool    spawn = FALSE;
  687.       Fun_Ops    *fop;
  688. +     char        *cmdcom = NULL;
  689.   
  690.       if (t->type == TCOM)
  691.       {
  692. ***************
  693. *** 494,501 ****
  694.   
  695.   /* Check for built in commands */
  696.   
  697. !     else if (cp != (char *)NULL)
  698. !         shcom = inbuilt (cp);
  699.       }
  700.   
  701.   /* Unix fork simulation? */
  702. --- 532,541 ----
  703.   
  704.   /* Check for built in commands */
  705.   
  706. !     else
  707. !           if (cp != (char *)NULL)
  708. !         if ( (shcom = inbuilt (cp)) == NULL )
  709. !               cmdcom = cmd_internal(cp);
  710.       }
  711.   
  712.   /* Unix fork simulation? */
  713. ***************
  714. *** 634,639 ****
  715. --- 674,682 ----
  716.   
  717.   /* Ok - execute the program */
  718.   
  719. +     if (cmdcom)
  720. +       return restore_std (rexecve (NULL, wp, makenv (), spawn), TRUE);
  721. +     else
  722.         return restore_std (rexecve (wp[0], wp, makenv (), spawn), TRUE);
  723.   }
  724.   
  725. ***************
  726. *** 860,867 ****
  727.       int            nargc = 0;        /* # script args    */
  728.       char        *p_name;        /* Program name        */
  729.       int            i;
  730. -     union REGS        r;
  731.   
  732.   /* If the environment is null - It is too big - error */
  733.   
  734.       if (envp == (char **)NULL)
  735. --- 903,917 ----
  736.       int            nargc = 0;        /* # script args    */
  737.       char        *p_name;        /* Program name        */
  738.       int            i;
  739.   
  740. + /* Count the number of arguments to the program in case of shell script or
  741. +  * bat file
  742. +  */
  743. +     while (v[argc++] != (char *)NULL);
  744. +     ++argc;                /* Including the null        */
  745.   /* If the environment is null - It is too big - error */
  746.   
  747.       if (envp == (char **)NULL)
  748. ***************
  749. *** 870,886 ****
  750.       else if ((p_name = getcell (FFNAME_MAX)) == (char *)NULL)
  751.       em = strerror (ENOMEM);
  752.   
  753. !     else
  754.       {
  755. ! /* Count the number of arguments to the program in case of shell script or
  756. !  * bat file
  757. !  */
  758. !     while (v[argc++] != (char *)NULL);
  759.   
  760. !     ++argc;                /* Including the null        */
  761.   
  762.   /* Start off on the search path for the executable file */
  763.   
  764.       sp = (any ('/', c) || (*(c + 1) == ':')) ? null : path->value;
  765. --- 920,945 ----
  766.       else if ((p_name = getcell (FFNAME_MAX)) == (char *)NULL)
  767.       em = strerror (ENOMEM);
  768.   
  769. !     else if ( c == NULL )
  770.       {
  771. ! /* cmd.exe interal command */
  772.   
  773. !       if ((new_argv = (char **) getcell (sizeof(char *) * (argc + 2)))
  774. !            == NULL)
  775. !       em = strerror (ENOMEM);
  776. !       else
  777. !       {
  778. !         memcpy (&new_argv[2], &v[0], sizeof(char *) * argc);
  779. !         new_argv[0] = lookup ("COMSPEC", FALSE)->value;
  780. !         new_argv[1] = "/c";
  781. !         res = rexecve (new_argv[0], new_argv, envp, d_flag);
  782. !         DELETE (new_argv);
  783. !     return res;
  784. !       }
  785. !     }
  786.   
  787. +     else
  788. +     {
  789.   /* Start off on the search path for the executable file */
  790.   
  791.       sp = (any ('/', c) || (*(c + 1) == ':')) ? null : path->value;
  792. ***************
  793. *** 940,953 ****
  794.               {
  795.               new_argv[0] = lookup ("COMSPEC", FALSE)->value;
  796.               new_argv[1] = "/c";
  797. - /* Get the switch character */
  798. -             r.x.ax = 0x3700;
  799. -             intdos (&r, &r);
  800. -             if (r.h.al == 0)
  801. -                 *new_argv[1] = (char)(r.h.dl);
  802.               }
  803.   
  804.   /* Stick in the pre-fix arguments */
  805. --- 999,1004 ----
  806. ***************
  807. *** 1044,1052 ****
  808.       ++cp;
  809.   
  810.       if ((cp = strrchr (cp, '.')) == (char *)NULL)
  811. !     strcat (local_path, ".bat");
  812.   
  813. !     else if (stricmp (cp, ".bat") != 0)
  814.       {
  815.       DELETE (local_path);
  816.       return FALSE;
  817. --- 1095,1103 ----
  818.       ++cp;
  819.   
  820.       if ((cp = strrchr (cp, '.')) == (char *)NULL)
  821. !     strcat (local_path, BATCHEXT);
  822.   
  823. !     else if (stricmp (cp, BATCHEXT) != 0)
  824.       {
  825.       DELETE (local_path);
  826.       return FALSE;
  827. ***************
  828. *** 1157,1167 ****
  829.   char        **parms;
  830.   char        **envp;
  831.   {
  832. !     unsigned int    c_cur = (unsigned int)(_psp - 1);
  833. !     unsigned int    size = 0;
  834. !     char        *ep, *ep1;
  835.       int            res, serrno;
  836. -     struct MCB_list    *mp = (struct MCB_list *)((unsigned long)c_cur << 16L);
  837.   
  838.   /* Check to see if the file exists */
  839.   
  840. --- 1208,1215 ----
  841.   char        **parms;
  842.   char        **envp;
  843.   {
  844. !     char        *ep, *ep1, path_line[255];
  845.       int            res, serrno;
  846.   
  847.   /* Check to see if the file exists */
  848.   
  849. ***************
  850. *** 1198,1578 ****
  851.       else if (access (path_line, F_OK) != 0)
  852.       return -1;
  853.   
  854. ! /* Process the command line.  If no swapping, we have executed the program */
  855. !     res = build_command_line (path_line, parms, envp);
  856. !     if ((Swap_Mode == SWAP_OFF) || res)
  857. !     return res;
  858. ! /* Find the length of the swap area */
  859. !     while ((mp = (struct MCB_list *)((unsigned long)c_cur << 16L))->MCB_type
  860. !         == MCB_CON)
  861. !     {
  862. !     if ((mp->MCB_pid != _psp) && (mp->MCB_pid != 0) &&
  863. !         (mp->MCB_type != MCB_END))
  864. !     {
  865. !         Clear_Extended_File ();
  866. !         print_error ("Fatal: Memory chain corrupt\n");
  867. !         return -1;
  868. !     }
  869. !     c_cur += (mp->MCB_len + 1);
  870. !     size += mp->MCB_len + 1;
  871. !     }
  872. ! /*
  873. !  * Convert swap size from paragraphs to 16K blocks.
  874. !  */
  875. !     if (size == 0)
  876. !     size = mp->MCB_len + 1;
  877. !     SW_Blocks = (size / 0x0400) + 1;
  878. !     SW_SBlocks = ((size - etext + _psp - 1) / 0x0400) + 1;
  879. ! /* OK Now we've set up the FCB's, command line and opened the swap file.
  880. !  * Get some sys info for the swapper and execute my little assembler
  881. !  * function to swap us out
  882. !  */
  883. ! /* Save the interrupt 0 and 23 addresses */
  884. !     SW_I0_V  = _dos_getvect (0x00);
  885. !     SW_I23_V = _dos_getvect (0x23);
  886. ! /* Ok - 3 methods of swapping */
  887. ! /* If expanded memory - try that */
  888. !     if ((Swap_Mode & SWAP_EXPAND) && Get_EMS_Driver ())
  889. !     {
  890. !     int    cr;
  891. !     SW_Mode = 3;            /* Set Expanded memory swap    */
  892. !     res = SA_spawn (envp);
  893. !     cr = EMS_Close ();        /* Close EMS            */
  894. !     if ((res != -2) && cr)        /* Report Close error ?        */
  895. !     {
  896. !         res = -2;
  897. !         errno = cr;
  898. !     }
  899. !     if (res == -2)
  900. !         EMS_error ("Expanded memory swap failed (%x)\n", errno);
  901. !     else
  902. !     {
  903. !         Clear_Extended_File ();
  904. !         return res;
  905. !     }
  906. ! /* Failed - disabled */
  907. !     Swap_Mode &= (~SWAP_EXPAND);
  908. !     }
  909. !     if ((Swap_Mode & SWAP_EXTEND) && Get_XMS_Driver ())
  910. !     {
  911. !     int    cr;
  912. ! /* Set Extended memory or XMS driver */
  913. !     SW_Mode = (SW_fp == -1) ? 2 : 4;
  914. !     res = SA_spawn (envp);
  915. !     cr = XMS_Close ();        /* Close XMS            */
  916. !     if ((res != -2) && cr)        /* Report Close error ?        */
  917. !     {
  918. !         res = -2;
  919. !         errno = cr;
  920. !     }
  921. !     if (res == -2)
  922. !         XMS_error ("Extended memory swap failed (%x)\n", errno);
  923. !     else
  924. !     {
  925. !         Clear_Extended_File ();
  926. !         return res;
  927. !     }
  928. ! /* Failed - disabled */
  929. !     Swap_Mode &= (~SWAP_EXTEND);
  930. !     }
  931. ! /* Try the disk if available */
  932. !     if (Swap_Mode & SWAP_DISK)
  933. !     {
  934. !     SW_Pwrite = 0;
  935. !     if (Swap_File == (char *)NULL)
  936. !         SW_fp = S_open (FALSE, (ep = g_tempname ()), O_SMASK, 0600);
  937. !     else
  938. !     {
  939. !         SW_fp = S_open (FALSE, Swap_File, O_SaMASK);
  940. !         SW_Pwrite = 1;
  941. !     }
  942. !     if (SW_fp < 0)
  943. !     {
  944. !         Clear_Swap_File ();
  945. !         Swap_Mode &= (~SWAP_DISK);
  946. !         print_error ("No Swap files\n");
  947. !         errno = ENOSPC;
  948. !         return -1;
  949. !     }
  950. ! /* Save the swap file name ? */
  951. !     if ((Swap_File == (char *)NULL) &&
  952. !         ((Swap_File = strsave (ep, 0)) == null))
  953. !         Swap_File = (char *)NULL;
  954. !     SW_Mode = 1;            /* Set Disk file swap        */
  955. ! /* Seek to correct location */
  956. !     if (SW_Pwrite)
  957. !     {
  958. !             long    loc = (long)(etext - _psp + 1) * 16L;
  959. !         if (lseek (SW_fp, loc, SEEK_SET) != loc)
  960. !         {
  961. !         serrno = errno;
  962. !         S_close (SW_fp, TRUE);
  963. !         Clear_Swap_File ();
  964. !         Swap_Mode &= (~SWAP_DISK);
  965. !         print_error ("No Swap files\n");
  966. !         errno = serrno;
  967. !         return -1;
  968. !         }
  969. !     }
  970. ! /* Execute the program */
  971. !     res = SA_spawn (envp);
  972. ! /* Close the swap file and extended command line files */
  973. !     Clear_Extended_File ();
  974. !     serrno = errno;
  975. !     S_close (SW_fp, TRUE);
  976. !     errno = serrno;
  977. ! /* Check for out of swap space */
  978. !     if (res == -2)
  979. !     {
  980. !         Clear_Swap_File ();
  981. !         Swap_Mode &= (~SWAP_DISK);
  982. !         print_warn ("Swap file write failed\n");
  983. !         errno = ENOSPC;
  984. !         res = -1;
  985. !     }
  986. ! /* Return the result */
  987. !     return res;
  988. !     }
  989. ! /* No swapping available - give up */
  990. !     Clear_Extended_File ();
  991. !     print_error ("All Swapping methods failed\n");
  992. !     errno = ENOSPC;
  993. !     return -1;
  994. ! }
  995. ! /* Get the XMS Driver information */
  996. ! static bool    Get_XMS_Driver ()
  997. ! {
  998. !     union REGS        or;
  999. !     struct SREGS    sr;
  1000. !     unsigned int    SW_EMsize;    /* Number of extend memory blks    */
  1001. ! /* Get max Extended memory pages, and convert to 16K blocks.  If Extended
  1002. !  * memory swapping disabled, set to zero
  1003. !  */
  1004. !     SW_fp = -1;                /* Set EMS/XMS handler not    */
  1005. !                     /* defined            */
  1006. ! /* Is a XMS memory driver installed */
  1007. !     or.x.ax = 0x4300;
  1008. !     int86 (0x2f, &or, &or);
  1009. !     if (or.h.al != 0x80)
  1010. !     {
  1011. !     or.x.ax = 0x8800;
  1012. !     int86 (0x15, &or, &or);
  1013. !     SW_EMsize = or.x.ax / 16;
  1014. !     if ((SW_EMsize <= SW_Blocks) ||
  1015. !          ((SW_EMstart - 0x100000L +
  1016. !           ((long)(SW_Blocks - SW_EMsize) * 16L * 1024L)) < 0L))
  1017. !         return XMS_error ("Not enough Extended memory for swap\n", 0);
  1018. !     else
  1019. !         return TRUE;
  1020. !     }
  1021. ! /* Get the driver interface */
  1022. !     or.x.ax = 0x4310;
  1023. !     int86x (0x2f, &or, &or, &sr);
  1024. !     SW_XMS_Driver = (void (*)())((unsigned long)(sr.es) << 16L | or.x.bx);
  1025. !     if ((SW_XMS_Gversion () & 0xff00) != 0x0200)
  1026. !     return XMS_error ("Warning: XMS Version != 2\n", 0);
  1027. !     else if ((SW_fp = SW_XMS_Allocate (SW_Blocks * 16)) == -1)
  1028. !     return XMS_error (XMS_emsg, errno);
  1029. !     return TRUE;
  1030. ! }
  1031. ! /* Get the EMS Driver information */
  1032. ! static bool    Get_EMS_Driver ()
  1033. ! {
  1034. !     union REGS        or;
  1035. !     struct SREGS    sr;
  1036. !     char        *sp;
  1037. ! /* Set EMS/XMS handler not defined */
  1038. !     SW_fp = -1;
  1039. !     or.x.ax = 0x3567;
  1040. !     intdosx (&or, &or, &sr);
  1041. !     sp = (char *)((unsigned long)(sr.es) << 16L | 10L);
  1042. ! /* If not there - disable */
  1043. !     if (memcmp ("EMMXXXX0", sp, 8) != 0)
  1044. !     return EMS_error ("Warning: EMS not available\n", 0);
  1045. !     or.h.ah = 0x40;            /* Check status            */
  1046. !     int86 (0x67, &or, &or);
  1047. !     if (or.h.ah != 0)
  1048. !     return EMS_error (EMS_emsg, or.h.ah);
  1049. ! /* Check version greater than 3.2 */
  1050. !     or.h.ah = 0x46;
  1051. !     int86 (0x67, &or, &or);
  1052. !     if ((or.h.ah != 0) || (or.h.al < 0x32))
  1053. !     return EMS_error ("Warning: EMS Version < 3.2\n", 0);
  1054. ! /*  get page frame address */
  1055. !     or.h.ah = 0x41;
  1056. !     int86 (0x67, &or, &or);
  1057. !     if (or.h.ah != 0)
  1058. !     return EMS_error (EMS_emsg, or.h.ah);
  1059. !     SW_EMSFrame = or.x.bx;        /* Save the page frame        */
  1060. ! /* Get the number of pages required */
  1061. !     or.h.ah = 0x43;
  1062. !     or.x.bx = SW_Blocks;
  1063. !     int86 (0x67, &or, &or);
  1064. !     if (or.h.ah != 0)
  1065. !     return EMS_error (EMS_emsg, or.h.ah);
  1066. ! /* Save the EMS Handler */
  1067. !     SW_fp = or.x.dx;
  1068. ! /* save EMS page map */
  1069. !     or.h.ah = 0x47;
  1070. !     or.x.dx = SW_fp;
  1071. !     int86 (0x67, &or, &or);
  1072. !     return (or.h.ah != 0) ? EMS_error (EMS_emsg, or.h.ah) : TRUE;
  1073. ! }
  1074. ! /* Print EMS error message */
  1075. ! static bool    EMS_error (s, v)
  1076. ! char        *s;
  1077. ! int        v;
  1078. ! {
  1079. !     print_warn (s, v);
  1080. !     Swap_Mode &= ~(SWAP_EXPAND);
  1081. !     EMS_Close ();
  1082. !     return FALSE;
  1083. ! }
  1084. ! /* Print XMS error message */
  1085. ! static bool    XMS_error (s, v)
  1086. ! char        *s;
  1087. ! int        v;
  1088. ! {
  1089. !     print_warn (s, v);
  1090. !     Swap_Mode &= ~(SWAP_EXTEND);
  1091. !     XMS_Close ();
  1092. !     return FALSE;
  1093. ! }
  1094. ! /* If the XMS handler is defined - close it */
  1095. ! static int    XMS_Close ()
  1096. ! {
  1097. !     int        res = 0;
  1098. ! /* Release XMS page */
  1099. !     if (SW_fp != -1)
  1100. !     res = SW_XMS_Free (SW_fp);
  1101. !     SW_fp = -1;
  1102. !     return res;
  1103. ! }
  1104. ! /* If the EMS handler is defined - close it */
  1105. ! static int    EMS_Close ()
  1106. ! {
  1107. !     union REGS        or;
  1108. !     int            res = 0;
  1109. !     if (SW_fp == -1)
  1110. !     return 0;
  1111. ! /* Restore EMS page */
  1112. !     or.h.ah = 0x48;
  1113. !     or.x.dx = SW_fp;
  1114. !     int86 (0x67, &or, &or);
  1115. !     if (or.h.ah != 0)
  1116. !     res = or.h.al;
  1117. !     or.h.ah = 0x45;
  1118. !     or.x.dx = SW_fp;
  1119. !     int86 (0x67, &or, &or);
  1120.   
  1121. !     SW_fp = -1;
  1122. !     return (res) ? res : or.h.ah;
  1123.   }
  1124.   
  1125.   /* Set up command line.  If the EXTENDED_LINE variable is set, we create
  1126. --- 1246,1254 ----
  1127.       else if (access (path_line, F_OK) != 0)
  1128.       return -1;
  1129.   
  1130. ! /* Process the command line. */
  1131.   
  1132. !     return build_command_line (path_line, parms, envp);
  1133.   }
  1134.   
  1135.   /* Set up command line.  If the EXTENDED_LINE variable is set, we create
  1136. ***************
  1137. *** 1595,1600 ****
  1138. --- 1271,1278 ----
  1139.       bool        found;
  1140.       char        *ep;
  1141.       char        *new_args[3];
  1142. +     char                cmd_line[CMD_LINE_MAX];
  1143. +     void         (*save_signal)(int);
  1144.   
  1145.   /* Translate process name to MSDOS format */
  1146.   
  1147. ***************
  1148. *** 1686,1692 ****
  1149.   
  1150.   /* Correctly terminate cmd_line in no swap mode */
  1151.   
  1152. -         if (Swap_Mode != SWAP_OFF)
  1153.           cmd_line[cmd_line[0] + 2] = '\r';
  1154.   
  1155.   /* If the name in the file is in upper case - use \ for separators */
  1156. --- 1364,1369 ----
  1157. ***************
  1158. *** 1696,1711 ****
  1159.   
  1160.   /* OK we are ready to execute */
  1161.   
  1162. -         if (Swap_Mode == SWAP_OFF)
  1163. -         {
  1164.           new_args[0] = *argv;
  1165.           new_args[1] = &cmd_line[1];
  1166.           new_args[2] = (char *)NULL;
  1167. -         return spawnve (P_WAIT, path, new_args, envp);
  1168. -         }
  1169.   
  1170. !         else
  1171. !         return 0;
  1172.       }
  1173.       }
  1174.   
  1175. --- 1373,1386 ----
  1176.   
  1177.   /* OK we are ready to execute */
  1178.   
  1179.           new_args[0] = *argv;
  1180.           new_args[1] = &cmd_line[1];
  1181.           new_args[2] = (char *)NULL;
  1182.   
  1183. !             save_signal = signal (SIGINT, SIG_DFL);
  1184. !         res = spawnve (spawnmode, path, new_args, envp);
  1185. !             signal (SIGINT, save_signal);
  1186. !             return res;
  1187.       }
  1188.       }
  1189.   
  1190. ***************
  1191. *** 1745,1753 ****
  1192.   
  1193.       cmd_line[0] = (char)res;
  1194.   
  1195. ! /* If swapping disabled - just execute it */
  1196.   
  1197. !     return (Swap_Mode == SWAP_OFF) ? spawnve (P_WAIT, path, argv, envp) : 0;
  1198.   }
  1199.   
  1200.   /* Check string for white space */
  1201. --- 1420,1431 ----
  1202.   
  1203.       cmd_line[0] = (char)res;
  1204.   
  1205. ! /* Just execute it */
  1206.   
  1207. !     save_signal = signal (SIGINT, SIG_DFL);
  1208. !     res = spawnve (spawnmode, path, argv, envp);
  1209. !     signal (SIGINT, save_signal);
  1210. !     return res;
  1211.   }
  1212.   
  1213.   /* Check string for white space */
  1214. ***************
  1215. *** 1784,1802 ****
  1216.       Extend_file = (char *)NULL;
  1217.   }
  1218.   
  1219. - /* Clear Disk swap file file */
  1220. - void    Clear_Swap_File ()
  1221. - {
  1222. -     if (Swap_File != (char *)NULL)
  1223. -     {
  1224. -     unlink (Swap_File);
  1225. -     DELETE (Swap_File);
  1226. -     }
  1227. -     Swap_File = (char *)NULL;
  1228. - }
  1229.   /* Convert the executable path to the full path name */
  1230.   
  1231.   static char    *Gen_Full_Path_Name (path)
  1232. --- 1462,1467 ----
  1233. ***************
  1234. *** 1830,1838 ****
  1235.   
  1236.   /* Switch drives and get the path of the other drive */
  1237.   
  1238. !         _dos_setdrive (tolower (*path) - 'a' + 1, &dummy);
  1239.           getcwd (npath, PATH_MAX + 3);
  1240. !         _dos_setdrive (tolower (*cpath) - 'a' + 1, &dummy);
  1241.        }
  1242.       }
  1243.   
  1244. --- 1495,1503 ----
  1245.   
  1246.   /* Switch drives and get the path of the other drive */
  1247.   
  1248. !         DosSelectDisk(tolower (*path) - 'a' + 1);
  1249.           getcwd (npath, PATH_MAX + 3);
  1250. !         DosSelectDisk(tolower (*cpath) - 'a' + 1);
  1251.        }
  1252.       }
  1253.   
  1254. ***************
  1255. *** 1861,1867 ****
  1256.   /* Change to the directory containing the executable */
  1257.   
  1258.       if (*(path + 1) == ':')
  1259. !         _dos_setdrive (tolower (*path) - 'a' + 1, &dummy);
  1260.   
  1261.   /* Save the current directory on this drive */
  1262.   
  1263. --- 1526,1532 ----
  1264.   /* Change to the directory containing the executable */
  1265.   
  1266.       if (*(path + 1) == ':')
  1267. !         DosSelectDisk(tolower (*path) - 'a' + 1);
  1268.   
  1269.   /* Save the current directory on this drive */
  1270.   
  1271. ***************
  1272. *** 1882,1888 ****
  1273.   
  1274.   /* Restore our original directory */
  1275.   
  1276. !     _dos_setdrive (tolower (*cpath) - 'a' + 1, &dummy);
  1277.   
  1278.       if (chdir (cpath) < 0)
  1279.           return (char *)NULL;
  1280. --- 1547,1553 ----
  1281.   
  1282.   /* Restore our original directory */
  1283.   
  1284. !     DosSelectDisk(tolower (*cpath) - 'a' + 1);
  1285.   
  1286.       if (chdir (cpath) < 0)
  1287.           return (char *)NULL;
  1288. diff -cbBw sh-dos/sh4.c sh-os2/sh4.c
  1289. *** sh-dos/sh4.c    Thu Jul 05 19:50:28 1990
  1290. --- sh-os2/sh4.c    Sat Aug 04 16:22:18 1990
  1291. ***************
  1292. *** 45,59 ****
  1293.   #include <signal.h>
  1294.   #include <errno.h>
  1295.   #include <setjmp.h>
  1296. - #include <dirent.h>
  1297.   #include <string.h>
  1298.   #include <stdlib.h>
  1299.   #include <unistd.h>
  1300.   #include <ctype.h>
  1301. - #include <bios.h>
  1302. - #include <dos.h>
  1303.   #include "sh.h"
  1304.   
  1305.   /*
  1306.    * ${}, `command`, blank interpretation, quoting and file name expansion
  1307.    */
  1308. --- 45,62 ----
  1309.   #include <signal.h>
  1310.   #include <errno.h>
  1311.   #include <setjmp.h>
  1312.   #include <string.h>
  1313.   #include <stdlib.h>
  1314. + #include <stdio.h>
  1315.   #include <unistd.h>
  1316. + #include <dir.h>
  1317.   #include <ctype.h>
  1318.   #include "sh.h"
  1319.   
  1320. + #define INCL_NOPM
  1321. + #define INCL_DOS
  1322. + #include <os2.h>
  1323.   /*
  1324.    * ${}, `command`, blank interpretation, quoting and file name expansion
  1325.    */
  1326. ***************
  1327. *** 853,859 ****
  1328.       register char    *np, *cp;
  1329.       char        *name, *gp, *dp;
  1330.       DIR            *dn;
  1331. !     struct dirent    *d_ce;
  1332.       char        dname[NAME_MAX + 1];
  1333.       struct stat        dbuf;
  1334.   
  1335. --- 856,862 ----
  1336.       register char    *np, *cp;
  1337.       char        *name, *gp, *dp;
  1338.       DIR            *dn;
  1339. !     struct direct    *d_ce;
  1340.       char        dname[NAME_MAX + 1];
  1341.       struct stat        dbuf;
  1342.   
  1343. ***************
  1344. *** 898,904 ****
  1345.   
  1346.   /* Scan for matches */
  1347.   
  1348. !     while ((d_ce = readdir (dn)) != (struct dirent *)NULL)
  1349.       {
  1350.       if ((*(strcpy (dname, d_ce->d_name)) == '.') && (*gp != '.'))
  1351.           continue;
  1352. --- 901,907 ----
  1353.   
  1354.   /* Scan for matches */
  1355.   
  1356. !     while ((d_ce = readdir (dn)) != (struct direct *)NULL)
  1357.       {
  1358.       if ((*(strcpy (dname, d_ce->d_name)) == '.') && (*gp != '.'))
  1359.           continue;
  1360. ***************
  1361. *** 1105,1153 ****
  1362.   char        *start;
  1363.   {
  1364.       unsigned int    c_drive;    /* Current drive        */
  1365. -     unsigned int    m_drive;    /* Max drive            */
  1366. -     unsigned int    s_drive;    /* Selected drive        */
  1367. -     unsigned int    x_drive, y_drive;    /* Dummies        */
  1368.       char        *multi;        /* Multi-drive flag        */
  1369.       static char        *t_drive = "x";
  1370.       char        *new_pattern;
  1371.   
  1372.   /* Search all drives ? */
  1373.   
  1374.       if ((multi = Check_Multi_Drive (pattern)) != (char *)NULL)
  1375.       {
  1376. !     _dos_getdrive (&c_drive);    /* Get number of drives        */
  1377. !     _dos_setdrive (c_drive, &m_drive);
  1378. !     new_pattern = space (strlen (multi) + 2);
  1379.   
  1380.       strcpy (new_pattern + 1, multi);
  1381. -     *multi = 0;
  1382.   
  1383. !     for (s_drive = 1; s_drive <= m_drive; ++s_drive)
  1384.       {
  1385. !         _dos_setdrive (s_drive, &x_drive);
  1386. !         _dos_getdrive (&y_drive);
  1387. !         _dos_setdrive (c_drive, &x_drive);
  1388. ! /* Check to see if the second diskette drive is really there */
  1389. !         if (((_bios_equiplist () & 0x00c0) == 0x0000) && (s_drive == 2))
  1390. !         continue;
  1391. ! /* If the drive exists and is in our list - process it */
  1392. !         *t_drive = (char)(s_drive + 'a' - 1);
  1393.   
  1394. !         if ((y_drive == s_drive) && gmatch (t_drive, pattern, TRUE))
  1395.           {
  1396.           *new_pattern = *t_drive;
  1397. !         globname (new_pattern, &new_pattern[2]);
  1398.           }
  1399.       }
  1400.   
  1401.   /* Restore and delete space */
  1402.   
  1403. -     *multi = ':';
  1404.       DELETE (new_pattern);
  1405.       }
  1406.   
  1407. --- 1108,1146 ----
  1408.   char        *start;
  1409.   {
  1410.       unsigned int    c_drive;    /* Current drive        */
  1411.       char        *multi;        /* Multi-drive flag        */
  1412.       static char        *t_drive = "x";
  1413.       char        *new_pattern;
  1414. +     ULONG               l_map;
  1415. +     int                 cnt;
  1416.   
  1417.   /* Search all drives ? */
  1418.   
  1419.       if ((multi = Check_Multi_Drive (pattern)) != (char *)NULL)
  1420.       {
  1421. !         DosQCurDisk((PUSHORT) &c_drive, &l_map);
  1422.   
  1423. +     new_pattern = space (strlen (multi) + 2);
  1424.       strcpy (new_pattern + 1, multi);
  1425.   
  1426. !         for ( cnt = 1; cnt <= 26; cnt++, l_map >>= 1 )
  1427. !           if ( l_map & 1L )
  1428.         {
  1429. !           *t_drive = (char)(cnt + 'a' - 1);
  1430. !               *multi = 0;
  1431.   
  1432. !           if (gmatch (t_drive, pattern, TRUE))
  1433.             {
  1434.             *new_pattern = *t_drive;
  1435. !                 *multi = ':';
  1436. !           globname (new_pattern, strchr(new_pattern,0));
  1437.             }
  1438. +               else
  1439. +                 *multi = ':';
  1440.         }
  1441.   
  1442.   /* Restore and delete space */
  1443.   
  1444.       DELETE (new_pattern);
  1445.       }
  1446.   
  1447. diff -cbBw sh-dos/sh6.c sh-os2/sh6.c
  1448. *** sh-dos/sh6.c    Thu Jul 05 19:50:30 1990
  1449. --- sh-os2/sh6.c    Sat Aug 04 13:45:18 1990
  1450. ***************
  1451. *** 69,76 ****
  1452.   #include <string.h>
  1453.   #include "sh.h"
  1454.   
  1455. ! static char    *Copy_Right1 = "MS-DOS SH Version 1.6.2 - %s (DOS %d.%d)\n";
  1456.   static char    *Copy_Right2 = "Copyright (c) Data Logic Ltd and Charles Forsyth 1990\n";
  1457.   char        **dolv;        /* Parameter array            */
  1458.   int        dolc;        /* Number of entries in parameter array    */
  1459.   int        exstat;        /* Exit status                */
  1460. --- 69,78 ----
  1461.   #include <string.h>
  1462.   #include "sh.h"
  1463.   
  1464. ! static char    *Copy_Right1 = "\nSH Version 1.6.2 - %s (OS/2 %d.%02d)\n";
  1465.   static char    *Copy_Right2 = "Copyright (c) Data Logic Ltd and Charles Forsyth 1990\n";
  1466. + static char    *Copy_Right3 = "Ported to OS/2 by Kai Uwe Rommel 1990\n\n";
  1467.   char        **dolv;        /* Parameter array            */
  1468.   int        dolc;        /* Number of entries in parameter array    */
  1469.   int        exstat;        /* Exit status                */
  1470. ***************
  1471. *** 83,89 ****
  1472.   int        *failpt;    /* Current fail point jump address    */
  1473.   int        *errpt;        /* Current error point jump address    */
  1474.                   /* Swap mode                */
  1475. - int        Swap_Mode = SWAP_EXPAND | SWAP_DISK;
  1476.   Break_C        *Break_List;    /* Break list for FOR/WHILE        */
  1477.   Break_C        *Return_List;    /* Return list for RETURN        */
  1478.   Break_C        *SShell_List;    /* SubShell list for EXIT        */
  1479. --- 85,90 ----
  1480. ***************
  1481. *** 161,167 ****
  1482.   {
  1483.       char    buf[100];
  1484.   
  1485. !     sprintf (buf, Copy_Right1, __DATE__, _osmajor, _osminor);
  1486.       write (fp, buf, strlen (buf));
  1487.       write (fp, Copy_Right2, strlen (Copy_Right2));
  1488.   }
  1489. --- 162,169 ----
  1490.   {
  1491.       char    buf[100];
  1492.   
  1493. !     sprintf (buf, Copy_Right1, __DATE__, _osmajor / 10, _osminor);
  1494.       write (fp, buf, strlen (buf));
  1495.       write (fp, Copy_Right2, strlen (Copy_Right2));
  1496. +     write (fp, Copy_Right3, strlen (Copy_Right3));
  1497.   }
  1498. diff -cbBw sh-dos/sh7.c sh-os2/sh7.c
  1499. *** sh-dos/sh7.c    Thu Jul 05 19:50:32 1990
  1500. --- sh-os2/sh7.c        Fri Aug 17 19:09:32 1990
  1501. ***************
  1502. *** 78,84 ****
  1503.   #include <sys/stat.h>
  1504.   #include <stdio.h>
  1505.   #include <process.h>
  1506. - #include <dos.h>
  1507.   #include <signal.h>
  1508.   #include <errno.h>
  1509.   #include <setjmp.h>
  1510. --- 78,83 ----
  1511. ***************
  1512. *** 91,96 ****
  1513. --- 90,99 ----
  1514.   #include <stdarg.h>
  1515.   #include "sh.h"
  1516.   
  1517. + #define INCL_NOPM
  1518. + #define INCL_DOS
  1519. + #include <os2.h>
  1520.   #define    SECS        60L
  1521.   #define    MINS        3600L
  1522.   #define IS_OCTAL(a)    (((a) >= '0') && ((a) <= '7'))
  1523. ***************
  1524. *** 101,107 ****
  1525.   #define FILE_READABLE    1
  1526.   #define FILE_WRITABLE    2
  1527.   #define FILE_REGULAR    3
  1528. ! #define FILE_DIRECTORY    4
  1529.   #define FILE_NONZERO    5
  1530.   #define FILE_TERMINAL    6
  1531.   #define STRING_ZERO    7
  1532. --- 104,110 ----
  1533.   #define FILE_READABLE    1
  1534.   #define FILE_WRITABLE    2
  1535.   #define FILE_REGULAR    3
  1536. ! #define _FILE_DIRECTORY    4
  1537.   #define FILE_NONZERO    5
  1538.   #define FILE_TERMINAL    6
  1539.   #define STRING_ZERO    7
  1540. ***************
  1541. *** 143,149 ****
  1542.       {"-w",    FILE_WRITABLE,        UNARY_OP},
  1543.       {"-x",    FILE_EXECUTABLE,    UNARY_OP},
  1544.       {"-f",    FILE_REGULAR,        UNARY_OP},
  1545. !     {"-d",    FILE_DIRECTORY,        UNARY_OP},
  1546.       {"-s",    FILE_NONZERO,        UNARY_OP},
  1547.       {"-t",    FILE_TERMINAL,        UNARY_OP},
  1548.       {"-z",    STRING_ZERO,        UNARY_OP},
  1549. --- 146,152 ----
  1550.       {"-w",    FILE_WRITABLE,        UNARY_OP},
  1551.       {"-x",    FILE_EXECUTABLE,    UNARY_OP},
  1552.       {"-f",    FILE_REGULAR,        UNARY_OP},
  1553. !     {"-d",    _FILE_DIRECTORY,    UNARY_OP},
  1554.       {"-s",    FILE_NONZERO,        UNARY_OP},
  1555.       {"-t",    FILE_TERMINAL,        UNARY_OP},
  1556.       {"-z",    STRING_ZERO,        UNARY_OP},
  1557. ***************
  1558. *** 197,203 ****
  1559.   static int        doecho (C_Op *);
  1560.   static int        dogetopt (C_Op *);
  1561.   static int        dopwd (C_Op *);
  1562. - static int        doswap (C_Op *);
  1563.   static int        dounset (C_Op *);
  1564.   static int        dotype (C_Op *);
  1565.   static int        dotest (C_Op *);
  1566. --- 200,205 ----
  1567. ***************
  1568. *** 217,222 ****
  1569. --- 219,226 ----
  1570.   static int        doreadonly (C_Op *);
  1571.   static int        doset (C_Op *);
  1572.   static int        dohistory (C_Op *);
  1573. + extern int              dojobs(C_Op *);
  1574.   static void        setsig (int, int (*)());
  1575.   static int        rdexp (char **, int, char *);
  1576.   
  1577. ***************
  1578. *** 453,575 ****
  1579.   }
  1580.   
  1581.   /*
  1582. !  * Display the current version
  1583.    */
  1584.   
  1585. ! static int    dover (t)
  1586.   C_Op        *t;
  1587.   {
  1588. -     Print_Version (1);
  1589.       return 0;
  1590.   }
  1591.   
  1592. - static char    *swap_device[] = {"disk", "extend", "expand"};
  1593.   /*
  1594. !  * Modify swapping information: swap options
  1595.    */
  1596.   
  1597. ! static int    doswap (t)
  1598. ! register C_Op    *t;
  1599. ! {
  1600. !     register int    n = 1;
  1601. !     char        *cp;
  1602. ! /* Display current values ? */
  1603. !     if (t->words[1] == (char *)NULL)
  1604. !     {
  1605. !     if (Swap_Mode == SWAP_OFF)
  1606. !         v1a_puts ("Swapping disabled");
  1607. !     else
  1608. !     {
  1609. !         register int    j;
  1610. !         v1_puts ("Swap devices: ");
  1611. !         for (j = 0, n = 1; j < 3; ++j, n <<= 1)
  1612. !         {
  1613. !         if (Swap_Mode & n)
  1614. !         {
  1615. !             v1printf ("%s ", swap_device[j]);
  1616. !             if (n == SWAP_EXTEND)
  1617. !             v1printf ("(0x%.6lx) ", SW_EMstart);
  1618. !         }
  1619. !         }
  1620. !         v1_putc (NL);
  1621. !     }
  1622. !     return 0;
  1623. !     }
  1624. ! /* Set up new values */
  1625. !     Swap_Mode = SWAP_OFF;
  1626. !     Clear_Swap_File ();
  1627. !     while ((cp = t->words[n++]) != (char *)NULL)
  1628.       {
  1629. !     if (strcmp (cp, "off") == 0)
  1630. !         Swap_Mode = SWAP_OFF;
  1631. !     else if (strcmp (cp, "on") == 0)
  1632. !         Swap_Mode = SWAP_DISK | SWAP_EXPAND | SWAP_EXTEND;
  1633. ! /* Scan for valid arguments */
  1634. !     else
  1635. !     {
  1636. !         register int    j, k;
  1637. !         for (j = 0, k = 1; j < 3; ++j, k <<= 1)
  1638. !         {
  1639. !         if (strcmp (cp, swap_device[j]) == 0)
  1640. !         {
  1641. !             Swap_Mode |= k;
  1642. ! /* If extended memory, they can specify the start address as a hex number */
  1643. !             if (k == SWAP_EXTEND)
  1644. !             {
  1645. !             char    *sp;
  1646. !             long    start;
  1647. ! /* Check for not changed */
  1648. !             if ((sp = t->words[n]) == (char *)NULL)
  1649. !                 break;
  1650. ! /* Convert hex number */
  1651. !             start = strtol (sp, &sp, 16);
  1652. ! /* If not completely a hex number, ignore */
  1653. !             if (*sp)
  1654. !                 break;
  1655. ! /* Set used and saved new value */
  1656. !             SW_EMstart = start;
  1657. !             ++n;
  1658. !             if ((SW_EMstart < 0x100000L) ||
  1659. !                 (SW_EMstart > 0xf00000L))
  1660. !                 SW_EMstart = 0x100000L;
  1661. !             v1printf ("Extend memory start set to 0x%.6lx\n",
  1662. !                   SW_EMstart);
  1663. !             }
  1664. !             break;
  1665. !         }
  1666. !         }
  1667. !     }
  1668. !     }
  1669.       return 0;
  1670.   }
  1671.   
  1672. --- 457,479 ----
  1673.   }
  1674.   
  1675.   /*
  1676. !  * Do nothing
  1677.    */
  1678.   
  1679. ! static int    donothing (t)
  1680.   C_Op        *t;
  1681.   {
  1682.       return 0;
  1683.   }
  1684.   
  1685.   /*
  1686. !  * Display the current version
  1687.    */
  1688.   
  1689. ! static int    dover (t)
  1690. ! C_Op        *t;
  1691.   {
  1692. !     Print_Version (1);
  1693.       return 0;
  1694.   }
  1695.   
  1696. ***************
  1697. *** 846,852 ****
  1698.       case FILE_REGULAR:
  1699.           return stat (*test_alist, &s) == 0 && S_ISREG(s.st_mode);
  1700.   
  1701. !     case FILE_DIRECTORY:
  1702.           return stat (*test_alist, &s) == 0 && S_ISDIR(s.st_mode);
  1703.   
  1704.       case FILE_NONZERO:
  1705. --- 750,756 ----
  1706.       case FILE_REGULAR:
  1707.           return stat (*test_alist, &s) == 0 && S_ISREG(s.st_mode);
  1708.   
  1709. !     case _FILE_DIRECTORY:
  1710.           return stat (*test_alist, &s) == 0 && S_ISDIR(s.st_mode);
  1711.   
  1712.       case FILE_NONZERO:
  1713. ***************
  1714. *** 948,957 ****
  1715.   {
  1716.       unsigned int    cdrive;
  1717.       unsigned int    ndrive = tolower (**t->words) - 'a' + 1;
  1718.   
  1719. !     _dos_setdrive (ndrive, &cdrive);
  1720.       Getcwd ();
  1721. !     _dos_getdrive (&cdrive);
  1722.       return (ndrive == cdrive) ? 0 : 1;
  1723.   }
  1724.   
  1725. --- 852,862 ----
  1726.   {
  1727.       unsigned int    cdrive;
  1728.       unsigned int    ndrive = tolower (**t->words) - 'a' + 1;
  1729. +     ULONG l_map;
  1730.   
  1731. !     DosSelectDisk(ndrive);
  1732.       Getcwd ();
  1733. !     DosQCurDisk((PUSHORT) &cdrive, &l_map);
  1734.       return (ndrive == cdrive) ? 0 : 1;
  1735.   }
  1736.   
  1737. ***************
  1738. *** 969,974 ****
  1739. --- 874,880 ----
  1740.       int            first = 0;
  1741.       unsigned int    dummy;
  1742.       unsigned int    cdrive;
  1743. +     ULONG l_map;
  1744.   
  1745.   /* If restricted shell - illegal */
  1746.   
  1747. ***************
  1748. *** 992,998 ****
  1749.   
  1750.   /* Save the current drive */
  1751.   
  1752. !     _dos_getdrive (&cdrive);
  1753.   
  1754.   /* Scan for the directory.  If there is not a / or : at start, use the
  1755.    * CDPATH variable
  1756. --- 898,904 ----
  1757.   
  1758.   /* Save the current drive */
  1759.   
  1760. !     DosQCurDisk((PUSHORT) &cdrive, &l_map);
  1761.   
  1762.   /* Scan for the directory.  If there is not a / or : at start, use the
  1763.    * CDPATH variable
  1764. ***************
  1765. *** 1011,1017 ****
  1766.   
  1767.       if (*(nd + 1) == ':')
  1768.       {
  1769. !         _dos_setdrive (tolower (*nd) - 'a' + 1, &dummy);
  1770.           nd += 2;
  1771.       }
  1772.   
  1773. --- 917,923 ----
  1774.   
  1775.       if (*(nd + 1) == ':')
  1776.       {
  1777. !         DosSelectDisk(tolower (*nd) - 'a' + 1);
  1778.           nd += 2;
  1779.       }
  1780.   
  1781. ***************
  1782. *** 1038,1044 ****
  1783.   
  1784.   /* Restore our original drive and restore directory info */
  1785.   
  1786. !     _dos_setdrive (cdrive, &dummy);
  1787.       Getcwd ();
  1788.   
  1789.       print_error ("%s: bad directory\n", p);
  1790. --- 944,950 ----
  1791.   
  1792.   /* Restore our original drive and restore directory info */
  1793.   
  1794. !     DosSelectDisk(cdrive);
  1795.       Getcwd ();
  1796.   
  1797.       print_error ("%s: bad directory\n", p);
  1798. ***************
  1799. *** 1756,1766 ****
  1800.   #endif
  1801.   
  1802.   /*
  1803. !  * Type fucntion: For each name, indicate how it would be interpreted
  1804.    */
  1805.   
  1806.   static char    *type_ext[] = {
  1807. !     "", ".exe", ".com", ".sh", ".bat"
  1808.   };
  1809.   
  1810.   static int    dotype (t)
  1811. --- 1662,1672 ----
  1812.   #endif
  1813.   
  1814.   /*
  1815. !  * Type function: For each name, indicate how it would be interpreted
  1816.    */
  1817.   
  1818.   static char    *type_ext[] = {
  1819. !     "", ".exe", ".com", ".sh", BATCHEXT
  1820.   };
  1821.   
  1822.   static int    dotype (t)
  1823. ***************
  1824. *** 1776,1781 ****
  1825. --- 1682,1688 ----
  1826.       bool        found;            /* Found flag        */
  1827.       char        *l_path;
  1828.       Fun_Ops        *fops;
  1829. +     char                *mp;
  1830.   
  1831.   /* Get some memory for the buffer */
  1832.   
  1833. ***************
  1834. *** 1789,1794 ****
  1835. --- 1696,1714 ----
  1836.   
  1837.       while ((cp = t->words[n++]) != (char *)NULL)
  1838.       {
  1839. +     if ( inbuilt (cp) )
  1840. +         {
  1841. +         v1_puts (cp);
  1842. +         v1a_puts (" is a shell internal command");
  1843. +         continue;
  1844. +         }
  1845. +         if ( cmd_internal(cp) )
  1846. +         {
  1847. +         v1_puts (cp);
  1848. +         v1a_puts (" is a CMD.EXE internal command");
  1849. +         continue;
  1850. +         }
  1851.   
  1852.   /* Check for a function */
  1853.   
  1854. ***************
  1855. *** 1841,1849 ****
  1856.   
  1857.               else if ((stricmp (xp, ".exe") != 0) &&
  1858.                    (stricmp (xp, ".com") != 0) &&
  1859. !                  (stricmp (xp, ".bat") != 0))
  1860.               continue;
  1861.   
  1862.               print_error ("%s is %s\n", cp, l_path);
  1863.               found = TRUE;
  1864.           }
  1865. --- 1761,1775 ----
  1866.   
  1867.               else if ((stricmp (xp, ".exe") != 0) &&
  1868.                    (stricmp (xp, ".com") != 0) &&
  1869. !                  (stricmp (xp, BATCHEXT) != 0))
  1870.               continue;
  1871.   
  1872. +                     strlwr(l_path);
  1873. +                     for ( mp = l_path; *mp; mp++ )
  1874. +                       if ( *mp == '\\' )
  1875. +                         *mp = '/';
  1876.               print_error ("%s is %s\n", cp, l_path);
  1877.               found = TRUE;
  1878.           }
  1879. ***************
  1880. *** 1871,1880 ****
  1881. --- 1797,1808 ----
  1882.       "exec",        doexec,
  1883.       "exit",        doexit,
  1884.       "export",    doexport,
  1885. +         "extproc",      donothing,
  1886.       "getopt",    dogetopt,
  1887.   #ifndef NO_HISTORY
  1888.       "history",    dohistory,
  1889.   #endif
  1890. +         "jobs",         dojobs,
  1891.       "msdos",    domsdos,
  1892.       "pwd",        dopwd,
  1893.       "read",        doread,
  1894. ***************
  1895. *** 1882,1888 ****
  1896.       "return",    doreturn,
  1897.       "set",        doset,
  1898.       "shift",    doshift,
  1899. -     "swap",        doswap,
  1900.       "test",        dotest,
  1901.       "trap",        dotrap,
  1902.       "type",        dotype,
  1903. --- 1810,1815 ----
  1904. ***************
  1905. *** 1911,1916 ****
  1906. --- 1838,1872 ----
  1907.       }
  1908.   
  1909.       return (int (*)())NULL;
  1910. + }
  1911. + /* recognize CMD.EXE internal commands */
  1912. + char *cmd_tab[] =
  1913. + {
  1914. +   "chcp", "cls", "copy",
  1915. +   "date", "del", "detach", "dir",
  1916. +   "erase",
  1917. +   "md", "mkdir", "move",
  1918. +   "ren", "rename", "rd", "rmdir",
  1919. +   "start",
  1920. +   "time",
  1921. +   NULL
  1922. + };
  1923. + #define cmds (sizeof(cmd_tab) / sizeof(char *) - 1)
  1924. + char *cmd_internal(char *s)
  1925. + {
  1926. +     int cnt;
  1927. +     for ( cnt = 0; cnt < cmds; cnt++ )
  1928. +     {
  1929. +     if (stricmp (cmd_tab[cnt], s) == 0)
  1930. +         return cmd_tab[cnt];
  1931. +     }
  1932. +     return NULL;
  1933.   }
  1934.   
  1935.   /* Write to stdout functions - printf, fputs, fputc, and a special */
  1936. diff -cbBw sh-dos/sh8.c sh-os2/sh8.c
  1937. *** sh-dos/sh8.c    Thu Jul 05 19:50:34 1990
  1938. --- sh-os2/sh8.c    Sat Aug 04 17:44:18 1990
  1939. ***************
  1940. *** 58,63 ****
  1941. --- 58,64 ----
  1942.   #include <errno.h>
  1943.   #include <setjmp.h>
  1944.   #include <stdlib.h>
  1945. + #include <stdio.h>
  1946.   #include <fcntl.h>
  1947.   #include <io.h>
  1948.   #include <stdarg.h>
  1949. ***************
  1950. *** 594,600 ****
  1951.   /* Try the file name and then with a .sh appended */
  1952.   
  1953.       if ((i = Check_Script (strcpy (local_path, path), params, nargs)) < 0)
  1954. !     i = Check_Script (strcat (local_path, ".sh"), params, nargs);
  1955.   
  1956.       DELETE (local_path);
  1957.       return i;
  1958. --- 595,602 ----
  1959.   /* Try the file name and then with a .sh appended */
  1960.   
  1961.       if ((i = Check_Script (strcpy (local_path, path), params, nargs)) < 0)
  1962. !       if ((i = Check_Script (strcat (local_path, ".sh"), params, nargs)) == 0)
  1963. !         strcpy(path, local_path);
  1964.   
  1965.       DELETE (local_path);
  1966.       return i;
  1967. diff -cbBw sh-dos/sh9.c sh-os2/sh9.c
  1968. *** sh-dos/sh9.c    Thu Jul 05 19:50:34 1990
  1969. --- sh-os2/sh9.c    Sat Aug 04 19:02:28 1990
  1970. ***************
  1971. *** 74,84 ****
  1972.   #include <errno.h>
  1973.   #include <setjmp.h>
  1974.   #include <limits.h>
  1975. - #include <dos.h>
  1976.   #include <unistd.h>
  1977. ! #include <dirent.h>
  1978.   #include "sh.h"
  1979.   
  1980.   /* Keyboard functions */
  1981.   
  1982.   #define KF_LENGTH        (sizeof (KF_List) / sizeof (KF_List[0]))
  1983. --- 74,87 ----
  1984.   #include <errno.h>
  1985.   #include <setjmp.h>
  1986.   #include <limits.h>
  1987.   #include <unistd.h>
  1988. ! #include <dir.h>
  1989.   #include "sh.h"
  1990.   
  1991. + #define INCL_NOPM
  1992. + #define INCL_VIO
  1993. + #include <os2.h>
  1994.   /* Keyboard functions */
  1995.   
  1996.   #define KF_LENGTH        (sizeof (KF_List) / sizeof (KF_List[0]))
  1997. ***************
  1998. *** 99,107 ****
  1999.   #define KF_DELETELEFT    0x0e        /* Delete left character    */
  2000.   #define KF_COMPLETE    0x0f        /* Complete file name        */
  2001.   #define KF_DIRECTORY    0x10        /* Complete directory function    */
  2002. ! #define KF_END_FKEYS    0x11        /* End of function keys        */
  2003. ! #define KF_RINGBELL    0x11        /* Ring bell            */
  2004. ! #define KF_HALFHEIGTH    0x12        /* Half height cursor        */
  2005.   
  2006.   /* Function Declarations */
  2007.   
  2008. --- 102,112 ----
  2009.   #define KF_DELETELEFT    0x0e        /* Delete left character    */
  2010.   #define KF_COMPLETE    0x0f        /* Complete file name        */
  2011.   #define KF_DIRECTORY    0x10        /* Complete directory function    */
  2012. ! #define KF_JOBS         0x11            /* Jobs list */
  2013. ! #define KF_END_FKEYS    0x12        /* End of function keys        */
  2014. ! #define KF_RINGBELL    0x12        /* Ring bell            */
  2015. ! #define KF_HALFHEIGTH    0x13        /* Half height cursor        */
  2016.   
  2017.   /* Function Declarations */
  2018.   
  2019. ***************
  2020. *** 130,136 ****
  2021.   static int    Max_Cols  = 80;        /* Max columns            */
  2022.   static int    Max_Lines = 25;        /* Max Lines            */
  2023.   #ifndef NO_HISTORY
  2024. ! static bool    insert_mode = FALSE;
  2025.   static char    *c_buffer_pos;        /* Position in command line    */
  2026.   static char    *end_buffer;        /* End of command line        */
  2027.   static int    m_line = 0;        /* Max write line number    */
  2028. --- 135,141 ----
  2029.   static int    Max_Cols  = 80;        /* Max columns            */
  2030.   static int    Max_Lines = 25;        /* Max Lines            */
  2031.   #ifndef NO_HISTORY
  2032. ! static bool    insert_mode = TRUE;
  2033.   static char    *c_buffer_pos;        /* Position in command line    */
  2034.   static char    *end_buffer;        /* End of command line        */
  2035.   static int    m_line = 0;        /* Max write line number    */
  2036. ***************
  2037. *** 162,180 ****
  2038.       { "WordRight",    0,    't',    KF_WORDRIGHT },
  2039.       { "WordLeft",    0,    's',    KF_WORDLEFT },
  2040.       { "Start",        0,    'G',    KF_START },
  2041. !     { "Clear",        0,    'v',    KF_CLEAR },
  2042.       { "Flush",        0,    'u',    KF_FLUSH },
  2043.       { "End",        0,    'O',    KF_END },
  2044.       { "Insert",        0,    'R',    KF_INSERT },
  2045.       { "DeleteRight",    0,    'S',    KF_DELETERIGHT },
  2046.       { "DeleteLeft",    0x08,    0,    KF_DELETELEFT },
  2047. !     { "Complete",    0,    'w',    KF_COMPLETE },
  2048.       { "Directory",    0,    0x0f,    KF_DIRECTORY },
  2049.   
  2050.   /* End of function keys - flags */
  2051.   
  2052.       { "Bell",        1,    0,    KF_RINGBELL },
  2053. !     { "HalfHeight",    0,    0,    KF_HALFHEIGTH }
  2054.   };
  2055.   
  2056.   /* Arrary of history Items */
  2057. --- 167,186 ----
  2058.       { "WordRight",    0,    't',    KF_WORDRIGHT },
  2059.       { "WordLeft",    0,    's',    KF_WORDLEFT },
  2060.       { "Start",        0,    'G',    KF_START },
  2061. !     { "Clear",        0x1b,    0,    KF_CLEAR },
  2062.       { "Flush",        0,    'u',    KF_FLUSH },
  2063.       { "End",        0,    'O',    KF_END },
  2064.       { "Insert",        0,    'R',    KF_INSERT },
  2065.       { "DeleteRight",    0,    'S',    KF_DELETERIGHT },
  2066.       { "DeleteLeft",    0x08,    0,    KF_DELETELEFT },
  2067. !     { "Complete",    0x09,    0,    KF_COMPLETE },
  2068.       { "Directory",    0,    0x0f,    KF_DIRECTORY },
  2069. +     { "Jobs",        0,    0x94,    KF_JOBS },
  2070.   
  2071.   /* End of function keys - flags */
  2072.   
  2073.       { "Bell",        1,    0,    KF_RINGBELL },
  2074. !     { "HalfHeight",    1,    0,    KF_HALFHEIGTH }
  2075.   };
  2076.   
  2077.   /* Arrary of history Items */
  2078. ***************
  2079. *** 238,244 ****
  2080.   
  2081.       while (TRUE)
  2082.       {
  2083. !     Init_Input (FALSE);            /* Initialise        */
  2084.   
  2085.       while (((a_key = (char)getch ()) != 0x1a) && (a_key != NL) &&
  2086.           (a_key != '\r'))
  2087. --- 244,250 ----
  2088.   
  2089.       while (TRUE)
  2090.       {
  2091. !     Init_Input (TRUE);            /* Initialise        */
  2092.   
  2093.       while (((a_key = (char)getch ()) != 0x1a) && (a_key != NL) &&
  2094.           (a_key != '\r'))
  2095. ***************
  2096. *** 246,251 ****
  2097. --- 252,260 ----
  2098.   
  2099.   /* If function key, get the fkey value */
  2100.   
  2101. +             if ( a_key == 0xE0 )
  2102. +               a_key = 0;
  2103.           if (!a_key)
  2104.           f_key = (char)getch ();
  2105.   
  2106. ***************
  2107. *** 482,487 ****
  2108. --- 491,503 ----
  2109.   
  2110.              return TRUE;
  2111.   
  2112. +         case KF_JOBS:
  2113. +         v1_putc (NL);
  2114. +             dojobs(NULL);
  2115. +         put_prompt (last_prompt);
  2116. +         read_cursor_position ();
  2117. +             return TRUE;
  2118.       case KF_DIRECTORY:        /* File name directory        */
  2119.           fn_search = TRUE;
  2120.   
  2121. ***************
  2122. *** 521,540 ****
  2123.   static void    set_cursor_shape (mode)
  2124.   bool        mode;
  2125.   {
  2126. !     union REGS        r;
  2127.   
  2128. ! /* Get the current cursor position to get the cursor lines */
  2129.   
  2130. !     r.h.ah = 0x03;
  2131. !     int86 (0x10, &r, &r);
  2132. ! /* Reset the type */
  2133. !     r.h.ah = 0x01;
  2134. !     r.h.ch = (unsigned char)(!mode ? r.h.cl - 1
  2135. !                    : (KF_List[KF_HALFHEIGTH].akey
  2136. !                     ? (r.h.cl / 2) + 1 : 1));
  2137. !     int86 (0x10, &r, &r);
  2138.   }
  2139.   #endif
  2140.   
  2141. --- 537,550 ----
  2142.   static void    set_cursor_shape (mode)
  2143.   bool        mode;
  2144.   {
  2145. !   VIOCURSORINFO vioci;
  2146.   
  2147. !   vioci.yStart = mode ? (KF_List[KF_HALFHEIGTH].akey ? -50 : 0) : -90;
  2148. !   vioci.cEnd = -100;
  2149. !   vioci.cx = 0;
  2150. !   vioci.attr = 0;
  2151.   
  2152. !   VioSetCurType(&vioci, 0);
  2153.   }
  2154.   #endif
  2155.   
  2156. ***************
  2157. *** 542,553 ****
  2158.   
  2159.   static void    read_cursor_position ()
  2160.   {
  2161. !     union REGS    r;
  2162.   
  2163. !     r.h.ah = 0x03;                /* Read cursor position    */
  2164. !     r.h.bh = 0;                    /* Page zero        */
  2165. !     int86 (0x10, &r, &r);
  2166. !     s_cursor = (r.h.dh * Max_Cols) + r.h.dl;
  2167.   }
  2168.   
  2169.   /* Re-position the cursor */
  2170. --- 552,561 ----
  2171.   
  2172.   static void    read_cursor_position ()
  2173.   {
  2174. !     USHORT usRow, usColumn;
  2175.   
  2176. !     VioGetCurPos(&usRow, &usColumn, 0);
  2177. !     s_cursor = (usRow * Max_Cols) + usColumn;
  2178.   }
  2179.   
  2180.   /* Re-position the cursor */
  2181. ***************
  2182. *** 557,579 ****
  2183.   int        new;
  2184.   {
  2185.       int        diff;
  2186. !     union REGS    r;
  2187.   
  2188. !     r.h.ah = 0x02;                /* Set new position    */
  2189. !     r.h.bh = 0;                    /* Page zero        */
  2190. !     r.h.dh = (unsigned char)(new / Max_Cols);
  2191. !     r.h.dl = (unsigned char)(new % Max_Cols);
  2192.   
  2193.   /* Are we at the bottom of the page? */
  2194.   
  2195. !     if (r.h.dh >= (unsigned char)Max_Lines)
  2196.       {
  2197. !     diff = r.h.dh + 1 - Max_Lines;
  2198. !     r.h.dh = (unsigned char)(Max_Lines - 1);
  2199.       s_cursor -= Max_Cols * diff;
  2200.       }
  2201.   
  2202. !     int86 (0x10, &r, &r);
  2203.   }
  2204.   
  2205.   /* Erase to end of line (avoid need for STUPID ansi.sys memory eater!) */
  2206. --- 565,585 ----
  2207.   int        new;
  2208.   {
  2209.       int diff;
  2210. !     USHORT usRow, usColumn;
  2211.   
  2212. !     usRow    = (unsigned char)(new / Max_Cols);
  2213. !     usColumn = (unsigned char)(new % Max_Cols);
  2214.   
  2215.   /* Are we at the bottom of the page? */
  2216.   
  2217. !     if (usRow >= (unsigned char)Max_Lines)
  2218.       {
  2219. !     diff = usRow + 1 - Max_Lines;
  2220. !     usRow = (unsigned char)(Max_Lines - 1);
  2221.       s_cursor -= Max_Cols * diff;
  2222.       }
  2223.   
  2224. !     VioSetCurPos(usRow, usColumn, 0);
  2225.   }
  2226.   
  2227.   /* Erase to end of line (avoid need for STUPID ansi.sys memory eater!) */
  2228. ***************
  2229. *** 580,611 ****
  2230.   
  2231.   static void    erase_to_end_of_line ()
  2232.   {
  2233. !     union REGS        r;
  2234. !     unsigned char    backg;
  2235. ! /* Get the background attribute of the cursor */
  2236.   
  2237. !     r.h.ah = 0x08;
  2238. !     r.h.bh = 0;
  2239. !     int86 (0x10, &r, &r);
  2240. !     backg = r.h.ah & 0x07;
  2241. !     r.h.ah = 0x03;
  2242. !     r.h.bh = 0;
  2243. !     int86 (0x10, &r, &r);
  2244. ! /* Check that we use the correct m_line */
  2245. !     if (m_line < r.h.dh)
  2246. !     m_line = r.h.dh;
  2247. !     if ((r.x.cx = Max_Cols - r.h.dl + (m_line - r.h.dh) * Max_Cols) > 0)
  2248. !     {
  2249. !     r.x.ax = 0x0a20;
  2250. !     r.x.bx = backg;
  2251. !     int86 (0x10, &r, &r);
  2252.       }
  2253. - }
  2254.   
  2255.   /* Generate the new cursor position */
  2256.   
  2257. --- 586,596 ----
  2258.   
  2259.   static void    erase_to_end_of_line ()
  2260.   {
  2261. !     USHORT usRow, usColumn;
  2262.   
  2263. !     VioGetCurPos(&usRow, &usColumn, 0);
  2264. !     VioWrtNChar(" ", Max_Cols - usColumn, usRow, usColumn, 0);
  2265.   }
  2266.   
  2267.   /* Generate the new cursor position */
  2268.   
  2269. ***************
  2270. *** 1069,1075 ****
  2271.       int            fn_len, pre_len, i;
  2272.       DIR            *dn;
  2273.       char        d_name [NAME_MAX + 1];
  2274. !     struct dirent    *d_ce;
  2275.       int            found_cnt = 0;
  2276.       int            max_per_line;
  2277.       static char        *ms_drive = "a:/";
  2278. --- 1054,1060 ----
  2279.       int            fn_len, pre_len, i;
  2280.       DIR            *dn;
  2281.       char        d_name [NAME_MAX + 1];
  2282. !     struct direct    *d_ce;
  2283.       int            found_cnt = 0;
  2284.       int            max_per_line;
  2285.       static char        *ms_drive = "a:/";
  2286. ***************
  2287. *** 1176,1182 ****
  2288.   
  2289.   /* Scan the directory */
  2290.   
  2291. !     while ((d_ce = readdir (dn)) != (struct dirent *)NULL)
  2292.       {
  2293.       if (strnicmp (d_ce->d_name, fn_mstart, fn_len) == 0)
  2294.       {
  2295. --- 1161,1167 ----
  2296.   
  2297.   /* Scan the directory */
  2298.   
  2299. !     while ((d_ce = readdir (dn)) != (struct direct *)NULL)
  2300.       {
  2301.       if (strnicmp (d_ce->d_name, fn_mstart, fn_len) == 0)
  2302.       {
  2303. ***************
  2304. *** 1269,1274 ****
  2305. --- 1254,1260 ----
  2306.       c_buffer_pos = l_buffer;    /* Initialise            */
  2307.       end_buffer = l_buffer;
  2308.       insert_mode = im;
  2309. +     set_cursor_shape (insert_mode);
  2310.       M_length = -1;
  2311.   
  2312.   /* Reset max line length and get the number of columns */
  2313. ***************
  2314. *** 1411,1426 ****
  2315.   
  2316.   void    In_Col_Zero ()
  2317.   {
  2318. !     union REGS        r;
  2319.   
  2320.       Get_Screen_Params ();
  2321.       read_cursor_position ();
  2322.   
  2323. !     r.h.ah = 0x08;
  2324. !     r.h.bh = 0x00;
  2325. !     int86 (0x10, &r, &r);
  2326.   
  2327. !     if ((s_cursor % Max_Cols) || (r.h.al != ' '))
  2328.       v1_putc (NL);
  2329.   }
  2330.   
  2331. --- 1397,1413 ----
  2332.   
  2333.   void    In_Col_Zero ()
  2334.   {
  2335. !     CHAR str[1];
  2336. !     USHORT cb = sizeof(str);
  2337. !     USHORT usRow, usColumn;
  2338.   
  2339.       Get_Screen_Params ();
  2340.       read_cursor_position ();
  2341.   
  2342. !     VioGetCurPos(&usRow, &usColumn, 0);
  2343. !     VioReadCharStr(str, &cb, usRow, usColumn, 0);
  2344.   
  2345. !     if ((s_cursor % Max_Cols) || (str[0] != ' '))
  2346.       v1_putc (NL);
  2347.   }
  2348.   
  2349. ***************
  2350. *** 1428,1453 ****
  2351.   
  2352.   static void    Get_Screen_Params ()
  2353.   {
  2354. !     union REGS        r;
  2355. !     Max_Cols = *(int *)(0x0040004aL);
  2356. !     Max_Lines = 25;
  2357.   
  2358. ! /* Is this an EGA?  This test was found in NANSI.SYS */
  2359. !     r.h.ah = 0x12;
  2360. !     r.x.bx = 0xff10;
  2361. !     int86 (0x10, &r, &r);
  2362. !     if (r.x.bx & 0xfefc)
  2363. !     return;
  2364. ! /* Else read the number of rows */
  2365.   
  2366. !     r.x.ax = 0x1130;
  2367. !     r.h.bh = 0;
  2368. !     int86 (0x10, &r, &r);
  2369. !     Max_Lines = r.h.dl + 1;
  2370.   }
  2371.   
  2372.   /* Ring Bell ? */
  2373. --- 1415,1427 ----
  2374.   
  2375.   static void    Get_Screen_Params ()
  2376.   {
  2377. !     VIOMODEINFO viomi;
  2378.   
  2379. !     viomi.cb = sizeof(viomi);
  2380. !     VioGetMode(&viomi, 0);
  2381.   
  2382. !     Max_Cols  = viomi.col;
  2383. !     Max_Lines = viomi.row;
  2384.   }
  2385.   
  2386.   /* Ring Bell ? */
  2387. diff -cbBw sh-dos/sh10.c sh-os2/sh10.c
  2388. *** sh-dos/sh10.c    Thu Jul 05 19:50:22 1990
  2389. --- sh-os2/sh10.c    Fri Aug 03 20:26:34 1990
  2390. ***************
  2391. *** 30,36 ****
  2392.   #include <sys/stat.h>
  2393.   #include <stdio.h>
  2394.   #include <process.h>
  2395. - #include <dos.h>
  2396.   #include <signal.h>
  2397.   #include <errno.h>
  2398.   #include <setjmp.h>
  2399. --- 30,35 ----
  2400. diff -cbBw sh-dos/stdargv.c sh-os2/stdargv.c
  2401. *** sh-dos/stdargv.c    Sat Feb 17 00:15:50 1990
  2402. --- sh-os2/stdargv.c    Sat Aug 04 16:23:50 1990
  2403. ***************
  2404. *** 32,51 ****
  2405.   #include <stdio.h>            /* Standard I/O delarations         */
  2406.   #include <stdlib.h>            /* Standard library functions       */
  2407.   #include <errno.h>            /* Error number declarations        */
  2408. - #include <dos.h>            /* DOS functions declarations       */
  2409. - #include <bios.h>            /* BIOS functions declarations      */
  2410.   #include <ctype.h>            /* Character type declarations      */
  2411.   #include <string.h>            /* String library functions         */
  2412.   #include <limits.h>            /* String library functions         */
  2413.   #include <fcntl.h>            /* File Control Declarations        */
  2414.   #include <io.h>                /* Input/Output Declarations        */
  2415. ! #include <dirent.h>            /* Direction I/O functions        */
  2416.   
  2417.   /*
  2418.    *  DATA DEFINITIONS:
  2419.    */
  2420.   
  2421. ! #define MAX_LINE    160        /* Max line length        */
  2422.   #define S_ENTRY        sizeof (char *)
  2423.   
  2424.   /*
  2425. --- 32,54 ----
  2426.   #include <stdio.h>            /* Standard I/O delarations         */
  2427.   #include <stdlib.h>            /* Standard library functions       */
  2428.   #include <errno.h>            /* Error number declarations        */
  2429.   #include <ctype.h>            /* Character type declarations      */
  2430.   #include <string.h>            /* String library functions         */
  2431.   #include <limits.h>            /* String library functions         */
  2432.   #include <fcntl.h>            /* File Control Declarations        */
  2433.   #include <io.h>                /* Input/Output Declarations        */
  2434. ! #include <changes.h>
  2435. ! #include <dir.h>            /* Direction I/O functions        */
  2436.   
  2437. + #define INCL_NOPM
  2438. + #define INCL_DOS
  2439. + #include <os2.h>
  2440.   /*
  2441.    *  DATA DEFINITIONS:
  2442.    */
  2443.   
  2444. ! #define MAX_LINE    256        /* Max line length        */
  2445.   #define S_ENTRY        sizeof (char *)
  2446.   
  2447.   /*
  2448. ***************
  2449. *** 71,76 ****
  2450. --- 74,82 ----
  2451.   extern char    **__argv;         /* Current argument address    */
  2452.   extern int    __argc;         /* Current argument count    */
  2453.   
  2454. + extern unsigned _aenvseg;
  2455. + extern unsigned _acmdln;
  2456.   /*
  2457.    *  MODULE ABSTRACT: _setargv
  2458.    *
  2459. ***************
  2460. *** 80,87 ****
  2461.   void    _setargv ()
  2462.   {
  2463.                       /* Set up pointer to command line */
  2464. !     char far        *argvp = (char far *)((((long)_psp) << 16) + 0x081L);
  2465. !     unsigned int    envs = *(int far *)((((long)_psp) << 16) + 0x02cL);
  2466.       char far        *s;         /* Temporary string pointer        */
  2467.   #ifndef M_I86LM
  2468.       char        buf[MAX_LINE];    /* Temporary space        */
  2469. --- 86,92 ----
  2470.   void    _setargv ()
  2471.   {
  2472.                       /* Set up pointer to command line */
  2473. !     char far        *argvp = MAKEP(_aenvseg, _acmdln);
  2474.       char far        *s;         /* Temporary string pointer        */
  2475.   #ifndef M_I86LM
  2476.       char        buf[MAX_LINE];    /* Temporary space        */
  2477. ***************
  2478. *** 110,126 ****
  2479.   /* In the case of DOS 3+, we look in the environment space */
  2480.   
  2481.       else
  2482. !     {
  2483. !     s = (char far *)(((long)envs) << 16);
  2484. !     while (*s)
  2485. !     {
  2486. !         while (*(s++) != 0);
  2487. !     }
  2488.   
  2489. -     s += 3;
  2490. -     }
  2491.       _pgmptr = s;
  2492.   
  2493.   #ifndef M_I86LM
  2494. --- 115,122 ----
  2495.   /* In the case of DOS 3+, we look in the environment space */
  2496.   
  2497.       else
  2498. !     for ( s = argvp; *(s - 1); s-- );
  2499.   
  2500.       _pgmptr = s;
  2501.   
  2502.   #ifndef M_I86LM
  2503. ***************
  2504. *** 234,240 ****
  2505.       char        *name;        /* Match string            */
  2506.       char        *p, *p1;
  2507.       DIR            *dp;
  2508. !     struct dirent    *c_de;
  2509.       unsigned int    c_drive;    /* Current drive        */
  2510.       unsigned int    m_drive;    /* Max drive            */
  2511.       unsigned int    s_drive;    /* Selected drive        */
  2512. --- 230,236 ----
  2513.       char        *name;        /* Match string            */
  2514.       char        *p, *p1;
  2515.       DIR            *dp;
  2516. !     struct direct    *c_de;
  2517.       unsigned int    c_drive;    /* Current drive        */
  2518.       unsigned int    m_drive;    /* Max drive            */
  2519.       unsigned int    s_drive;    /* Selected drive        */
  2520. ***************
  2521. *** 241,246 ****
  2522. --- 237,244 ----
  2523.       unsigned int    x_drive, y_drive;    /* Dummies        */
  2524.       char        *multi;        /* Multi-drive flag        */
  2525.       char        t_drive[2];
  2526. +     ULONG               l_map;
  2527. +     int                 cnt;
  2528.   
  2529.   /* Convert file name to lower case */
  2530.   
  2531. ***************
  2532. *** 250,283 ****
  2533.   
  2534.       if ((multi = _ex_multi_drive (prefix)) != (char *)NULL)
  2535.       {
  2536. !     _dos_getdrive (&c_drive);    /* Get number of drives        */
  2537. !     _dos_setdrive (c_drive, &m_drive);
  2538.       t_drive[1] = 0;
  2539.   
  2540. !     for (s_drive = 1; s_drive <= m_drive; ++s_drive)
  2541.       {
  2542. !         _dos_setdrive (s_drive, &x_drive);
  2543. !         _dos_getdrive (&y_drive);
  2544. !         _dos_setdrive (c_drive, &x_drive);
  2545. ! /* Check to see if the second diskette drive is really there */
  2546. !         if (((_bios_equiplist () & 0x00c0) == 0x0000) && (s_drive == 2))
  2547. !         continue;
  2548. ! /* If the drive exists and is in our list - process it */
  2549.           *multi = 0;
  2550. -         *t_drive = (char)(s_drive + 'a' - 1);
  2551.   
  2552. !         if ((y_drive == s_drive) && pnmatch (t_drive, prefix, 0))
  2553.           {
  2554.           *multi = ':';
  2555. !         *fn = *t_drive;
  2556.           strcpy (fn + 1, multi);
  2557.           f_count += ex_pfield (fn, postfix);
  2558.           }
  2559.           *multi = ':';
  2560.       }
  2561.   
  2562. --- 248,270 ----
  2563.   
  2564.       if ((multi = _ex_multi_drive (prefix)) != (char *)NULL)
  2565.       {
  2566. !         DosQCurDisk((PUSHORT) &c_drive, &l_map);
  2567.       t_drive[1] = 0;
  2568.   
  2569. !         for ( cnt = 1; cnt <= 26; cnt++, l_map >>= 1 )
  2570. !           if ( l_map & 1L )
  2571.         {
  2572. !           t_drive[0] = (char)(cnt + 'a' - 1);
  2573.                 *multi = 0;
  2574.   
  2575. !           if (pnmatch (t_drive, prefix, 0))
  2576.             {
  2577.                   *multi = ':';
  2578. !           fn[0] = t_drive[0];
  2579.             strcpy (fn + 1, multi);
  2580.             f_count += ex_pfield (fn, postfix);
  2581.             }
  2582. !               else
  2583.                   *multi = ':';
  2584.         }
  2585.   
  2586. ***************
  2587. *** 342,348 ****
  2588.   
  2589.   /* Are there any matches */
  2590.   
  2591. !     while ((c_de = readdir (dp)) != (struct dirent *)NULL)
  2592.       {
  2593.       if ((*c_de->d_name == '.') && (*name != '.'))
  2594.           continue;
  2595. --- 329,335 ----
  2596.   
  2597.   /* Are there any matches */
  2598.   
  2599. !     while ((c_de = readdir (dp)) != (struct direct *)NULL)
  2600.       {
  2601.       if ((*c_de->d_name == '.') && (*name != '.'))
  2602.           continue;
  2603. diff -cbBw sh-dos/unistd.h sh-os2/unistd.h
  2604. *** sh-dos/unistd.h    Sat Feb 17 00:15:34 1990
  2605. --- sh-os2/unistd.h    Mon May 21 20:26:10 1990
  2606. ***************
  2607. *** 4,10 ****
  2608.   /*  unistd.h  */
  2609.   
  2610.   #include <sys/types.h>
  2611. ! #include <sys/proto.h>
  2612.   
  2613.   /* Definition for NULL pointer */
  2614.   
  2615. --- 4,11 ----
  2616.   /*  unistd.h  */
  2617.   
  2618.   #include <sys/types.h>
  2619. ! #include <proto.h>
  2620. ! #include <changes.h>
  2621.   
  2622.   /* Definition for NULL pointer */
  2623.   
  2624.