home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BSRC_250.LZH / B_SPAWN.C < prev    next >
C/C++ Source or Header  |  1991-09-15  |  14KB  |  442 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*            This module was originally written by Bob Hartman             */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*                        BinkleyTerm "Spawn" module                        */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.250.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  27. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  28. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  29. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  30. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /* You can contact Bit Bucket Software Co. at any one of the following      */
  34. /* addresses:                                                               */
  35. /*                                                                          */
  36. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  37. /* P.O. Box 460398                AlterNet 7:491/0                          */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                Internet f491.n343.z1.fidonet.org         */
  40. /*                                                                          */
  41. /* Please feel free to contact us at any time to share your comments about  */
  42. /* our software and/or licensing policies.                                  */
  43. /*                                                                          */
  44. /*--------------------------------------------------------------------------*/
  45.  
  46. /* Include this file before any other includes or defines! */
  47.  
  48. #include "includes.h"
  49.  
  50. #ifndef OS_2
  51. /*
  52.  
  53.    We now use Thomas Wagner's EXEC module to do our swapping.
  54.    There's probably no good reason why we can't just hack our
  55.    code to work with his as distributed. We'll put that on the
  56.    wishlist. For now, we hacked his and you'll find the
  57.    appropriate excerpts below.
  58.  
  59.  
  60.  
  61.    EXEC.H: EXEC function with memory swap - Main function header file.
  62.  
  63.    Public domain software by
  64.  
  65.         Thomas Wagner
  66.         Ferrari electronic GmbH
  67.         Beusselstrasse 27
  68.         D-1000 Berlin 21
  69.         Germany
  70. */
  71.  
  72. extern int do_exec (char *xfn, char *pars, int spawn, unsigned needed,
  73.                     char **envp);
  74.  
  75. /*
  76.    The EXEC function.
  77.  
  78.       Parameters:
  79.  
  80.          xfn      is a string containing the name of the file
  81.                   to be executed.
  82.  
  83.          pars     The program parameters.
  84.  
  85.          spawn    If 0, the function will terminate after the 
  86.                   EXECed program returns, the function will not return.
  87.  
  88.                   NOTE: If the program file is not found, the function 
  89.                         will always return with the appropriate error 
  90.                         code, even if 'spawn' is 0.
  91.  
  92.                   If non-0, the function will return after executing the
  93.                   program. If necessary (see the "needed" parameter),
  94.                   memory will be swapped out before executing the program.
  95.                   For swapping, spawn must contain a combination of the 
  96.                   following flags:
  97.  
  98.                      USE_EMS  (0x01)  - allow EMS swap
  99.                      USE_XMS  (0x02)  - allow XMS swap
  100.                      USE_FILE (0x04)  - allow File swap
  101.  
  102.                   The order of trying the different swap methods can be
  103.                   controlled with one of the flags
  104.  
  105.                      EMS_FIRST (0x00) - EMS, XMS, File (default)
  106.                      XMS_FIRST (0x10) - XMS, EMS, File
  107.  
  108.                   If swapping is to File, the attribute of the swap file
  109.                   can be set to "hidden", so users are not irritated by
  110.                   strange files appearing out of nowhere with the flag
  111.  
  112.                      HIDE_FILE (0x40)    - create swap file as hidden
  113.  
  114.                   and the behaviour on Network drives can be changed with
  115.  
  116.                      NO_PREALLOC (0x100) - don't preallocate
  117.                      CHECK_NET (0x200)   - don't preallocate if file on net.
  118.  
  119.                   This checking for Network is mainly to compensate for
  120.                   a strange slowdown on Novell networks when preallocating
  121.                   a file. You can either set NO_PREALLOC to avoid allocation
  122.                   in any case, or let the prep_swap routine decide whether
  123.                   to do preallocation or not depending on the file being
  124.                   on a network drive (this will only work with DOS 3.1 or 
  125.                   later).
  126.  
  127.          needed   The memory needed for the program in paragraphs (16 Bytes).
  128.                   If not enough memory is free, the program will 
  129.                   be swapped out. 
  130.                   Use 0 to never swap, 0xffff to always swap. 
  131.                   If 'spawn' is 0, this parameter is irrelevant.
  132.  
  133.          envp     The environment to be passed to the spawned
  134.                   program. If this parameter is NULL, a copy
  135.                   of the parent's environment is used (i.e.
  136.                   'putenv' calls have no effect). If non-NULL,
  137.                   envp must point to an array of pointers to
  138.                   strings, terminated by a NULL pointer (the
  139.                   standard variable 'environ' may be used).
  140.  
  141.       Return value:
  142.  
  143.          0x0000..00FF: The EXECed Program's return code
  144.          0x0101:       Error preparing for swap: no space for swapping
  145.          0x0102:       Error preparing for swap: program too low in memory
  146.          0x0200:       Program file not found
  147.          0x03xx:       DOS-error-code xx calling EXEC
  148.          0x0400:       Error allocating environment buffer
  149.          0x0500:       Swapping requested, but prep_swap has not 
  150.                        been called or returned an error.
  151.          0x0501:       MCBs don't match expected setup
  152.          0x0502:       Error while swapping out
  153. */
  154.  
  155.  
  156. /* Return codes (only upper byte significant) */
  157.  
  158. #define RC_PREPERR   0x0100
  159. #define RC_NOFILE    0x0200
  160. #define RC_EXECERR   0x0300
  161. #define RC_ENVERR    0x0400
  162. #define RC_SWAPERR   0x0500
  163.  
  164. /* Swap method and option flags */
  165.  
  166. #define USE_EMS      0x01
  167. #define USE_XMS      0x02
  168. #define USE_FILE     0x04
  169. #define EMS_FIRST    0x00
  170. #define XMS_FIRST    0x10
  171. #define HIDE_FILE    0x40
  172. #define NO_PREALLOC  0x100
  173. #define CHECK_NET    0x200
  174.  
  175. #define USE_ALL      (USE_EMS | USE_XMS | USE_FILE)
  176.  
  177. #endif
  178.  
  179. void b_spawn (char *cmd_str)
  180. {
  181.    char this_dir[80];
  182.  
  183. #ifndef OS_2
  184.    char *command;
  185.    char *p;
  186. #ifndef __TURBOC__
  187.    unsigned j;
  188. #endif /* ifndef __TURBOC__ */
  189. #ifdef __ZTC__
  190.    char **environ;
  191. #endif
  192.  
  193. #else /* ifndef OS_2 */
  194.    char *comspec;
  195. #endif /* ifndef OS_2 */
  196.  
  197.    if (saved_TZ != NULL)
  198.       {
  199.       (void) putenv (saved_TZ);
  200.       tzset ();
  201.       }
  202.  
  203.    /* Save where we are */
  204.    (void) fflush (status_log);
  205.    (void) real_flush (fileno (status_log));
  206.    need_update = 0;
  207.  
  208.    /* Save where we are */
  209.    (void) getcwd (this_dir, 79);
  210.  
  211. #ifdef OS_2
  212.  
  213.    if (cmd_str)
  214.       system (cmd_str);
  215.    else
  216.       {
  217.       comspec = getenv("COMSPEC");
  218.       if (comspec)
  219.    spawnlp (P_WAIT, comspec, comspec, NULL);
  220.       }
  221.    DosSelectDisk (*this_dir - 'A' + 1);
  222.    chdir (this_dir);
  223.  
  224. #else   /* ifdef OS_2 */
  225.  
  226.    if ((p = getenv ("COMSPEC")) == NULL)
  227.       p = "COMMAND.COM";
  228.  
  229. #ifdef MEWEL
  230.    VidShowCursor();
  231. #endif
  232.  
  233. #ifdef __ZTC__
  234.    environ = NULL;
  235. #endif
  236.  
  237.    if (swapdir == NULL)
  238.       {
  239.       if (cmd_str != NULL)
  240.    (void) system (cmd_str);
  241.       else
  242.    (void) spawnlp (P_WAIT, p, p, NULL);
  243.       }
  244.    else
  245.       {
  246.       if (cmd_str != NULL)
  247.          {
  248.          command = calloc (1, strlen (cmd_str) + 4);
  249.          if (command != NULL)
  250.             {
  251.             (void) strcpy (command, "/c ");
  252.             (void) strcat (command, cmd_str);
  253.             (void) do_exec (p, command, USE_ALL, 0xffff, environ);
  254.             free (command);
  255.             }
  256.          }
  257.       else  (void) do_exec (p, "", USE_ALL, 0xffff, environ);
  258.  
  259.       }
  260.  
  261.    /* Go back to the proper directory */
  262. #ifdef __TURBOC__
  263.    setdisk ((unsigned) (this_dir[0] - 'A'));
  264. #else /* __TURBOC__ */
  265.    _dos_setdrive ((unsigned) ((int) this_dir[0] - 'A' + 1), &j);
  266. #endif /* __TURBOC__ */
  267.    (void) chdir (this_dir);
  268.  
  269. #endif /* OS_2 */
  270.  
  271.    if (saved_TZ != NULL)
  272.       {
  273.       (void) putenv ("TZ=GMT0");
  274.       tzset ();
  275.       }
  276. #ifdef MEWEL
  277.   VidHideCursor();
  278.   WinDrawAllWindows();
  279. #endif
  280.  
  281. }
  282.  
  283. #ifndef OS_2
  284.  
  285. /*
  286.    EXEC.C: EXEC function with memory swap - Prepare parameters.
  287.  
  288.    Public domain software by
  289.  
  290.         Thomas Wagner
  291.         Ferrari electronic GmbH
  292.         Beusselstrasse 27
  293.         D-1000 Berlin 21
  294.         Germany
  295.  
  296.         BIXname: twagner
  297. */
  298.  
  299. #define SWAP_FILENAME "$$AAAAAA.AAA" 
  300.  
  301. /* internal flags for prep_swap */
  302.  
  303. #define CREAT_TEMP      0x0080
  304. #define DONT_SWAP_ENV   0x4000
  305.  
  306. #ifndef __TURBOC__
  307. #define stpcpy(d,s)     (strcpy (d, s), d + strlen (s))
  308. #endif
  309.  
  310. #ifdef __cplusplus
  311. extern "C" int
  312. #else
  313. extern int _cdecl
  314. #endif
  315. do_spawn (int swapping,     /* swap if non-0 */
  316.           char *xeqfn,      /* file to execute */
  317.           char *cmdtail,    /* command tail string */
  318.           unsigned envlen,  /* environment length */
  319.           char *envp);      /* environment pointer */
  320.  
  321. #ifdef __cplusplus
  322. extern "C" int
  323. #else
  324. extern int _cdecl
  325. #endif
  326. prep_swap (int method,      /* swap method */
  327.            char *swapfn);   /* swap file name and/or path */
  328.  
  329. int do_exec (char *exfn, char *epars, int spwn, unsigned needed, char **envp)
  330. {
  331.    static char swapfn [82];
  332.    static char execfn [82];
  333.    unsigned avail;
  334.    union REGS regs;
  335.    unsigned envlen;
  336.    int rc;
  337.    int idx;
  338.    char **env;
  339.    char *ep, *envptr, *envbuf;
  340.    int swapping;
  341.  
  342.    (void) strcpy (execfn, exfn);
  343.  
  344.    /* Now create a copy of the environment if the user wants it. */
  345.  
  346.    envlen = 0;
  347.    envptr = envbuf = NULL;
  348.  
  349.    if (envp != NULL)
  350.       for (env = envp; *env != NULL; env++)
  351.          envlen += strlen (*env) + 1;
  352.  
  353.    if (envlen)
  354.       {
  355.       /* round up to paragraph, and alloc another paragraph leeway */
  356.       envlen = (envlen + 32) & 0xfff0;
  357.       envbuf = (char *)malloc (envlen);
  358.       if (envbuf == NULL)
  359.          return RC_ENVERR;
  360.  
  361.       /* align to paragraph */
  362.       envptr = envbuf;
  363.       if (FP_OFF (envptr) & 0x0f)
  364.          envptr += 16 - (FP_OFF (envptr) & 0x0f);
  365.       ep = envptr;
  366.  
  367.       for (env = envp; *env != NULL; env++)
  368.          {
  369.          ep = stpcpy (ep, *env) + 1;
  370.          }
  371.       *ep = 0;
  372.       }
  373.  
  374.    if (!spwn)
  375.       swapping = -1;
  376.    else
  377.       {
  378.       /* Determine amount of free memory */
  379.  
  380.       regs.x.ax = 0x4800;
  381.       regs.x.bx = 0xffff;
  382.       (void) intdos (®s, ®s);
  383.       avail = regs.x.bx;
  384.  
  385.       /* No swapping if available memory > needed */
  386.  
  387.       if (needed < avail)
  388.          swapping = 0;
  389.       else
  390.          {
  391.          /* Swapping necessary, use 'TMP' or 'TEMP' environment variable
  392.            to determine swap file path if defined. */
  393.  
  394.          swapping = spwn;
  395.          if (spwn & USE_FILE)
  396.             {
  397.             (void) strcpy (swapfn, swapdir);
  398.  
  399.             if (_osmajor >= 3)
  400.                swapping |= CREAT_TEMP;
  401.             else
  402.                {
  403.                (void) strcat (swapfn, SWAP_FILENAME);
  404.                idx = strlen (swapfn) - 1;
  405.                while (dexists (swapfn))
  406.                   {
  407.                   if (swapfn [idx] == 'Z')
  408.                      idx--;
  409.                   if (swapfn [idx] == '.')
  410.                      idx--;
  411.                   swapfn [idx]++;
  412.                   }
  413.                }
  414.             }
  415.          }
  416.       }
  417.  
  418.    /* All set up, ready to go. */
  419.  
  420.    if (swapping > 0)
  421.       {
  422.       if (!envlen)
  423.          swapping |= DONT_SWAP_ENV;
  424.  
  425.       rc = prep_swap (swapping, swapfn);
  426.       if (rc < 0)
  427.          return RC_PREPERR | -rc;
  428.       }
  429.  
  430.    rc = do_spawn (swapping, execfn, epars, envlen, envptr);
  431.  
  432.    /* Free the environment buffer if it was allocated. */
  433.  
  434.    if (envlen)
  435.       free (envbuf);
  436.  
  437.    return rc;
  438. }
  439.  
  440. #endif /* ifndef OS_2 */
  441.  
  442.