📄 readme.doc
字号:
The "no return" mode of EXEC is included for completeness only. It
has some disadvantages over the standard compiler functions for
executing without return. In particular, files are not closed, and
interrupt vectors used by the Run-Time-Library are not restored to
the DOS defaults. If possible, use the standard RTL functions for
this mode.
The assembler module "spawn" must not be the first module linked.
Either put it into a library, or specify spawn.obj as one of the last
objects in the link command or the Turbo project file. The spawn
module will overwrite about 1k at the start of the program image.
Although the contents of this area will be saved, they may not
contain parts of the spawn module itself, since this could destroy
the code being executed. The do_exec function will check for this
condition, and return an error code if the program code could be in
danger.
The calling program may not have interrupt handlers installed when
calling the do_exec function. This includes handlers for Control C
and critical errors. If you want to handle interrupts while the
program is swapped, you will have to modify the spawn module such
that the interrupt handlers are included in the resident part.
All open files will stay open during the EXEC call. This reduces the
number of handles available to the child process. The "C_FILE_INFO"
environment variable created by some C compilers on the standard C
spawn call is not supported. If the NO_INHERIT flag is set in
spawn.asm (default), all open files except for the first five
standard handles will be "hidden" from the child, and thus will not
be inherited. This increases the possible number of open files for
the child, although the system-wide open file limit (the config.sys
FILES= value) still must be high enough to support all open files.
Internal commands are not automatically processed. You can execute
those by loading the command interpreter (by passing an empty string
as the command name). For example:
(C) retcode = do_exec ("dir", "*.*", USE_ALL, 0xffff, environ);
if (retcode == RC_NOFILE)
retcode = do_exec ("", "/c dir *.*", USE_ALL, 0xffff, environ);
(P) retcode := do_exec ('dir', '*.*', USE_ALL, $ffff, true);
if (retcode = RC_NOFILE)
retcode := do_exec ('', '/c dir *.*', USE_ALL, $ffff, true);
CAUTIONS
========
The functions should be compatible with DOS versions down to DOS
2.21, but they have been tested under DOS 3.3, DOS 4.0, DOS 5.0,
DOS 6.0, and DR-DOS 5.0 only.
Compiler compatibility has been tested for Borland C++ 2.0/3.1,
Microsoft C 6.0a, Visual C++ 1.0, and Turbo Pascal 5.5 only. I do not
have access to other compilers. Turbo Pascal 6.0 was reported to work
fine with EXEC. The DOS-extender mode of Turbo Pascal 7.0 (and any
other DOS extender) will not work with EXEC.
Spawning a command that exits and stays resident (TSR), like PRINT or
Sidekick, will fragment memory and prevent a return to the calling
program. This should, however, not crash the system. Allocated EMS
or XMS pages are released, a swap file is deleted.
If the program memory image is not contiguous, the swapping code has
to use undocumented DOS-internals. In particular, the swapper has to
modify DOS memory control blocks directly. In theory, this could lead
to incompatibilities with later versions of DOS, or with DOS
substitutes or emulators. In practice, no problems have been reported
with any DOS version, including DOS 6.0 and the DR-DOS versions.
If the NO_INHERIT flag is set to TRUE in spawn.asm, some undocumented
fields in the PSP are used and modified. This should work with all
DOS versions and clones, but you can set NO_INHERIT to FALSE if you
are afraid of potential problems (but not if you use handle-table
expansion).
Revision History
================
Changes for version 3.3 to 3.3a:
Besides the address change, the only significant modification is a
better handling of redirection. Like with DOS, redirection parameters
may now be interspersed with other command line arguments.
The Pascal version was buggy in the handling of multiple redirection
and COMSPEC parameters. This was fixed.
Changes for version 3.2a to 3.3:
A new option for Turbo Pascal recognizes the free heap space and
suppresses swapping for this area. For many applications this will
speed up the swapping process, and reduce swap space requirements.
Since this is version dependent (Turbo Pascal version 6 uses a
different heap management scheme than its predecessors), the
preassembled version has this feature disabled. Please set PAS_FREE
in SPAWN.ASM to TRUE, and set TPAS_6 to TRUE or FALSE depending on
your version of Turbo Pascal to use it.
The Pascal "putenv" function was buggy. When putting a variable
already in the environment, it produced a duplicate entry instead of
replacing it. Bug reported and fixed by A. Bailey.
When determining program name and path, a program with a base name
(without extension) equal to the name of a directory was not found
under certain circumstances. The checkpath function was modified to
correctly handle this case. Bug reported by H. Lembke.
An extended handle table would cause the swap-back to fail on a
file-swap if NO_INHERIT was true. This was due to the restoration of
the handle table pointers before allocating and restoring the MCB the
handle table was in. The handle table pointer is now restored after
swapping everything back. Bug reported by H. Lembke.
EXEC would fail completely with an extended handle table if
NO_INHERIT was false. The MCB containing the handle table now is not
swapped, which will likely fragment memory, so setting NO_INHERIT to
false when extending the handle table is not recommended.
The C do_exec function now correctly handles NULL pointers to the
command line and parameter strings.
Changes for version 3.2 to 3.2a:
A bug in checkpat.asm that caused incomplete path specs was fixed.
A bug in spawn.asm that caused redirected files to stay open even
after program termination was fixed.
Changes for version 3.1 to 3.2:
The call of a user-defineable function (through a function pointer or
a procedure variable) from do_exec immediately before executing the
external command was added. This function can output messages and
perform additional checks. The previously internal structure
containing the swap parameters was made global for access by this
function. For details see exec.h/exec.pas, and the example in
extest.c/extest.pas.
A bug in checkpat.asm that led to erroneous operation of the 'exists'
function when used with Turbo Pascal was fixed.
The Pascal version of extest was (finally) brought up to date, and
now corresponds closely to the C version. A sample for the use of the
user-defined call-back function was added in both versions.
The definition of the internal routines in exec.c was changed to
"static", initialisation of some variables in do_exec was corrected.
Changes for version 3.0a to 3.1:
The capability to process BAT files and to handle redirection was
added. The program search order now exactly matches the DOS order
with the exception of internal commands (there is no safe way to
determine whether a command is internal or external). Redirection is
optional. The interface to do_exec did not change (redirection is
handled by parsing the parameter string), but do_spawn takes three
new parameters if redirection is enabled.
A routine was added (checkpat.asm) that checks and resolves a path
name in addition to splitting it. This routine does some thorough
checks on the supplied path and filename, and will handle critical
errors (invalid drive, drive not ready) without user intervention.
This routine is used to process the program file name, the command
processor filename, and the temporary path. This routine is not
dependent on the other EXEC/SPAWN routines, and thus might be
useful for other applications.
Several new error codes allow better analysis of error conditions.
The temporary file path will now always be a complete path, so that a
change of the default drive and directory while spawned can no longer
cause the swap file to get lost.
Any parameters on the COMSPEC= environment string will be inserted
into the command parameters when calling the command processor. This
allows specification of environment size and other parameters when
spawning.
The check for file existance was moved to checkpat.asm, and changed
from a 'find first' operation to 'get file attributes'. This seems to
be marginally faster, and avoids compiler dependencies.
The GETLANG program was corrected to use stderr to output the usage
information.
Changes for version 3.0 to 3.0a:
A minor bug in EXEC.C was fixed: a '<' was missing in a German
comment, so that GETLANG E would gobble up a large part of the file.
A problem (feature? bug?) with the Turbo C/Borland C "stat" function
always returning directories with a "read-only" attribute prevented
the "TEMP" directory from being used. The Write permission for the
directory is no longer checked.
The preallocation of the swap file introduced in Version 3.0 to make
sure that the disk can hold the swap file causes a severe slowdown
when the swap drive is a Novell Network drive. Two new "method" flags
were introduced to circumvent this problem:
NO_PREALLOC - never preallocate
CHECK_NET - check for network drive, don't preallocate if net
If the file is not preallocated, the disk is not checked for
sufficient space at all. Using the "get disk free space" call usually
takes even longer than preallocation. This is not a big problem
though, swapping simply will fail with error code 0x502 when the disk
is full on swapping out.
Thanks to Tim Frost ('<' bug) and Tron Hvaring (stat and Novell
problems) for their reports.
Changes for version 3.0:
This is a major rewrite of the code in spawn.asm. The interface for
do_exec and do_spawn has changed, the exec and extest files have been
modified accordingly.
The main enhancement is support for XMS.
The code in spawn.c was modularized a tad, and a lot of comments were
added. This should help in better understanding the code. Old bugs
(versions 2.4 and 2.5 were buggy in handling non-swapping spawns)
were eliminated.
The allocation of swap space has been separated from the actual
swapping. Although not used in the current do_exec routine, this
could be used to issue an informative message about where the
swapping will go to, and to try other paths for the temporary file if
allocation fails. You might elect to add support for this in the
do_exec routine, just be careful not to modify the memory layout
between the calls to prep_swap and do_swap.
The MCB blocks are no longer modified in preparation of the swap.
Instead of using an internal chain with undocumented fields in the
MCB, the MCB chain is now parsed multiple times. Since the chain
normally consists of just a few elements, this will not severely
impact execution performance. MCBs are now swapped out and restored
in their original form, including the "unused" fields that are not
really unused in DOS 4.0 and later versions.
Saving fragmented memory will now use less EMS space, since the
blocks are packed tight. Previous versions started a new page for
every MCB.
Memory blocks located "below" the PSP (including the environment
block, unless it is needed for an environment copy) will now be
swapped, too. This may increase available memory if DOS memory is
fragmented.
Things not done in this release:
The MCB chain still is modified directly. Although some users have
suggested trying to call DOS to allocate the blocks, this has proven
impractical in some tests. If memory is fragmented, getting DOS to
allocate a block at an exact location is rather tedious. I will keep
the suggestion in mind, but the current method works reliably with
all known (and unknown) versions of DOS and its clones.
Another good suggestion not implemented in this version is the save
and restore of the interrupt vector table to remove TSRs installed
while the program was swapped out. It would be rather complex to find
and release all memory blocks belonging to the TSR, and without
releasing the TSRs memory, the program can not be swapped back in
anyway, so restoring the interrupt table wouldn't help.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -