The C Run-time (CRT), included with:
- Microsoft C for MS-DOS, versions 6.0, 6.0a, and 6.0ax
- Microsoft C/C++ for MS-DOS, version 7.0
- Microsoft Visual C++ for Windows, versions 1.0, 1.5, 1.51, and 1.52
- Microsoft Visual C++ 32-bit Edition, versions 1.0, 2.0, 2.1, and
4.0
SYMPTOMS
Using the program below to spawn SORT.EXE on MS-DOS, the following error message is generated:
SORT: Too many parameters
Running the same program on Windows NT causes the following error message to be generated:
SORT: Invalid Switch
CAUSE
This is the expected behavior as COMMAND.COM or CMD.EXE (the command interpreter for Windows NT), not the EXEC loader, handles indirection. Child processes inherit the handles of their parents; therefore, to redirect the input and output of the child, first change the definitions of STDIN and STDOUT in the parent process.
RESOLUTION
The proper way to redirect input for a filter is described starting on page 441 of the "MS-DOS Encyclopedia," along with a complete MASM example. Note: The dup, dup2, _dup, and _dup2 functions in the MS-DOS C run-time library are the same as the Interrupt 21h functions 45h and 46h, respectively.
There also are partial examples of this technique included with the C run-time library reference documentation for the _dup related functions and on page 353 of "Advanced MS-DOS Programming" (by Duncan, published by Microsoft Press).
It is possible to use freopen() to redefine STDIN and STDOUT; however, doing so loses any redirection that may have been performed on the parent process.
The easiest workaround is to use the system() function to spawn a copy of COMMAND.COM or CMD.EXE that runs SORT.EXE, as follows:
system("sort.exe <infile.dat >outfile.dat");
MORE INFORMATION
The following code sample demonstrates the problem.
Sample Code
/* Compile options needed: none */
#include <stdio.h> #include <process.h> main() {
char *args[6] ;
args[0] = "sort" ;
args[1] = "<" ;
args[2] = "infile.dat" ; /* exists */
args[3] = ">" ; /* direct output to a disk file */
args[4] = "outfile.dat" ;
args[5] = NULL ;
spawnvp (P_WAIT, "sort.exe", args) ;
}