[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: man-db segfault: problem found (but need help for the solution :-)

Steve Greenland wrote:
> On Nov 11, Richard Braakman <dark@xs4all.nl> wrote:
> > [app closes stderr, spawns child who writes to stderr, which
> >  causes corruption ]
> > Then it writes to stderr.  The stdio library apparently did not
> > know that stderr started out closed, and happily writes to file
> > descriptor 2.  I think this is a bug in the stdio library.
> Huh? A descriptor is a descriptor is a descriptor. How is the library
> supposed to know what the programs intent was? The bug is in the
> program that closes streams that its children depend on.

Well, I was not so precise as I should (late night), writing that the
parent program closed the stream ...
If this were the case, it would have been a bug in stdio (it is not).

Instead, the parent program closes the _file_ to which the stream is
associated, leaving a dangling stream ready to write to whatever file
will happen to get the same handle.
This is a bug in the parent program, and I have just raised it.

> > If you want a quick hack, just put
> >
> >      /* Skip fd's 0 through 2 even if they are available */
> >      open("/dev/null", O_WRONLY);
> >      open("/dev/null", O_WRONLY);
> >      open("/dev/null", O_WRONLY);
> >
> > in main() somewhere close to the beginning.
> 1) quote the line in the POSIX spec that says open() always uses the
> lowest numbered available descriptor. (It may actually say this,
> I don't have a copy available, but it seems unlikely.)

I have looked at the X3J11 excerpts included in Plauger's book (1992)
and in fact it doesn't say such a thing.
However we know that open() will do that on Linux and also other unices,
so I have added the following test at the beginning of man:

{ /* opens base streams in case someone like "info" closed their
associated files */ 
        struct stat buf;
        if ( fstat( 0, &buf) < 0 ) 
                freopen( "/dev/null", "r", 0);
        if ( fstat( 1, &buf) < 0 ) 
                freopen( "/dev/null", "w", 1);
        if ( fstat( 2, &buf) < 0 ) 
                freopen( "/dev/null", "w", 2);

This will associate a new file to the stream if the stream was open
while the file was not; this will not overwrite any setting of those
streams made by any parent process.

> 2) Assuming this works, it leaves stderr dumping to /dev/null, making
> error messages less than accessible.
> Why not just take the close of stdout and stderr out of the parent
> program? Surely it's not using hard-coded descriptors? Or is it doing
> something "clever" with pipes...?

Only on stdout; therefore it doesn't want to have stderr output, thus it
should redirect stderr to /dev/null , not close it.

| fpolacco@icenet.fi    fpolacco@debian.org    fpolacco@pluto.linux.it
| Pluto Leader - Debian Developer & Happy Debian 1.3.1 User - vi-holic
| 6F7267F5 fingerprint 57 16 C4 ED C9 86 40 7B 1A 69 A1 66 EC FB D2 5E

TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-devel-request@lists.debian.org . 
Trouble?  e-mail to templin@bucknell.edu .

Reply to: