madd@bu-cs.UUCP (07/13/88)
In a previous article I gave a sample program showing one way that you
could make an initial environment that was pretty large.
Unfortunately I didn't have time to properly fix things up before I
sent it off, so this is to complete what I'd started and to fix a
couple of problems that I've noticed.
The following program is called "envmake". If you add it to your
shell= line in \config.sys, it will look for the file \envmake.def and
will read environment entries from there to build an environment.
Each line should be left-justified and should be of the form
<variable>=<setting> just as with the "set" command in command.com.
After building the environment it runs a permanent command.com,
putting the user into the familiar mashdos world. Note that this
program will eat up several k of your computer's memory. Some people
won't like it for that, others will like it just for the larger
environment. You decide. This may be the only simple way to get a
large environment on some versions of MS-DOS.
This particular program is designed to be an example. Some things
that you might like to add might be variable environment size (though
MS-DOS memory allocation) and some means of running a command other
than command.com. Since this is completely off-the-cuff, I have not
been able to test it. I've used similar routines before in a similar
application, so it should be close. I think that the stack size could
be reduced but without testing it I'm not sure. At any rate, I hope
this is useful to someone.
Happy hacking,
jim frost
madd@bu-it.bu.edu
-- cut here --
{ envmake.pas:
this is a Turbo Pascal 4.0 program that sets up an environment
before calling the initial COMMAND.COM. It should be called from
the shell= line in CONFIG.SYS.
written by jim frost on 7.12.88. comments to madd@bu-it.bu.edu.
this program is in the public domain.
}
{$m 1024,0,0 } { 1k stack, no heap }
{$i-}
program envmake;
uses dos;
const prog = 'envmake';
fname = '\envmake.def';
elen = 1023; { 1 less than 1024; adjust as necessary }
var env : array[0..elen] of char; { environment area }
ptr : integer; { ptr in environment area }
eseg, { segment addr of environment }
eofs : word; { offset addr of environment }
f : text; { file to get defs from }
s : string[255]; { string from file of defs }
{ add to the environment buffer }
procedure addenv;
var eq : boolean;
a : integer;
begin
{ if we've reached the end of the environment, don't add this }
if ptr+length(s)+2 > elen then begin
writeln(prog,': environment area full');
exit
end;
eq:= false;
for a:= 1 to length(s) do begin
if s[a] = '=' then
eq:= true;
if not eq then { capitalize up to '=' }
env[ptr]:= upcase(s[a]);
else
env[ptr]:= s[a];
inc(ptr)
end;
env[ptr]:= #0; { terminate string }
inc(ptr);
env[ptr]:= #0 { terminate environment }
end;
begin
{ this gets the pointer to the environment area we've allocated and
adjusts it to align with a paragraph boundary. if we were using
the MS-DOS memory allocation stuff this wouldn't be necessary }
eseg:= seg(env)+(ofs(env) mod 16);
eofs:= ofs(env) mod 16;
if eofs <> 0 then begin
inc(eseg);
ptr:= 16 - eofs
end;
memw[prefixseg:$2c]:= eseg; { tell dos about it }
{ environment is now at env[ptr], so fill it }
assign(f,fname);
reset(f);
if ioresult <> 0 then
writeln(prgname,': could not open ',fname)
else begin
while not eof(f) do begin
readln(f,s);
addenv
end;
close(f)
end;
exec('\command.com','/p');
{ if we get to here, it's real bad. tell the user what happened and
just hang. if we exit we'll get an error from MS-DOS anyway. }
writeln('exec: command.com execution failure (',doserror,')');
repeat until false
end.