delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/09/24/05:08:10

Date: Mon, 24 Sep 2001 12:06:48 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: Tim Van Holder <tim DOT van DOT holder AT pandora DOT be>
cc: djgpp-workers AT delorie DOT com
Subject: Re: The Perl/FD issue: update
In-Reply-To: <000601c1445e$8d466520$047d76d5@pandora.be>
Message-ID: <Pine.SUN.3.91.1010924120559.25254E-100000@is>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp-workers AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Sun, 23 Sep 2001, Tim Van Holder wrote:

> +Auto-closing file:
> +  _cnt            = 0
> +  _ptr            = 0
> +  _base           = 0
> +  _bufsiz         = 0
> +  _flag           = 514
> +  _file           = 3
> +  _name_to_remove = (null)
> +  _fillsize       = 0
> +* fflush(f) returns 0
> +* fclose(f) returns 0
> >> FD 3, but not our file
> +Auto-closing file:
> +  _cnt            = 15075
> +  _ptr            = 137b2d
> +  _base           = 137610
> +  _bufsiz         = 16384
> +  _flag           = 48
> +  _file           = 3
> +  _name_to_remove = (null)
> +  _fillsize       = 0
> +* fflush(f) returns -1
> +* fclose(f) returns -1
> >> Aha - BINGO - this is actually our file.

Thanks for debugging this.

> So the problem seems to be that FD 3 gets closed using the
> WRONG FILE structure (stdaux?) -> the close works, but does
> no flushing.  Then the fflush and close fail because the FD
> is closed.

Yes, that is what happens.

> So I guess we need skip stdaux and stdprn in fcloseall, if
> those FD's were closed at startup?

How would you know that stdaux/stdprn were closed at startup?  If
their handle is reused by some other file, there's no way to know
that, I think.

Even if there were a way, what you found is an indication of a larger
problem, not limited to stdaux/stdprn.  It will happen with any FILE
stream whose file handle is closed with a call to `close' (as opposed
to `fclose').  The problem is that calling `close' leaves the FILE
object in a state where the next call to `fopen' cannot reuse it,
because it looks as if it were still being used.  So `fopen' creates
another FILE object, but `open' returns the same handle (3, in this
case) which we just closed.  So now we have two FILE objects which
record the same file handle, but one of them is ``dead'': no output
will ever use it.  If stdiohk.c walks the FILE objects in a wrong
order, it will try to fclose the ``dead'' FILE object first, and the
``alive'' FILE object will never get a chance to be fflushed properly.

Fixing this is a bit tricky.  Hmm...

Okay, one possibility is to change `fwalk' to walk the FILE objects
from end to start, on the assumption that the ``dead'' FILEs will be
closer to the beginning of the list.  That requires a change in the
data structure used by `__alloc_file', since it currently lacks a back
pointer.  It is also somewhat risky to assume that the ``alive'' FILE
object will _always_ be after the ``dead'' one.

Another possibility is to add to `_close' or to `close' code which
will walk FILE objects and if it finds one that uses the handle being
closed, it will mark that FILE object as unused, like `fclose' does.
The disadvantage of this is that it slows down `_close'/`close', and
doesn't catch code which closes the handle via `__dpmi_int' or
`int86'.

Yet another possibility would be to modify `__alloc_file' to test the
handle in each FILE object when it looks for an empty slot: if the
handle is invalid, it could consider the FILE object unused, even if
its flags say otherwise, and reuse that slot.  To see if the handle is
invalid, we could lseek(fd, SEEK_CUR, 0L), for example.

I like the last alternative more than the others, but the question is:
could there be some program out there which closes a handle of a FILE
object, but still uses that FILE object later, perhaps with a
different handle, and calls `fopen' in between on top of that?  And if
there is such a program, can we dismiss it by saying it's buggy?

Actually, the second alternative above has the same problem as the
third.

Comments?  Thoughts?

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019