diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2024-04-28 14:28:03 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2024-04-28 14:28:03 +0000 |
commit | 891358d20de03c388fb10d0148c4660261604dda (patch) | |
tree | 1ac0768f34c564815c7096278da22fcdbf9372fe /lib/libc | |
parent | c2247d7ef89055fcaa31cc6422dbcfc00fd168f5 (diff) |
__sfvwrite: allow writing buffers larger than BUFSIZ or st_blksize.
This can vastly improve write performance. For unbuffered writes,
we now write up to INT_MAX instead of BUFSIZE. For buffered writes,
write the largest multiple of the buffer size (which may be st_blksize).
From Apple via enh at google. OK tb@
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/stdio/fvwrite.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c index d83de884581..d615245abc2 100644 --- a/lib/libc/stdio/fvwrite.c +++ b/lib/libc/stdio/fvwrite.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fvwrite.c,v 1.21 2023/10/06 16:41:02 millert Exp $ */ +/* $OpenBSD: fvwrite.c,v 1.22 2024/04/28 14:28:02 millert Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -31,6 +31,7 @@ * SUCH DAMAGE. */ +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -76,11 +77,12 @@ __sfvwrite(FILE *fp, struct __suio *uio) } if (fp->_flags & __SNBF) { /* - * Unbuffered: write up to BUFSIZ bytes at a time. + * Unbuffered: write up to INT_MAX bytes at a time, to not + * truncate the value of len if it is greater than 2^31 bytes. */ do { GETIOV(;); - w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ)); + w = (*fp->_write)(fp->_cookie, p, MIN(len, INT_MAX)); if (w <= 0) goto err; p += w; @@ -90,7 +92,8 @@ __sfvwrite(FILE *fp, struct __suio *uio) /* * Fully buffered: fill partially full buffer, if any, * and then flush. If there is no partial buffer, write - * one _bf._size byte chunk directly (without copying). + * entire payload directly (without copying) up to a + * multiple of the buffer size. * * String output is a special case: write as many bytes * as fit, but pretend we wrote everything. This makes @@ -134,7 +137,15 @@ __sfvwrite(FILE *fp, struct __suio *uio) if (__sflush(fp)) goto err; } else if (len >= (w = fp->_bf._size)) { - /* write directly */ + /* + * Write directly up to INT_MAX or greatest + * multiple of buffer size (whichever is + * smaller), keeping in the memory buffer the + * remaining part of payload that is smaller + * than buffer size. + */ + if (w != 0) + w = MIN(w * (len / w), INT_MAX); w = (*fp->_write)(fp->_cookie, p, w); if (w <= 0) goto err; |