Mail Archives: djgpp-workers/1997/06/03/09:59:52
Here's a problem of which I'm aware for a long time, but only now have I
seen a real-world example where it causes trouble.
DJGPP calls DOS OpenFile function (Int 21h/AH=3Dh) in a way that makes the
resulting handle be inherited by the child programs. However, DOS has a
misfeature whereby the child only inherits the first 20 handles (which get
copied into its default handle table in the PSP). Here's how this bug
can bite you:
1) When a parent DJGPP program has used up its 20-handle table, it
calls a DOS function that enlarges handles and bravely moves on.
2) The DOS function in point allocates a new handle table, copies
the 20 handles into it and updates the pointer in the PSP to point to the
new table.
3) When you call a child program, DOS copies the first 20 handles
into the PSP of the child and invokes the child.
4) The child starts without even a single free handle to begin
with.
A DJGPP-specific aspect of this problem is that the child program won't
start because the stub cannot open the .exe file to read the COFF
header. That is how I bumped into this problem (it was a Dvilj4 job that
needed a lot of fonts, and it was calling external programs to generate
the missing fonts).
Solutions? I can think of two:
a) Change low-level libc functions so that they open files with a
non-inherit bit. It is a rare program that really needs this on MS-DOS,
most of the handles beyond the first 5 don't need to be inherited (in
fact, first thing that COMMAND.COM does when it starts is to close all
handles from 6 on). If we NEVER need the inheritance, this is the best
solution. However, I'm afraid that Bash relies on the inheritance
sometimes (to support constructs like "6> foo"), and other programs might
need this too. Can anybody comment on this?
b) The second way is a bit kludgy but safer, I think. We can
reserve a couple of handles in the first 20 and close them in the code
that invokes child programs, so that at least a few handles are free on
the child side. When the child returns, we just reopen them (say, on NUL
device).
Comments?
- Raw text -