This is the mail archive of the
mailing list for the libstdc++ project.
Re: [Patch] Fix libstdc++/9533
Nathan Myers wrote:
Ok. Thanks for the explanation.
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.
The current showmanyc() is really simple:Almost anything. This is good, because now we don't need the
block() and no_block() functions; it all goes in showmanyc().
Dunno what can be put in it according to the standard.
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.
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?
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
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)
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,