This is the mail archive of the cygwin mailing list for the Cygwin 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: bash-3.1-7 BUG


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/


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