summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChip Salzenberg <chip@pobox.com>2004-03-09 23:51:41 +0000
committerchip <chip@pobox.com>2004-03-09 23:51:41 +0000
commitb392781d461bfc107b8449e5c9d7f596d578ead5 (patch)
tree135ab958b74b22f4a7cf590e2b2f33199d1f1317
parentcd863ffdf1d9c1185aa1ef18b26ddb1f72ff33e0 (diff)
downloadperl-b392781d461bfc107b8449e5c9d7f596d578ead5.tar.gz
[PERLIO] In line-buffered mode, flush on the *last* newline,
not on every newline. p4raw-id: //depot/perl@22478
-rw-r--r--perlio.c37
1 files changed, 16 insertions, 21 deletions
diff --git a/perlio.c b/perlio.c
index 87ac75f4a5..da4a1822b6 100644
--- a/perlio.c
+++ b/perlio.c
@@ -3691,6 +3691,7 @@ PerlIOBuf_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
{
PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
const STDCHAR *buf = (const STDCHAR *) vbuf;
+ const STDCHAR *flushptr = buf;
Size_t written = 0;
if (!b->buf)
PerlIO_get_base(f);
@@ -3701,32 +3702,26 @@ PerlIOBuf_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
return 0;
}
}
+ if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF) {
+ flushptr = buf + count;
+ while (flushptr > buf && *(flushptr - 1) != '\n')
+ --flushptr;
+ }
while (count > 0) {
SSize_t avail = b->bufsiz - (b->ptr - b->buf);
if ((SSize_t) count < avail)
avail = count;
+ if (flushptr > buf && flushptr <= buf + avail)
+ avail = flushptr - buf;
PerlIOBase(f)->flags |= PERLIO_F_WRBUF;
- if (PerlIOBase(f)->flags & PERLIO_F_LINEBUF) {
- while (avail > 0) {
- int ch = *buf++;
- *(b->ptr)++ = ch;
- count--;
- avail--;
- written++;
- if (ch == '\n') {
- PerlIO_flush(f);
- break;
- }
- }
- }
- else {
- if (avail) {
- Copy(buf, b->ptr, avail, STDCHAR);
- count -= avail;
- buf += avail;
- written += avail;
- b->ptr += avail;
- }
+ if (avail) {
+ Copy(buf, b->ptr, avail, STDCHAR);
+ count -= avail;
+ buf += avail;
+ written += avail;
+ b->ptr += avail;
+ if (buf == flushptr)
+ PerlIO_flush(f);
}
if (b->ptr >= (b->buf + b->bufsiz))
PerlIO_flush(f);