Date: Mon, 3 May 1999 07:43:43 +0300 (IDT) From: Eli Zaretskii X-Sender: eliz AT is To: DJ Delorie cc: djgpp-workers AT delorie DOT com Subject: Re: Windows 9X bug when it runs out of file handles In-Reply-To: <199905021813.OAA06944@envy.delorie.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk On Sun, 2 May 1999, DJ Delorie wrote: > I think a better solution would be to check for the specific errors > that mean "file not found" where calling _creat makes sense. That > way, random errors we aren't expecting in the future won't cause > problems by slipping thought to _creat. It seems I was too quick in blaming Windows. The real story behind this problem is much simpler: we *always* call _creat when _open fails, and Windows simply truncates the file before it realizes that it has no more handles to return to the caller (evidently, DOS does it the other way around and thus doesn't fail like that). So here's a better patch (relative to the original v2.02 source). I believe it also references your concerns about being defensive wrt unexpected problems in the future: *** src/libc/posix/fcntl/open.c1~ Sun Jun 28 22:47:08 1998 --- src/libc/posix/fcntl/open.c Mon May 3 06:28:00 1999 *************** open(const char* filename, int oflag, .. *** 59,72 **** { fd = _open(filename, oflag); ! /* Under multi-taskers, such as Windows, our file might be open ! by some other program with DENY-NONE sharing bit, which fails ! the `_open' call above. Try again with DENY-NONE bit set, ! unless some sharing bits were already set in the initial call. */ ! if (fd == -1 && dont_have_share) ! fd = _open(filename, oflag | SH_DENYNO); ! if (fd == -1 && oflag & O_CREAT) ! fd = _creat(filename, dmode); } if (fd == -1) --- 59,86 ---- { fd = _open(filename, oflag); ! if (fd == -1) ! { ! /* It doesn't make sense to try anything else if there are no ! more file handles available. */ ! if (errno == EMFILE || errno == ENFILE) ! return fd; ! ! if (__file_exists(filename)) ! { ! /* Under multi-taskers, such as Windows, our file might be ! open by some other program with DENY-NONE sharing bit, ! which fails the `_open' call above. Try again with ! DENY-NONE bit set, unless some sharing bits were already ! set in the initial call. */ ! if (dont_have_share) ! fd = _open(filename, oflag | SH_DENYNO); ! } ! /* Don't call _creat on existing files for which _open fails, ! since the file could be truncated as a result. */ ! else if ((oflag & O_CREAT)) ! fd = _creat(filename, dmode); ! } } if (fd == -1)