This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch] Fix libstdc++/9533


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]