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/