Mail Archives: cygwin/2006/09/14/13:26:56
Volker Quetschke <quetschke <at> scytek.de> writes:
> >
> (snip)
> > +#ifdef __CYGWIN__
> > + /* lseek'ing on text files is problematic; lseek reports the true
> > + file offset, but read collapses \r\n and returns a character
> > + count. We cannot reliably seek backwards if nr is smaller than
> > + the seek offset encountered during the read, and must instead
> > + treat the stream as unbuffered. */
> > + if ((bp->b_flag & (B_TEXT | B_UNBUFF)) == B_TEXT)
> ------------------------^^^^^^^^^^^^^^^^^ ^^^^^^
> part of the patch looks suspicious to me. You probably just want to test
> if the LHS expression is true.
That part is correct as presented - I really did mean to check with bitwise AND
if we are dealing with a text file which has not previously been marked
unbuffered...
>
> Volker
>
> > + {
> > + off_t offset = lseek (bp->b_fd, 0, SEEK_CUR);
> > + nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
...as the condition to perform extra lseeks and make sure that lseek and the
unbuffered text file are still consistent; if not...
> > + if (nr > 0 && nr < lseek (bp->b_fd, 0, SEEK_CUR) - offset)
> > + {
> > + lseek (bp->b_fd, offset, SEEK_SET);
> > + bp->b_flag |= B_UNBUFF;
... we change the flags to mark the stream unbuffered, and never fall into this
if-block again for the rest of the life of the file.
> > + nr = zread (bp->b_fd, bp->b_buffer, bp->b_size = 1);
> > + }
> > + }
> > + else
> > +#endif
> > nr = zread (bp->b_fd, bp->b_buffer, bp->b_size);
And the else-block works equally well whether a file is non-text (reading
multiple bytes), or is unbuffered (reading just one byte). The other thing to
remember is that a file will be marked unbuffered if you cannot seek on it (as
in a pipe), or if it is a text file that failed the lseek consistency checks
above. And it does mean that even with \n line endings on a text mount, that
although the file is read in the same number of buffers as the corresponding
binary mount, the text mount is penalized with 2 additional lseeks per buffer,
but that is a smaller penalty than doing one-byte reads.
> > if (nr <= 0)
> > {
--
Eric Blake
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -