Node:File handles, Next:, Previous:Distributing, Up:Running

9.7 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 here17, but I will try to explain at least those aspects which directly affect a typical DJGPP user.

It is true that the 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 (minus the 5 that are open by the system before the program starts), 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 dup18.

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 kept19. 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. (If your program doesn't need some of the 5 standard handles, you can close them and gain some more handles to play with.)

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 system-wide 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 you run DJGPP on Windows 3.X, and 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.