Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 02 Jul 1996 16:19:27 +0800
From:      Peter Wemm <peter@spinner.DIALix.COM>
To:        joerg_wunsch@uriah.heep.sax.de (Joerg Wunsch)
Cc:        jmz@freefall.freebsd.org (Jean-Marc Zucconi), CVS-committers@freefall.freebsd.org, cvs-all@freefall.freebsd.org, cvs-usrbin@freefall.freebsd.org
Subject:   Re: cvs commit: src/usr.bin/fetch main.c 
Message-ID:  <199607020819.QAA08915@spinner.DIALix.COM>
In-Reply-To: Your message of "Tue, 02 Jul 1996 08:39:46 %2B0200." <199607020639.IAA10225@uriah.heep.sax.de> 

next in thread | previous in thread | raw e-mail | index | archive | help
>>>J Wunsch said:
> As Jean-Marc Zucconi wrote:
> > jmz         96/07/01 18:49:49
> > 
> >   Modified:    usr.bin/fetch  main.c
> >   Log:
> >   Use read(fileno(fp), ...) instead of fread(..., fp) to avoid buffered inp
    ut.
> 
> I'm still against it, and i consider it bad style that you're
> committing something that has caused opposition in the mailing lists.
> 
> You haven't even marked your change with
> 
> 	/* XXX bogus */
> 
> as would be the least sign of warning.
> 
> If all your concern is avoiding input buffering, why have you never
> considered doing The Right Thing and using setvbuf(3)?

The problem isn't buffering, it's fread() itself.  libftpio has broken one 
of the fundamental features of ftpget, being the up-to-date status 
reporting.  read() returns as soon as a tcp push happens, and the loop 
checks to see if the next status report is due.  If you use fread(), it 
waits until the entire 30K buffer has been read.  setvbuf() doesn't seem 
to have any effect on this situation, as the only way out of the while 
loop in fread.c is to get an eof or error.


ie: in filbuf.c:
        fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size);
        fp->_flags &= ~__SMOD;  /* buffer contents are again pristine */
        if (fp->_r <= 0) {
                if (fp->_r == 0)
                        fp->_flags |= __SEOF;
                else {
                        fp->_r = 0;
                        fp->_flags |= __SERR;
                }
                return (EOF);
        }
        return (0);
and in fread.c:
        while (resid > (r = fp->_r)) {
                (void)memcpy((void *)p, (void *)fp->_p, (size_t)r);
                fp->_p += r;
                /* fp->_r = 0 ... done in __srefill */
                p += r;
                resid -= r;
                if (__srefill(fp)) {
                        /* no more input: return partial result */
                        return ((total - resid) / size);
                }
        }
There is no way for fread() to simply return the data that has been read 
so far on a tcp connection, which is what's needed here.


The other thing that I've found that seems to work OK is to reduce the 32K 
fread() buffer down to 1K or lower still.

-Peter





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199607020819.QAA08915>