home *** CD-ROM | disk | FTP | other *** search
- SPAWNO v4.10 4/26/91 disk/EMS/XMS/INT15 swapping replacement for spawn()
- (c) Copyright 1990,1991,1992 Ralf Brown. All Rights Reserved.
-
-
- -----------------
- LICENSE
-
- This document and the associated header file, libraries, and source and
- object modules may be freely copied provided that:
- 1) all of the files are copied as a group (such as in a single
- archive). See below for a list of files.
- 2) the files are not modified in any way (including removal or
- alteration of copyright notices or this license)
- 3) no charge beyond a cost-recovery fee not to exceed $5, or a
- general telecommunications connection fee, is made
-
- The source and/or object code comprising the public SPAWNO distribution
- may be incorporated at no charge into programs which are distributed or
- sold to others provided that:
- 1) credit is given in the documentation. A mention such as
- "This product uses the SPAWNO routines by Ralf Brown
- to minimize memory use while shelling to DOS and
- running other programs."
- is sufficient.
- 2) you drop me a line telling me that you are using SPAWNO and
- in which product(s) you are using it (see addresses at the
- end of this file). I'm interested in finding out how wide-
- spread the use of SPAWNO becomes.
-
-
- -----------------
- DISCLAIMER
-
- Although both I and others have tested the code which comprises SPAWNO,
- it is entirely possible that SPAWNO may malfunction in environments or
- under circumstances in which it has not been tested. This code is
- provided AS IS, and the author disclaims any and all responsibility for
- damages (both consequential and incidental) resulting from the use or
- misuse of SPAWNO. Sole responsibility for determining the suitability
- of the code rests with the user.
-
-
- -----------------
- FILES
-
- The disk or archive you received should contain the following files:
-
- SPAWNO.DOC this file
- SPAWNO.H the header file providing prototypes for the functions
- SPAWNx.LIB versions of the library for each of [T]iny, [S]mall,
- [C]ompact, [M]edium, [L]arge, and [H]uge memory
- models.
- SPAWNTP.OBJ Turbo Pascal version of SPAWNO
- SPAWNO.PAS Turbo Pascal unit encapsulating SPAWNO
- SPAWN_MS.ZIP Microsoft C versions of compiler-specific functions
- MSC.BAT replace Turbo C specific functions in libraries with
- Microsoft C versions.
- NOREPLAC.BAT remove replacements for the standard spawn..()
- functions from the libraries.
- SWAPTEST.C example program for testing
- TEST.PAS example program for testing
- SOURCE.ZIP archive containing partial source code for SPAWNO
- _SPAWNO.H header file for recompiling library
- *.C source for the spawn..() and spawn...o() functions
- RULES.ASI shortened and modified Turbo C macro file
- SPAWNO.INC include file for various important constants
- SPAWNPTH.ASM source for the path search
- CHECKEXT.ASM check for 'file', 'file.EXE', and 'file.COM'
- SWAP_EMS.ASM support routines for swapping to EMS
- SWAPLIST.ASM specify which swap types will be linked in
- SPAWNENV.ASM make an environment block from an array of strings
- SPAWNERR.ASM set _doserrno and errno
- MAKEFILE
-
-
- -----------------
- WHAT'S NEW
-
- Changes/fixes since version 4.00:
- Now swaps to disk with non-NULL swap list in large-data memory models
- Now correctly deletes swap file if child program changes directories
- If the given program name is "FOO", and both "FOO" and either
- "FOO.COM" and/or "FOO.EXE" exist in the same directory, it will
- now execute either "FOO.COM" or "FOO.EXE" rather than "FOO", as
- both version 4.00 and the Borland library functions do. To
- execute "FOO", pass "FOO." rather than just "FOO" to the function.
- Fixed bug which may have led to a partially corrupted environment
- in a few circumstances
-
-
- -----------------
- INSTALLATION
-
- If you are using Turbo C, Turbo C++, or Borland C++, simply dearchive
- the libraries and header file and place them where your compiler can
- find them. If you are using Microsoft C, dearchive SPAWN_MS.ZIP and
- then run the MSC batch file to replace the compiler-specific functions
- in the libraries with Microsoft C versions. Please do not run this
- batch file on your original copy of the libraries.
-
- If you are using Turbo Pascal, unarchive SPAWNTP.OBJ and SPAWNO.PAS.
- Compile SPAWNO.PAS and then add a USES SPAWNO; line to your program.
- After that you can call the function SPAWN() as desired. The
- distribution does not contain a pre-compiled version because .TPU
- files are not compatible between different versions of Turbo Pascal.
-
-
- -----------------
- INSTRUCTIONS
-
- As distributed, SPAWNO contains replacements for the standard spawn..()
- functions. You can use SPAWNO with absolutely no changes to your
- existing source code; however, you will probably want to call
- init_SPAWNO() from main(), and include SPAWNO.H for that source file.
- The initialization function takes two arguments: the first is a string
- containing a list of directories (separated by semicolons) in which to
- attempt to store the swap file when swapping to disk. The second
- specifies which swap devices to attempt to use; it may be either
- SWAP_ANY or the ORing or addition of any combination of SWAP_DISK,
- SWAP_EMS, SWAP_EXT, and SWAP_XMS (such as SWAP_DISK|SWAP_XMS). If you
- do not call init_SPAWNO(), the defaults are to attempt all swap devices
- and to store the swap file in the current directory when swapping to
- disk. init_SPAWNO() will set the swap file directory list to the first
- of the following to have a non-NULL, non-empty value: the environment
- variable SWAPDIR, the passed parameter, the environment variable TEMP,
- and the environment variable TMP. Note that init_SPAWNO is the only
- function in the library which uses these environment variables.
-
- After making the above change, recompile your existing code, but include
- the SPAWNO library in the link step. Note that SPAWNO does not support
- the P_OVERLAY spawn type--any calls using that argument should be
- replaced with the corresponding exec..() function. If a SPAWNO function
- is called with P_OVERLAY, it simply returns an error.
-
- For backwards compatibility with previous versions of SPAWNO, and for
- those who (for whatever reason) require the use of both the swapping and
- standard spawn..() functions, there is a second set of functions which
- take an explicit swap directory argument. To use them, include the
- header file SPAWNO.H. Then use the functions provided in this
- archive--spawnvo(), spawnlo(), spawnvpo(), etc--as you would the
- corresponding spawnv(), spawnl(), etc, except replace the first argument
- by a string containing the path where the swap file is to be stored.
- Note that the swap file path is required even when swapping to XMS, EMS,
- or plain extended memory, as SPAWNO will swap to disk anyway if there is
- not enough memory available.
-
- If you require the use of both the swapping and standard spawn..()
- functions, you will need to run the NOREPLAC.BAT batch file to remove
- the modules containing the replacements for the standard functions or
- arrange the linker command line such that SPAWNx.LIB is listed after the
- standard runtime library (for Turbo/Borland C users, the latter requires
- a separate TLINK command, as TCC/BCC places any libraries specified on
- the command line prior to the runtime library). Please do not run
- NOREPLAC on your original copy of the libraries, as the process is
- destructive and cannot be reversed.
-
- The spawn?p??() functions search for both .COM and .EXE files in the
- current directory and then in the pathed directories if no extension is
- given, but use the specified extension if present. If a full pathname
- is given to those functions, only the specified directory is searched.
- If both a path and an extension are given, only that specific file will
- be loaded. The other spawn..() functions check the current directory
- only. For all functions, if the specified filename does not contain an
- extension, SPAWNO will try the exact name given and the name with .COM
- and .EXE extensions. The extension-less name will be used if neither
- .COM nor .EXE exist. To force the use of the extensionless file even
- if a .COM or .EXE with the same name exists in the same directory,
- append a period, i.e. use "PROGRAM." rather than just "PROGRAM" as
- the name.
-
- When linking, you must include SPAWNx.LIB. A sample TCC line would be
-
- tcc -mc <other-flags> sample spawnc.lib library.lib
-
- This results in 208 to 288 bytes remaining in memory (depending on swap
- type) while the spawned program executes. However, if you want to keep
- an interrupt hooked which might be invoked while spawned, you must set
- __spawn_resident large enough that *all* code and data which could be
- invoked by that interrupt is kept resident[1]. SPAWNO automatically
- deactivates INT 23h and INT 24h and restores them before returning to
- the caller unless __spawn_keepints is set to 1, so no extra work is
- required if those two are the only interrupts hooked by the program.
-
- ----
- [1] Due to the segment layout used by C compilers, this option is probably
- useful only when calling SPAWNO from assembly-language code (which can
- localize such code and data near the start of the executable) or a
- small program which uses a large amount of space in the far heap.
-
-
- -----------------
- ERROR MESSAGES
-
- SPAWNO: stack too small, retrying
- SPAWNO did not correctly determine the stack requirements for
- the system on which it is running, but was able to determine
- that the specified minimum size is insufficient. On the retry,
- the stack size is increased by one paragraph. Since SPAWNO
- cannot always detect the problem, which would result in
- memory chain corruption, you should increase the value of
- __spawn_res_stack to prevent a recurrence of this error
- message. For most systems, the default value of 4 paragraphs
- will be sufficient.
-
- SWAP ERR
- The resident stub detected an error while trying to reload the
- main portion of the program and aborted. This may be due to
- loading a TSR while swapped out or deleting the swap file.
-
- SPAWNO: error reloading program, aborting
- The main portion of SPAWNO detected an error while attempting
- to restore the remainder of the program to memory.
-
-
- -----------------
- LIMITATIONS
-
- After freeing all memory owned by the program except the initial (PSP)
- memory block and the environment, at least 384 bytes of conventional
- memory must be available. SPAWNO uses this for its temporary stack.
- This is of particular importance for the Turbo Pascal variant, because
- setting the maximum heap size to the available memory or greater will
- use up all RAM and prevent SPAWNO from allocating its temporary stack
- unless memory is fragmented or there is DOS 5 high memory available.
-
- SPAWNO may report insufficient memory even though the program to be
- executed would fit with up to 600 bytes to spare, due to the fact that
- part of the stack and all of the data used by DOS to start the program
- may be overwritten after the child program starts executing.
-
- Functions which pass an explicit environment attempt to allocate enough
- memory to build the environment block which is passed to the DOS EXEC
- function. If neither malloc() nor a DOS memory allocation request are
- successful, SPAWNO passes the original environment rather than the
- specified environment.
-
- As distributed, SPAWNO functions which do not take an explicit
- environment pointer pass the calling program's original environment to
- the child, rather than the current environment as modified by putenv().
- You may recompile SPAWNO to pass the current environment (see
- _SPAWNO.H); if you do so, the caveat discussed in the previous paragraph
- will apply to all of the spawn..() functions.
-
-
- -----------------
- SUPPORT
-
- Since I am not getting any money, I can't promise any support. Those
- who have purchased the complete source code will receive priority over
- those who haven't, but even they will only receive support to the
- extent that I have spare time....
-
-
- -----------------
- ACKNOWLEDGEMENTS
-
- Thanks to Gene McManus for testing the Microsoft versions of SPAWNO 3.0
- and 4.0.
-
-
- -----------------
- FUTURE PLANS
-
- The next release will drop support for DOS 2.x (which is now over
- seven years old) to reduce the code size and further reduce the size
- of the resident stub.
-
-
- -----------------
- SPAWNO versus THE COMPETITION
-
- Product: SPAWNO XSPAWN SWAP
- Version: 4.02 1.34 1.0
- Author: Ralf Brown Whitney Software Marty Del Vecchio
- Memory models: tsmclh tsmclh tsm
- Supported DOS vers: 2.0-5.0 2.1-5.0 3.0-5.0
- Code size [1]: 4.2-5.6K 4.4-9K 1.5K
- Resident stub (bytes): 208-288 1277+2*env 1.8K+env [2]
- Direct replacement for
- spawn..(): yes yes no
- Use in existing code
- without changes: yes no no
- Swap to disk: yes yes yes
- Swap to EMS: yes yes yes
- Swap to XMS: yes no no
- Swap to INT 15h ext: yes no no
- Multiple swap dirs: yes yes no
- Automatic unique swap
- file naming: yes yes no
- May leave interrupts
- hooked [3]: yes no yes
- Swaps DOS5 high memory: yes ? ?
- Free for any use: yes yes yes
- Source included: partial [4] yes yes
-
- Notes:
- [1] For both SPAWNO and XSPAWN, the amount added to the executable's
- size depends on which functions of the library are called and which
- of the additional C runtime library function that are called by
- SPAWNO/XSPAWN would have been included anyway. SPAWNO's size may
- be reduced by removing one or more swap types; the savings are
- about 400 bytes per swap type (without EMS and non-XMS (INT 15h)
- swapping, SPAWNO would add as little as 3.4K to the executable).
-
- [2] SWAP's resident size depends on the location of the object code
- within the executable. The size reported here is the resident
- size when SWAP immediately follows the Turbo C 2.0 startup code.
-
- [3] For SPAWNO, enough of the program must be left in memory to keep all
- interrupt handlers resident. XSPAWN has no provision for keeping
- an interrupt handler resident unless swapping is disabled; it does
- however permit selection whether a given interrupt handler will
- automatically be restored to its original value or pointed at an
- IRET instruction while swapped out. For SWAP, the swapper module
- must be linked in after all code and data which might be accessed
- by the interrupt handler(s).
-
- [4] Full SPAWNO source code is available for purchase. See ORDER.FRM for
- details.
-
-
- -----------------
- Functions:
- void init_SPAWNO(const char *swap_directories, int swap_types) ;
-
- /* replacements for the standard functions */
- int spawnv(int type, const char *name, const char **args) ;
- int spawnvp(int type, const char *name, const char **args) ;
- int spawnve(int type, const char *name, const char **args,
- const char **env) ;
- int spawnvpe(int type, const char *name, const char **args,
- const char **env) ;
- int spawnl(int type, const char *name, const char *argv0, ...) ;
- int spawnlp(int type, const char *name, const char *argv0, ...) ;
- int spawnle(int type, const char *name, const char *argv0, ...) ;
- int spawnlpe(int type, const char *name, const char *argv0, ...) ;
- int system(const char *command) ;
- /* Note: the above functions return -1 (error) if 'type' is not */
- /* P_WAIT */
-
- /* setup function */
- void init_SPAWNO(const char *overlay_path, int swap_types) ;
- /* setup swapping options for the compatibility functions above */
-
- /* SPAWNO-specific functions */
- int spawnvo(const char *overlay_path, const char *name,
- const char **args) ;
- int spawnvpo(const char *overlay_path, const char *name,
- const char **args) ;
- int spawnveo(const char *overlay_path, const char *name,
- const char **args,const char **env) ;
- int spawnvpeo(const char *overlay_path, const char *name,
- const char **args,const char **env) ;
- int spawnlo(const char *overlay_path, const char *name, ...) ;
- int spawnlpo(const char *overlay_path, const char *name, ...) ;
- int spawnleo(const char *overlay_path, const char *name, ...) ;
- int spawnlpeo(const char *overlay_path, const char *name, ...) ;
- int systemo(const char *overlay_path, const char *command) ;
- /* Note: the ..o() functions use the current directory only if */
- /* overlay_path is NULL; the only function which checks */
- /* the environment variables SWAPDIR and TEMP is */
- /* init_SPAWNO(). */
-
- Global variables:
- char __spawn_xms ;
- Specify whether to use XMS memory for swapping (if available).
- 0 = no, 1 = yes, default = 1
- This variable is set by init_SPAWNO().
- char __spawn_ems ;
- Specify whether to use EMS memory for swapping (if available).
- 0 = no, 1 = yes, default = 1
- This variable is set by init_SPAWNO().
- char __spawn_ext ; /* 0 = don't use non-XMS extended memory for swap */
- Specify whether to use non-XMS extended memory (via INT 15h) for
- swapping (if available). 0 = no, 1 = yes, default = 1
- This variable is set by init_SPAWNO().
- Note: SPAWNO should not be allowed to swap to extended memory if
- running under a multitasker or task switcher, as other programs
- would be able to grab the same memory used by SPAWNO to store the
- swapped-out program. For this reason, SPAWNO automatically
- disables swapping to non-XMS extended memory if it detects that
- TopView, DESQview, or any other TopView API-compatible multi-
- tasker is active, or the DOS 5 task switcher is loaded, or
- MS Windows 3 is running in real or standard mode (enhanced mode
- is not readily detectable from a program, unfortunately).
- const char *pascal ___spawn_swap_dirs ;
- Specify the list of directories in which to attempt to store
- the swap file when swapping to disk. The directories are
- separated by semicolons just as they would be in the PATH
- environment variable. Default = "." (current directory)
- This variable is set by init_SPAWNO().
- Note: SPAWNO will not swap to disk if this variable is set to an
- empty string; if it is set to NULL, SPAWNO will use the default
- of ".".
- char __spawn_keepints ;
- Specify whether to deactivate INT 23h and INT 24h handlers by
- temporarily restoring the vectors stored in the PSP.
- 0 = no, nonzero = yes, default = 0
- char __spawn_swap_UMA ;
- Specify whether to swap out memory blocks in the upper memory
- area (640K-1M). 0 = no, 1 = yes, default = 1
- Note: This option only has an effect under MSDOS 5.0 with the
- line DOS=UMB or DOS=HIGH,UMB in CONFIG.SYS.
- unsigned __spawn_resident ;
- Specify the minimum number of paragraphs in the memory block
- containing the PSP to keep resident while in the child program.
- This value will be increased if necessary to be large enough to
- hold the swapping code; it may also be increased slightly if it
- causes the end of the shrunken PSP block to fall within a
- specific section of SPAWNO's code. You may force the entire
- main block to stay in memory by setting this variable to 0xFFFF;
- however, the environment and any additional memory blocks
- allocated by the program will still be swapped out. default = 0
- Note: in addition to the PSP memory block, a small second block
- is used for the stack needed by the swapping code (see below).
- unsigned __spawn_res_stack ;
- Specify the minimum number of paragraphs of the stack to keep
- resident while in the child program. Default = 4, minimum = 2
- (two paragraphs is only sufficient for bare DOS; TSRs which
- hook INT 21h will increase the stack requirements, but four is
- sufficient for most systems). SPAWNO attempts to compute the
- necessary stack size, but this variable allows the computed
- value to be overridden if necessary.
-
- External functions called by SPAWNO:
- malloc() \ only when passing an array of environment strings
- free() /
-
- External variables referenced by SPAWNO:
- int errno ;
- int _doserrno ;
- unsigned int _psp ;
- char **environ ; (only when passing an array of environment strings)
-
- Other:
- This version of SPAWNO overwrites the PSP, so the commandline
- will be lost unless it was copied before the first spawn().
-
-
- -----------------
- Functions (Turbo Pascal):
- init_SPAWNO(swap_dirs : string ; swap_types : integer ;
- min_resident : integer ; resident_stack : integer) ;
- spawn(program_name : string ; arguments : string ;
- envseg : integer) : integer ;
-
- Global Variables (Turbo Pascal):
- spawno_error : integer ; (error code when spawn() returns -1)
-
-
- -----------------
- Send comments, bug reports, etc. to
-
- Internet: ralf+@cs.cmu.edu
- Fidonet: Ralf Brown 1:129/26.1 (or post a message to me on DR_DEBUG--I
- have to route netmail outside Zone 1
- via Internet -> Fidonet gateways, which
- is not always reliable)
- or
- Ralf Brown
- Suite #26
- 813 Copeland Way
- Pittsburgh, PA 15232
-