Dec 142017
Playing with paths & env variables.
File PCPATH.ZIP from The Programmer’s Corner in
Category Utilities for DOS and Windows Machines
Playing with paths & env variables.
File Name File Size Zip Size Zip Type
ADDPATH.BAT 970 516 deflated
GETENV.PAS 4215 1229 deflated
HOMEPATH.PAS 3576 1153 deflated
PATH.DOC 10070 4176 deflated
POPPATH.BAT 1593 682 deflated
PUSHPATH.BAT 1000 496 deflated

Download File PCPATH.ZIP Here

Contents of the PATH.DOC file

Tiptoe Through the Path Garden
(or, Just one more time at BAT)

As everybody by now should know, MS-DOS is basically a version of
CP/M that wants to be Unix when it grows up. Two Unix-like features that
can be very handy to the programmer are environment strings and the PATH
facility. Here we'll explore the manipulation of environment strings by
batch command files and use our discoveries to diddle the PATH in
interesting -- and perhaps even useful -- ways.

{ I. The Ecological Context }

DOS's "environment string area" is simply an area of memory filled
with null-terminated (ASCIIZ or C-type)[1] strings, itself terminated by
a zero-length string (or, alternatively, another null following the null
that marks the end of the last string. OK?). A segment pointer[2] to
this area is located in the PSP (Program Segment Prefix, i.e. the 100h
bytes DOS tacks on to the front of your program for its own use) at
offset 2Ch.

Each string is of the form XXX=yyy, where both XXX and yyy are
anything at all, but XXX is always in upper case. In particular,
blanks are significant: XXX=yyy and XXX =yyy are different environment
strings. The SET command manipulates these strings:

set my mother's address=127 Vibble Crescent, Raccoon, Indiana

is completely legal[3], and creates the variable MY MOTHER'S ADDRESS
with the expected value. 'Set my mother's address=' removes the
variable from the environment area.

<< Digression : Expanding the environment string area >>

At boot time, an environment area is reserved for the strings and a
COMSPEC= string is stored there. This area is by default about 127 bytes
long, which isn't very much, but it can be expanded as needed UNTIL some
permanently-resident program is loaded, which has the effect of
allocating memory immediately above the current environment area,
preventing further expansion. Then further SETs evoke the dreaded
"Out of environment space" message.

In order to get a reasonable amount of environment space to play
with, what we have to do depends on the particular version of DOS we're
running. We can always patch COMMAND.COM, which is unappetizing at
best both because it is difficult to undo and because it ties us to
this particular copy of the program. In addition, of course, since there
are so many different versions of COMMAND floating around we may not be
able to find the right patch for the one we use.

With DOS 3.x, we can use a switch on the SHELL command in
CONFIG.SYS. [If you don't have a config.sys file containing at
least the FILES=n and BUFFERS=n commands, you probably are not running
enough serious software to make this article worthwhile.] The
interpretation of the "/E:nnn" switch is different in 3.1 and 3.2:


will reserve an additional 512 (200 hex) paragraphs, or 8K bytes, in
3.1 but 200 (decimal) bytes in DOS 3.2 -- at least the vanilla MS-DOS
version that I use. Look in the CONFIG.SYS appendix of your DOS manual
and be prepared, as always, to try several different interpretations of
the verbiage you find there. MicroSoft apparently was not very sure
exactly how they wanted to handle this parameter . .

With DOS 2.x, the situation is even more confusing. I have not
been able to find any reliable way of expanding its environment, but
the following have been proposed in various places:

a) Use a switch on the command SET COMSPEC= (for example,
autoexec.bat file. This has never worked for me;
although it does not generate any error when autoexec
runs at boot time, as soon as some program with a
"jump through to DOS" function (such as most current
communications programs, dBASE III, or version 2 of the
Personal Editor) tries to load another copy of COMMAND, the
presence of the switches confuse the DOS loader and
he complains that he can't find the command processor.

b) Add enough strings to enlarge the environment area to the
desired size before any additional code is made resident
(which blocks further expansion). For example, the
following sequence in your autoexec file would create
a number of dummy strings to cause the environment area
to be expanded, then load resident code to block off
the area permanently, then empty the strings to free up
space for further use:

