21,6 → 21,7 |
#include <string.h> |
#include <stdlib.h> |
#include <errno.h> |
#include <limits.h> |
#include "local.h" |
#include "fvwrite.h" |
|
52,7 → 53,7 |
register size_t len; |
register _CONST char *p = NULL; |
register struct __siov *iov; |
register int w, s; |
register _READ_WRITE_RETURN_TYPE w, s; |
char *nl; |
int nlknown, nldist; |
|
89,12 → 90,14 |
if (fp->_flags & __SNBF) |
{ |
/* |
* Unbuffered: write up to BUFSIZ bytes at a time. |
* Unbuffered: Split buffer in the largest multiple of BUFSIZ < INT_MAX |
* as some legacy code may expect int instead of size_t. |
*/ |
do |
{ |
GETIOV (;); |
w = fp->_write (ptr, fp->_cookie, p, MIN (len, BUFSIZ)); |
w = fp->_write (ptr, fp->_cookie, p, |
MIN (len, INT_MAX - INT_MAX % BUFSIZ)); |
if (w <= 0) |
goto err; |
p += w; |
155,8 → 158,10 |
newsize); |
if (!str) |
{ |
/* Free buffer which is no longer used. */ |
/* Free buffer which is no longer used and clear |
__SMBF flag to avoid double free in fclose. */ |
_free_r (ptr, fp->_bf._base); |
fp->_flags &= ~__SMBF; |
/* Ensure correct errno, even if free changed it. */ |
ptr->_errno = ENOMEM; |
goto err; |
175,30 → 180,24 |
fp->_p += w; |
w = len; /* but pretend copied all */ |
} |
else if (fp->_p > fp->_bf._base && len > w) |
else if (fp->_p > fp->_bf._base || len < fp->_bf._size) |
{ |
/* fill and flush */ |
/* pass through the buffer */ |
w = MIN (len, w); |
COPY (w); |
/* fp->_w -= w; *//* unneeded */ |
fp->_w -= w; |
fp->_p += w; |
if (_fflush_r (ptr, fp)) |
if (fp->_w == 0 && _fflush_r (ptr, fp)) |
goto err; |
} |
else if (len >= (w = fp->_bf._size)) |
else |
{ |
/* write directly */ |
w = ((int)MIN (len, INT_MAX)) / fp->_bf._size * fp->_bf._size; |
w = fp->_write (ptr, fp->_cookie, p, w); |
if (w <= 0) |
goto err; |
} |
else |
{ |
/* fill and done */ |
w = len; |
COPY (w); |
fp->_w -= w; |
fp->_p += w; |
} |
p += w; |
len -= w; |
} |