Completely unexplicable (to me ;) behaviour of read (vs fread)

Paolo Carlini pcarlini@unitus.it
Sat Mar 8 20:16:00 GMT 2003


Hi,

regtesting the fix for 7744, which I'm preparing along the
lines already discussed in detail, I'm seeing completely
unexpected failures in filebuf_virtuals.cc.

Consider this sequence:

  fb_03.pubseekoff(0, std::ios_base::end);
  c1 = fb_03.sgetc();
  c2 = fb_03.sungetc();

Sungetc() calls pbackfail() which, then, calls underflow here:

   // At the beginning of the buffer, need to make a
   // putback position available.
   // But the seek may fail (f.i., at the beginning of
   // a file, see libstdc++/9439) and in that case
   // we return traits_type::eof()
   if (this->seekoff(-1, ios_base::cur) >= 0)
     {
       this->underflow();

Inside underflow the new _M_file.xsgetn() is called, which, when
the last parameter is false means read instead of fread:

   __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),
                           _M_buf_size, false);

The new xsgetn is:

  __basic_file<char>::xsgetn(char* __s, streamsize __n, bool __stdio)
  {
    if (__stdio)
      return fread(__s, 1, __n, _M_cfile);
    else
      {
        streamsize __ret;
        do
          {
            errno = 0;
            __ret = read(this->fd(), __s, __n);
          }
        while (__ret == -1L && errno == EINTR);
        return __ret;
      }
   }

The big mistery is that read (vs fread) in this situation returns _zero_
instead of one! No chars are read.

Any idea what I'm doing wrong?

Thanks once more,
Paolo.

P.S. I have already tried clearing O_NONBLOCK (as will eventually be the
case, after the fix for 9533), with no differences.



More information about the Libstdc++ mailing list