Environment Usage in MS-DOS. ---------------- All pathnames can have forward or back slashes. (This is also true of file names explicitly used in perl. The system call handlers in MS-DOS like / fine; it's command.com and other programs that are picky.) Environment variables are interpreted when they are needed. (Exception: creation of $TMP from $TMPDIR is done at startup.) Thus the perl script can change them. For example, if a huge "pipe" file is to be created, and there's room on the hard disk (c:) but not the usual $TMP, which is a RAM disk, one could write: ENV{'TMP'} = "c:/tmp"; open (HANDLE, "program|"); The state of the environment passed to perl.exe determines argument parsing, though, since this is done before compilation and interpretation of the perl script. PATH Semicolon-separated path list. The current directory is search first unless $MKSARGS is defined and MKS support is compiled in, in which case the current directory is searched only in response to an explicit "."or null path component. MKSARGS Set to 1 enable all MKSisms. The MKS tools can assume that the other pieces of the toolkit are lying around, but perl.exe can't. (It may be the only MKS-compatible program on a system.) If have have the MKS tools, you should set this variable. Perl will recoginize and generate MKS compatible arguments in any case, but without the switch will default SLASHC to "-c" instead of "-ce", will fail to run MKS glob, and will run perl's glob instead of the Korn shell to expand expressions like <*.c>. Note that MKS support can also be compiled out. ROOTDIR Full drive and path where MKS toolkit is installed. Example, "c:/mks" or "d:/". Typically is already set in MKS environment. Used only if $MKSARGS is set and $GLOB is not. See GLOB. Ignored if MKS support compiled out. TMP First choice for temporary files, e.g., "h:\\tmp". If not set, uses $TMPDIR (see below), if that's not set, the current directory is used. Swapping also goes here unless $EXESWAP is defined. Temp files are pseudo-pipes, the swap file, and the -e file. TMPDIR If $TMPDIR is set and $TMP is not, the following is done internally: ( $ENV{'TMP'} = $ENV{'TMPDIR'} ) =~ s,/,\\,g; (Backslashes are reversed as a gesture to decendents of the perl process.) Creation of $ENV{'TMP'} from $TMPDIR is done at perl.exe startup. Note that the MKS tools use $TMPDIR as a first choice; as a gesture of compatibility here, though, here it is a second choice. EXESWAP First choice for swap out file location. A RAM disk is a nice choice. $TMP is used if this isn't set. (See also $TMPDIR). The swap file created the first time swapping is invoked and is left open until perl exits or does an exec. Set to ".off" (note illegal DOS name) to inhibit swapping-- useful for speedy running of small subprocesses. This feature (inhibition) can be turned on and off: $ENV{'EXESWAP'} = 'e:/tmp'; # directory for swap file system "ls"; # perl opens swap file and swaps to run ls $ENV{'EXESWAP'} = '.off'; # temporarily disable swap system "who"; # no swapping, who run in available memory $ENV{'EXESWAP'} = 'yes'; # anything other that '.off'. system "ps"; # swapping to original file GLOB First choice for MKS globbing program: full path, name, and extension. Example: "d:/mks/etc/glob.exe". The perl globbing program (used for <*.c> expansion) is found, as before, via the $PATH. Used only in an MKS environment, and then only when perl is run from a non-MKS program. Ignored if MKS support compiled out. SHELL Full path name and extension of the shell used used for subprocesses when wildcard expansion is required, e.g., "c:/mks/bin/sh.exe". If undefined, COMSPEC is used. Presumably this could be the MKS korn shell, but it can be another shell (e.g., 4DOS) and thus $SHELL is inspected even if MKS support is compiled out. COMPSEC Full path name of DOS command interpreter, e.g., "c:\\command.com" Used only if $SHELL is not defined. If not found, "\\command.com" is used. (It is bad practice to allow $COMSPEC to default or to have it have anything other than a full drive and path name. You don't want your programs looking for command.com on alternate drives.) METACHAR List of characters that are metacharacters to the $SHELL or $COMPSPEC. Used to determine if command can be run directly or if a subshell must be invoked. If undefined, |<> is used for COMSPEC and *"?<>|()&][$#`'\ for SHELL. SLASHC The shell option for invoking a command. Defaults: /c for $COMSPEC, DOS version 4.x or better [sic] sc where s is the switch character, for $COMSPEC, DOS < 4.0 -ce for $SHELL if $MKSARGS is set and MKS support is compiled in. (-e needed to get status back). -c for other $SHELLs. (This is a guess.) PERLLIB Directory containing perl library. Defaults to /usr/local/lib/perl. Should be applicable even in Unix. Globbing Conventions ------------------------------------ Unix and MKS do globbing differently than MS-DOS. Under Unix and MKS, "abc*" matches abc.c, Under DOS, though, the * won't match '.' The MKS tools use the former interpretation; the glob program distributed with perl and the globbing built in to perl.exe use the latter. (Don't install the distributed glob.exe if you are using the MKS tools.) You can also write your own globber and call it ___setargv (__setargv in C) to replace the Microsoft library stuff. Interpretation of Incoming Arguments ------------------------------------ There are three cases: 1) Perl.exe was invoked MKS-style. The arguments are pulled from the environment as per MKS dodsexec(5). Several kilobytes of pre-globbed arguments can be passed this way. Works even if $MKSARGS is not set, but not if MKS support is compiled out. 2) Perl.exe was was invoked in non-MKS style but the MKS tools are intact. This will happen if there's if perl.exe is run by an incompatible program, such as Microsoft NMAKE, even though the toolkit is intact. The toolkit is presumed present iff $MKSARGS is set. The MKS glob program is looked for in $GLOB, $ROOTDIR/etc/glob.exe, and /etc/glob.exe in that order. (User really should set $ROOTDIR or $GLOB to avoid problems with "which drive?") This step is not done if MKS support is compiled out. 3) Perl.exe was invoked and $MKSARGS was not set or MKS support was compiled out. Perl globs the arguments itself, using the ___setargv code in the Microsoft library. That code deals with double (but not single) quotes and expands wildcards in the usual DOS manner, i.e., as in DIR and COPY. Globbing Expressions ------------------------------------ Expressions like <*.c> are expanded by a subshell in Unix. Under DOS, there are the following cases: 1) $MKSARGS is defined and MKS support is compiled in. The $SHELL is used, running echo piped to tr exactly as with the Bourne shell on Unix perl. 2) The supplied glob.exe is run. This program simply takes the supplied command line, DOS-globs it, and writes the result, "\r\n" separated, to the perl process via a "pipe." Running Subprocesses ------------------------------------ Perl.exe will by default swap itself out almost entirely when it runs a subprocess other than MKS $GLOB. (See EXESWAP). The swap file is opened when the first subprocess is run and is left open until perl exits or does an exec. The command line to be run is scanned for $METACHARacters as described above. If none are found, the subcommand is invoked directly. If metacharacter(s) are found, a $SHELL or $COMSPEC is invoked to run the command. Use of a single | in a open() command does not constitute a metacharcter: this is a directive to perl to open a pipe. The following, too, has no SHELL metacharacters since the subprocess is simply pwd: chop($direct = `pwd`); Beware of MS-DOS "internal" commands; i.e., those that are built into command.com. Examples are DIR and COPY. COMMAND.COM users can use these directly if the command has $METACHARacters; if not, you must invoke an explicit command.com: system "dir >my.fil"; # > is a metacharacter system "$ENV{'COMSPEC'} /c ver"; # no metacharacters, must be explicit Users of other $SHELLs must use the second format for anything to be passed to command.com. Be aware that no wild card expansion is going to be done by command.com usless you're using one of the built-in commands that does it (e.g., COPY). You can use <> expansion to get around this. Even those who have fancy $SHELLs should take note of this, since having perl run the $SHELL and then the command uses less memory than if perl runs the $SHELL which runs the command. $files = <*.c>; `the_com $files`; intead of `the_com *.c`; Typical MKS setup in profile.ksh ------------------------------------ # If you're using the MKS stuff, you probably don't have to do anything # other than set MKSARGS. export MKSARGS=1 # ROOTDIR set by init process or etc.rc or here. export TMPDIR=e:/tmp # EXESWAP left to default to $TMPDIR # GLOB left to default to $ROOTDIR/etc/glob.exe # SHELL set by init process or here. # COMSPEC not used by perl.exe but probably defined for other uses. # METACHAR not defined, left to default. export PERLLIB=c:/lib/perl Typical command.com setup in autoexec.bat ------------------------------------ Rem You probably don't need to do anything except set $TMP, which you Rem may be doing anyway. Rem MKSARGS not set Rem ROOTDIR not used set TMP=d:\tmp Rem EXESWAP left to default to $TMP Rem GLOB not used Rem SHELL not set Rem COMPEC set by config.sys SHELL command or by MS-DOS startup. Rem METACHAR not defined, left to default. set PERLLIB=c:/lib/perl Typical setup in autoexec.bat for user of some other shell ------------------------------------ Rem MKSARGS not set Rem ROOTDIR not used set TMP=d:\tmp Rem EXESWAP left to default to $TMP Rem GLOB not used set SHELL=c:\bin\whatever.exe Rem COMPEC set by config.sys SHELL command or by MS-DOS startup. set METACHAR=?*<>| # or whatever, shell dependent set PERLLIB=c:/lib/perl