[Patch] Fix libstdc++/9533

Paolo Carlini pcarlini@unitus.it
Tue Mar 4 09:14:00 GMT 2003


Nathan Myers wrote:

>>Does it make a difference? I adapted the whole scheme from an example
>>somewhere ;) and fcntl(this->fd(), F_SETFL, O_NONBLOCK); was already
>>in the code, instead.
>>
>The other flags that might be set (and which would be cleared here)
>are O_APPEND, O_ASYNC, and any OS-local extensions.
>
Ok. Thanks for the explanation.

>>The current showmanyc() is really simple:
>>... 
>>Dunno what can be put in it according to the standard.
>>
>Almost anything.  This is good, because now we don't need the 
>block() and no_block() functions; it all goes in showmanyc().
>showmanyc() is supposed to tell all it can find out about how
>many bytes are really there, not just how many it has buffered
>or will buffer, but it shouldn't take too long about it.
>
Yes.
I agree that it would be great to avoid the block/no_block
functions and putting everything inside showmanyc(). On the other
hand, what I find a little disturbing is that, instead of doing
this very-low-level work once, during open(), we end up doing it
repeatedly every time showmanyc() is called. And in general,
as a general design issue, this kind of code is really special:
you are not going to find any low-level system call inside the
other member functions.
Don't you share with me the feeling that perhaps the problem can
be fixed (or better avoided completely) by using a new higher
level strategy, perhaps even involving, a largish redesign of some
components, I don't know?

Anyway...

>Ideally showmanyc() should try to do an fstat64() on the file 
>descriptor and report the result, if any.   If it's not a file,
>then the IFREG or S_ISREG flag won't be set, and the st_size 
>isn't meaningful.  (If fstat64() reports more bytes than a 
>streamsize could represent, it ought to return 
>numeric_limits<streamsize>::max().  (Of course there might not
>be an fstat64(), so that would have to be #ifdef'ed, and use
>fstat() then.))
>
>It also ought to try 
>
>  ::recv(this->fd(), 0, 0, (MSG_DONTWAIT|MSG_PEEK|MSG_NOSIGNAL))
>
>in case it's a socket or pipe.  In fact, it should prefer that 
>over setting and clearing flags on the file descriptor and calling 
>underflow.  It would be rude for showmanyc to actually read the bytes 
>when it doesn't have to.  (If it returns -1, then errno is set to 
>EAGAIN if it meant to return zero.)
>
Thanks Nathan for this invaluable information. If we all agree to
actually put this kinf of code inside showmanyc (or better inside a
__basic_file function called from there, of course)  your explanations
should be largely sufficient for me to prepare something which (almost)
works.

Two questions, as a check of my understanding:
1- You suggest first calling fstat, then, if IFREG or S_IREG are not set,
calling recv, in order to acquire the similar information for pipes?

2- After that, we do _not_ actually read the data into the buffer, just
return from showmanyc a sensible value, a next underflow will do,
sure to obtain at least that amount of data.

Many thanks again,
Paolo.



More information about the Libstdc++ mailing list