UNDELETE for Linux "bug", lengthy mail over FreeCOM versus COUNT

Eric Auer <[email protected]> Sat, 9 Nov 2002 02:16:26 +0100 (MET)
Newsgroups gmane.os.freedos.devel,gmane.spam.detected
Message-ID <[email protected]>
Hi, I just noticed that the Linux version of my UNDELETE tool can only work
on 1.44 MB floppies and images of them. I will fix that.

Next problem is that COUNT probably contains a bug which could make
it trash the stack when displaying its help message. I have fixed that,
but have not put the new version online (the bug seems not to be serious,
and I want to fix another problem with COUNT before re-releasing it). COUNT
is also part of the UNDELETE package and used by MIRROR and MIRRTREE (which
are also part of the UNDELETE package).

The other problem with COUNT is that I cannot make it modify the instance of
%COUNT% that I want it to modify:
set COUNT=00000
global mirrtr2 magic ...
Now "mirrtr2" is a batch file. Global is a freeware tool that does, according
to my analysis:
pushd
"for all subdirectories" do begin
  cdd SUBDIRECTORY
  %COMSPEC% /C ARGUMENT
end
popd
echo Done with all directories.

When there is no %COMSPEC%, it uses \COMMAND.COM instead. Global can run all
commands, including batch files and internal commands of command.com, that
way.

The trouble is that FreeCOM command.com tries to outsmart me, and this breaks
things for me:
MIRRTR2 contains a "while file dir%COUNT%.bin exists, count up using COUNT"
loop. COUNT only modifies the environment of its parent (the temporary
instance of command.com, when I call MIRRTR2 through GLOBAL), so it always
starts from 00000 for each new directory. However, I tried modified versions
of COUNT that go further up the chain and are supposed to modify the environ-
ment of GLOBAL or even of the command.com instance where "global mirrtr..."
got started, WITHOUT SUCCESS. I always end up modifying a copy that only
the current MIRRTR2 instance sees, so each new instance starts at the same
value, which wastes a lot of time in counting!


I have investigated the problem and found out that FreeCOM tries to be
clever and avoids loading further instances of itself. This means: For
example, when I have a dir1.bat:
echo DIR of %_CWD% is:
dir
And a dir2.bat:
echo DIR of %_CWD% is:
drl /o=CON /1
And then I do:
global x:\here\dir1.bat
and a:
global x:\here\dir2.bat
Then FreeCOM seems to detect that dir1.bat only contains internal commands
and does SOMETHING strange that causes GLOBAL to fail (in a way that it
will just run dir1.bat for the current directory and then say "Done with
all directories" even though there would be subdirectories). Dir2.bat works.

I think this problem and my problems with
set COUNT=123
global count-using-batch-file.bat
are related:
While running a batch file that sets a variable causes a varible to be set
for the copy of FreeCOM where I type the command "run the batch file", but
not for parent copies of FreeCOM is roughly okay, it is a bit strange:
FreeCOM seems to treat the "run a batch file" command like "pretend the
batch file is user input" in some way. So the batch file is "part of the
current user" and not "child" of it. Even when I run it through "call".
Only when I run "freecom /c batchfile", batchfile is actually run in a new
copy of FreeCOM which is child of the current copy. Here some example:

a:\>set foo=
a:\>type foo.bat
@echo foo.bat running
@set foo=bar
@echo foo=%foo%
a:\>set foo=
a:\>foo
foo.bat running
foo=bar
a:\>echo foo=%foo%
foo=bar

When I type instead:
a:\>call foo.bat
Then the same happens.

When I type instead:
a:\>freecom /c foo
Then I get, as expected:
a:\>echo foo=%foo%
foo
(yes, the "=" is gone, strange, but my point is that %foo% is now not
set, as it only got set in the child freecom process that ran foo.bat,
as expected).

By the way, FreeCOM produces empty lines for all @ lines in batch files
on the screen, I do not like that feature.

I do not know how this is related, but when I run - in A.bat - a
global B.bat
then it is only logical that B.bat cannot modify the environment of A.bat
- so far so good. But in case of MIRRTR2 called from MIRRTREE, I actually
do want to modify the environment of MIRRTREE, so I modified COUNT: My
other version of count modifies the environment of the parent of the parent
of the parent, which SHOULD work:
freecom (1) processes MIRRTREE
  global (2) is a child of it
    freecom (3) processes MIRRTR2
      count (4) tries to modify the environment of (1)
      (the normal version would modify the environment of (3), and by the
      way, if you were to setenv() in (4), only (4) and its child processes
      would notice the change)
      For this, count tries to go two steps further than normal. Normal would
      be affecting (3) only, two steps further would be (1)...
    freecom (3b), a new instance of freecom spawned by global (2) processes
    MIRRTR2 again. However, not even global (2) got affected by count! No idea
    why this happens, but it is not what I want!

What I want is to modify the environment of MIRRTREE / (1), or at least of
GLOBAL (2), from COUNT (4). But I seem to be unable to reach it from there,
no matter how far I try to follow the chain. FreeCOM (3) seems to interfere
with FreeCOM (1) in some way, spoiling my efforts. Of course, this could also
be the fault of GLOBAL, but as said, when I try to modify the environment of
GLOBAL (would be enough), the next instance of FreeCOM (3b) gets the same
environment contents as the first one (3) anyway! Why this??? I would expect
that all childs of GLOBAL inherit their environment from the current state of
the environment of GLOBAL at the moment they get spawned by GLOBAL. But this
does not seem to hold (as said, GLOBAL always calls %COMSPEC%).

I have done some further testing with a program that decrements the drive
letter of COMSPEC in the environment of its parents parent (so not the
one for FreeCOM but the one of GLOBAL, when you call my test program by
global). Neither is GLOBAL affected by this manipulation nor does my test
program display "counting" comspec values (comspec is the first environment
variable for me, this is really a quick hack...):

a:\>echo ucs:100 l 2a | debug info2.com
1C1B:0103 8ED8          MOV     DS,AX
1C1B:0105 A11600        MOV     AX,[0016]
1C1B:0108 8ED8          MOV     DS,AX
1C1B:010A A12C00        MOV     AX,[002C]
1C1B:010D 8ED8          MOV     DS,AX
1C1B:010F FE0E0800      DEC     BYTE PTR [0008]
1C1B:0113 90            NOP
1C1B:0114 90            NOP
1C1B:0115 FC            CLD
1C1B:0116 31F6          XOR     SI,SI
1C1B:0118 AD            LODSW
1C1B:0119 09C0          OR      AX,AX
1C1B:011B 7504          JNZ     0121
1C1B:011D 0E            PUSH    CS
1C1B:011E 1F            POP     DS
1C1B:011F CD20          INT     20
1C1B:0121 4E            DEC     SI
1C1B:0122 B402          MOV     AH,02
1C1B:0124 88C2          MOV     DL,AL
1C1B:0126 CD21          INT     21
1C1B:0128 EBEE          JMP     0118
=
a:\>global \info2.com

(uhm, hey, why can't I redirect the output even though I am using
int 21.2? Whatever...)
Whatever. GLOBAL \info2.com outputs:
COMSPEC=B:\TOOLS\FREECOM.COM PATH=c:\bin;c:\gnu;c:\dosemu;c:\home\djgpp\bin;c:\tools HELPPATH=c:\help TEMP=c:\tmp DJGPP=c:\home\djgpp\djgpp.env BLASTER=A220 I5 D1 PROMPT=$P$G DOSEMU_VERSION=1.0.2.0 COUNT=001
COMSPEC=B:\TOOLS\FREECOM.COM PATH=c:\bin;c:\gnu;c:\dosemu;c:\home\djgpp\bin;c:\tools HELPPATH=c:\help TEMP=c:\tmp DJGPP=c:\home\djgpp\djgpp.env BLASTER=A220 I5 D1 PROMPT=$P$G DOSEMU_VERSION=1.0.2.0 COUNT=001
...

(the line breaks are from GLOBAL or the FreeCOM that is started by GLOBAL in
order to start info2.com)

I have added yet another "mov ax,[16] mov ds,ax" but it did not change a thing.
FreeCOM seems to form an impermeable border when trying to walk the process
tree! Even when I run \info2.com without global, the parent process of my
instance of FreeCOM (the one where I type
a:\>info2
) is never affected.

Any ideas how I could cross that "freecom process tree border" ???

Thanks!

Eric

PS: If you made it to read this long mail... something to cheer you up:
COUNT used locally in a batch file is no problem. The problem is that I
am unable to write a variant of COUNT that would affect the parent instance
of the shell where COUNT is used. It seems to be generally impossible to
reach the parent of any FreeCOM through the PSP chain.