delorie.com is funded by banner ads.
  www.delorie.com/djgpp/v2faq/faq079.html   search  

| Previous | Up | Top |

9.6 How many file handles can DJGPP use?

Q: The library reference tells me that DJGPP programs can use up to 255 file handles, but my program can only use much less, about 30...

Q: I put a FILES=60 directive in my CONFIG.SYS, but my programs cannot use more than 42 when they run on Windows. Why is that?


A: It's no wonder you are confused: this is one of the most complicated issues related to the DOS filesystem. I cannot discuss all the details here(Note: Those who want all the details should consult a good book about DOS internals, such as Undocumented DOS, 2nd ed. by Andrew Schullman, or Geoff Chappel's DOS Internals.), but I will try to explain at least those aspects which directly affect a typical DJGPP user.

It is true that DJGPP library lets you open up to 255 handles--but only if the operating system allows it. The operating system further limits this number, depending on several factors.

First, if you create new handles by calling the dup library function (or the underlying function 45h of the DOS Interrupt 21h), you can always have up to 255 such handles, even if the FILES= directive sets a much smaller count. All such handles refer to the same file or device and moving the file pointer using one handle moves all the rest of them.

In nested programs (that is, programs that were invoked by other programs), this is a bit more complicated. By default, any handle that is open in the parent program is inherited by the child, unless the parent sets the special O_NOINHERIT bit when it opens the file. Thus, if the parent had 10 files open when it invoked the child, the child program will have 10 less available handles--245--to work with, even if it only calls dup(Note: All DOS programs get the default 20-handle table when they start; DOS only copies the first 20 handles into the child, so it is not possible to inherit more than 20 handles. The expansion of the default 20-handle table to 255 handles is a special feature of the DJGPP library, and it only happens when the programs exhausts all of the 20 handles while it runs. Therefore, when all of the first 20 handles are taken up by files inherited from the parent program, the child program can fail to start because the DJGPP stub loader needs one free handle to open and read the COFF executable into memory. The stub cannot use the enlarged 255-handle table, since it cannot call the DJGPP library. Such problems indeed happen in programs compiled with DJGPP v2.01; v2.02 fixes this bug.).

The FILES= directive comes into play when you call open or any of its brethren to create handles. Unlike the handles created by dup, open (and the underlying functions 3Dh or 6Ch of Interrupt 21h) create handles that are independent of each other, even if you open the same file over and over again. The operating system will not let you create more such handles than the limit set by the FILES= directive. This is because the FILES= directive sets the number of entries in the SFT, the System File Table maintained by DOS, where all the information about every open file is kept(Note: Each handle created by a call to open uses up one slot in the SFT, whereas a handle created by dup just increments the use count of a slot that was already in use.). So, if your CONFIG.SYS specifies FILES=60, you cannot open more than 60 files. After that, a call to open will fail with ENFILE (Too many open files in system).

In practice, you won't even be able to get 60 handles if you have FILES=60 in your CONFIG.SYS, since several handles are always preconnected. On plain DOS, 5 handles are already open when a program starts. These correspond to standard input, standard output, and standard error streams, and the other 2 handles are connected to the AUX and PRN devices. So, if you have FILES=60, DOS will only let you open up to 55 independent handles.

The plot thickens even more if you run DJGPP programs on Windows. Since Windows itself uses up 10-15 handles in the System Virtual Machine (VM), it tries to make it up for the DOS programs by adding private file tables to each DOS box with additional handles, beyond those maintained in the SFT. The default is to add a private table with 10 handles to each DOS box, but the PerVMFiles= entry in the [386Enh] section of the SYSTEM.INI file can override that. So on Windows, you need to consider the PerVMFiles= setting as well, and the resulting limit on open handles is less predictable since the number of handles used by Windows isn't constant (for example, it depends on how many fonts are loaded by Windows programs at any given moment).

If your system loads SHARE.EXE during bootstrap, things become even more complicated. SHARE.EXE prevents Windows from adding private file tables (because it couldn't spy on files open via those private handles), so you get 10-15 less handles than what the FILES= directive says, and sometimes even less than that. That is how somebody who has FILES=60 on their CONFIG.SYS could only get 42 handles on Windows. If you are looking for reasons not to load SHARE.EXE, here you have another one.


  webmaster   donations   bookstore     delorie software   privacy  
  Copyright ⌐ 1998   by Eli Zaretskii     Updated Sep 1998  

Powered by Apache!

You can help support this site by visiting the advertisers that sponsor it! (only once each, though)