[comp.lang.c] MS C open file limit on PC

stryker@dicome.UUCP (don Stryker) (09/19/87)

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

I've run up against a disturbing feature of the Microsoft C compiler
for the PC.  Microsoft limits an applicaton to 20 open files, 5 of 
which are taken up by the standard file handles.  I can open my files
using DOS system calls to bypass the compiler, but I am working with 
a large existing application, and I cannot (would prefer not to) 
change all the I/O in this application to use DOS calls.  Has 
anyone else grappled with this one? Is there a way around it? 
Are you out there, Microsoft?  Will the Twins win the Pennant?
	
	- Don

dave@westmark.UUCP (09/20/87)

In article <1576@dicome.UUCP>, stryker@dicome.UUCP (don Stryker) writes:

> I've run up against a disturbing feature of the Microsoft C compiler
> for the PC.  Microsoft limits an applicaton to 20 open files, 5 of 
> which are taken up by the standard file handles.  I can open my files
> using DOS system calls to bypass the compiler, ...

This limit is imposed by MS-DOS itself, not by the C compiler.
There is a far pointer in the psp at offset 0x34 which points to an
array of unsigned char called the open file list.  The length of
this array is stored as an int at psp offset 0x32.  When MS-DOS
builds the psp, the array, itself, begins at psp offset 0x18 and is
20 bytes long.  To allow, for example, 40 files in a process, do the
following:

First: set the FILES= parameter in config.sys to a large number. (>40)

Then, in your code:

1. Allocate a static array of 40 unsigned char.
2. Initialize each element of the array to 0xff.
3. Copy the 20 bytes from the original array in psp:18 into your
   array. (This preserves the 5 pre-opened handles.)
4. Store a far pointer to your array at psp:34.
5. Change the int at psp:32 to 40.

This works in MS-DOS 3.2, and probably in earlier versions.
-- 
Dave Levenson
Westmark, Inc.		A node for news.
Warren, NJ USA
{rutgers | clyde | mtune | ihnp4}!westmark!dave

ddl@husc6.UUCP (Dan Lanciani) (09/20/87)

In article <173@westmark.UUCP>, dave@westmark.UUCP (Dave Levenson) writes:
| In article <1576@dicome.UUCP>, stryker@dicome.UUCP (don Stryker) writes:
| 
| > I've run up against a disturbing feature of the Microsoft C compiler
| > for the PC.  Microsoft limits an applicaton to 20 open files, 5 of 
| > which are taken up by the standard file handles.  I can open my files
| > using DOS system calls to bypass the compiler, ...
| 
| This limit is imposed by MS-DOS itself, not by the C compiler.

	Unfortunately, the limit is also imposed by the C library
which maintains its own table of open file descriptors.  This table
contains information about the binary/text mode of the file and
whether it is open (don't know why they really need the second).
(This is for MSC 4.0.)

| There is a far pointer in the psp at offset 0x34 which points to an
| array of unsigned char called the open file list.  The length of
| this array is stored as an int at psp offset 0x32.  When MS-DOS
| builds the psp, the array, itself, begins at psp offset 0x18 and is
| 20 bytes long.  To allow, for example, 40 files in a process, do the
| following:
| 
| First: set the FILES= parameter in config.sys to a large number. (>40)
| 
| Then, in your code:
| 
| 1. Allocate a static array of 40 unsigned char.
| 2. Initialize each element of the array to 0xff.
| 3. Copy the 20 bytes from the original array in psp:18 into your
|    array. (This preserves the 5 pre-opened handles.)
| 4. Store a far pointer to your array at psp:34.
| 5. Change the int at psp:32 to 40.

	Then find crt0dat.asm on your startup source disk and enlarge
the file descriptor table from 20 to whatever size you need.  Build
the small, medium, compact, large, and huge versions of crt0dat.obj
and replace them in your libraries.

| This works in MS-DOS 3.2, and probably in earlier versions.

	It works in 3.1...  Note also that you may close some of those
5 initial descriptors to make a few free ones.

					Dan Lanciani
					ddl@harvard.*

frisk@krafla.UUCP (Fridrik Skulason) (09/23/87)

In article <173@westmark.UUCP> dave@westmark.UUCP (Dave Levenson) writes:
>
>This works in MS-DOS 3.2, and probably in earlier versions.
>-- 
In MS-DOS 3.3 you have a new system function "Sent handle count", which 
(almost) eliminates this problem.

INT 21H
     AH = 67H
     BX = desired number of handles

Returns Carry clear if ok
	Carry set if error (and error code in AX)

atbowler@orchid.UUCP (10/08/87)

It has already been pointed out that the limits is not in
the C implementation but the operating system.  As a rule of
thumb if you want a program to be portable try not to depend
on having too many files open at once.  Operating system
imposed limits on the order of 20 files are extremely common.
It seems to be a favourite number with operating systems
implementors although they enforce it in a number of different
ways.

rickf@ihlpa.ATT.COM (Fritz) (10/09/87)

Keywords:


In article <11098@orchid.waterloo.edu> atbowler@orchid.waterloo.edu (Alan T. Bowler [SDG]) writes:
>It has already been pointed out that the limits is not in
>the C implementation but the operating system. ...
> Operating system imposed limits on the order of 20 files ...
>It seems to be a favourite number with operating systems
>implementors although they enforce it in a number of different ways.

The 'favourite' limit comes from (I think) the normal UNIX default FILE
table size of 20 entries.

In MS-DOS the op-sys limit can be changed with a line in the config.sys file
of the form:
	FILES=<Number of handle wanted>
	
Rick Frankel
ihn[4!ihlpa!rickf

henry@utzoo.UUCP (Henry Spencer) (10/11/87)

> ... Operating system
> imposed limits on the order of 20 files are extremely common.
> It seems to be a favourite number with operating systems
> implementors...

This is at least partly because the limit was 20 in Unix V7, which was the
(more or less) direct ancestor of practically every existing Unix system
and was also a major influence on non-Unix systems.
-- 
"Mir" means "peace", as in           |  Henry Spencer @ U of Toronto Zoology
"the war is over; we've won".        | {allegra,ihnp4,decvax,utai}!utzoo!henry

rwhite@nusdhub.UUCP (Robert C. White Jr.) (10/11/87)

In article <5819@ihlpa.ATT.COM>, rickf@ihlpa.ATT.COM (Fritz) writes:
> In MS-DOS the op-sys limit can be changed with a line in the config.sys file
> of the form:
> 	FILES=<Number of handle wanted>

But ho!, this changees the "SYSTEM WIDE" limit on the number of files
opened for the whole system.  There is STILL a maximum of 20 open files
per-process.  [Or the value of FILES, whichever is smaller]

Setting this to a larger number does not really help unless you are
useing a windowing package [or some such].

Rob White

dave@westmark.UUCP (Dave Levenson) (10/14/87)

In article <5819@ihlpa.ATT.COM>, rickf@ihlpa.ATT.COM (Fritz) writes:
> In article <11098@orchid.waterloo.edu> atbowler@orchid.waterloo.edu (Alan T. Bowler [SDG]) writes:
...
> > Operating system imposed limits on the order of 20 files ...
...
> In MS-DOS the op-sys limit can be changed with a line in the config.sys file
> of the form:
> 	FILES=<Number of handle wanted>


No, this doesn't solve Mr Bowler's problem!   The FILES= line in
config.sys adjusts the global limit (for all processes) but does not
increase the number of files available in any one process beyond 20.
The FILES= limit is the sum of the files opened by all processes,
active or dormant. 

Setting FILES= beyond 20 allows a process to open a lot of files,
and then spawn a subordinate process which then opens more files. 
The per-process file limit is imposed by the structure of the psp. 
It can be over-ridden by moving the table of file handles out of the
PSP and into user space.

The limit imposed by the MS-C runtime library, however, still gets
in the way.  Does anyone know how to circumvent that one?
-- 
Dave Levenson
Westmark, Inc.		A node for news.
Warren, NJ USA
{rutgers | clyde | mtune | ihnp4}!westmark!dave

bc@halley.UUCP (Bill Crews) (10/19/87)

In article <5819@ihlpa.ATT.COM> rickf@ihlpa.UUCP (rick frankel) writes:
>In MS-DOS the op-sys limit can be changed with a line in the config.sys file
>of the form:
>	FILES=<Number of handle wanted>

This changes the number of files that may be concurrently open system-wide,
not per user.  The 20-handle limit still exists per process, but with the
FILES variable set to, say, 100, several child processes and/or TSRs can have
several files open apiece, but each process is still limited to 20 (sysin,
sysout, syserr, sysaux, sysprn, and 15 more).

-bc
-- 
Bill Crews                                   Tandem Computers
                                             Austin, Texas
..!rutgers!ut-sally!im4u!esc-bb!halley!bc     (512) 244-8350

jpd@usl-pc.UUCP (DugalJP) (10/27/87)

In article <291@halley.UUCP> bc@halley.UUCP (Bill Crews) writes:
>>	FILES=<Number of handle wanted>
>This changes the number of files that may be concurrently open system-wide,
>not per user.  The 20-handle limit still exists per process, but with the

Not true!  It's possible to exceed the 20 file limit per-process by modifying
the PSP.  It was all described in Dr. Dobbs Journal some time ago.  The PSP
contains a 20-element list of handles, and a pointer to this list.  The
tecnique involves replacing the offset with that of a longer list you have
allocated somewhere, and copying over the handles and filling the unused
list elements.