rem Top of autoexec file
rem create dummy strings to force expansion of env area
SET Z0=bunny bunny zzzzz dummy string zzzzz bunny bunny bunny bunny
rem now make a bunch of copies
for %%s in ( 1 2 3 4 5 6 7 8 9 ) do set Z%%s=%Z%
rem now load some more resident code -- two old favorites are
PRINT/d:PRN /q:16
MODE co80
rem now empty the strings to allow reuse of the space
for %%s in ( 0 1 2 3 4 5 6 7 8 9 ) do set Z%%s=

This looks clever, but I haven't been able to make it
work with any of the DOS 2.x's I've tried. It might work
with yours, though . .

Perhaps the 2.x user might just as well bite the bullet and get a
copy of 3.x. The mail-order prices for 3.0 and 3.1 are under $50 now
(May 87) and dropping. Avoid PC-DOS 3.3 [for the new IBM hoopla
specials] -- early reports say it has terrible trouble with hard drives,
and you don't get DEBUG or EXE2BIN.

<< End of Digression >>

Although any program can access these strings through the pointer in
the PSP, the easiest way to make use of environment variables is in batch
files. (In fact, since each program only has access to a _copy_ of the
environment, the _only_ way to actually add anything to the environment

is with a batch file.) When the batch processor encounters a string
surrounded by %s in a command file, the contents of the variable named
between the %s is substituted for the delimited string before the line is
executed. For example,

set victim=newprogs.doc
ws %victim%

has the effect of issuing the command 'ws newprogs.doc'. If the string
is undefined, no error is generated -- you just get a zero-length string
(nothing at all).

{ II. The Primrose PATH (or are they BATchelor buttons?) }

As we all remember from our Sacred Mysteries of DOS 211, the PATH
string tells COMMAND where to look for programs -- once, for example,
the command

path \;bunny\rabbit\carrot;d:\mambo;..

has been issued, DOS will look for .COM and .EXE files first in our
current directory, then in the root ('\') directory on the mounted disk,
then in each directory listed between semicolons[4].

Where does DOS keep this path string? In the environment area, as
the value of the variable PATH (if you hadn't already guessed . . .).
So we can manipulate this string like any other.

ADDPATH, PUSHPATH, and POPPATH are batch files that add to, save,
and restore PATH specifications using the environment area. In a typical
session, you may well PUSHPATH to save your AUTOEXEC-set path, ADDPATH
\spec to access special programs you'll be using, and POPPATH to restore
the old path when you're finished.

GETENV is a Turbo Pascal routine, largely cribbed from Phillip
Burns' PIBTERM, which returns the value of the environment variable named
in its argument.

HOMEPATH is a Turbo routine for DOS 3.x only that returns the
pathname of the program that was invoked. Thus if your program needs,
say, a configuration file and was found by DOS via the PATH, you can use
this routine to find the directory where (presumably) your program's
files live, something like

procedure Init;
var MyDir : string [32];
CnfFile : Text;
MyDir := HomePath(true); {true to throw away the program name}
assign(CnfFile, MyDir + 'BUNNY.CNF') {config file spec }
etc . . .


Have fun and keep hacking. . .
Craig Goodrich
PussyCat Systems
box 266
Washington Grove MD 20880


[1] Actually first used extensively in DEC's RT-11 operating system
for the PDP-11. . . Anyone notice how much the user interfaces of CP/M
and MS-DOS both look like DEC timesharing systems? Or how much C looks
like structured PDP-11 assembly code, for that matter?

[2] Quit laughing, you 68000 hackers!

[3] Actually, XXX can't begin with a delimiter (blank, comma, etc.), but
then nobody's perfect.

[4] If the directory does not exist, DOS simply skips to the next one
listed without generating an error BUT {bug alert!} if the very
convenient '..' is included, meaning the parent of the current directory,
and the current directory is the root, then DOS will complain about an
illegal directory and stop his scan. [Apparently fixed in 3.2 -- cg ]

(c) 1987 PussyCat Systems, box 266, Washington Grove MD 20880
all rights reserved
Released to the DOS user community for non-commercial use only.

 December 14, 2017  Add comments

Leave a Reply