diff options
Diffstat (limited to 'src/stdio/fwrite.c')
-rw-r--r-- | src/stdio/fwrite.c | 44 |
1 files changed, 15 insertions, 29 deletions
diff --git a/src/stdio/fwrite.c b/src/stdio/fwrite.c index 23974fe1..02908c4b 100644 --- a/src/stdio/fwrite.c +++ b/src/stdio/fwrite.c @@ -2,50 +2,36 @@ size_t __fwritex(const unsigned char *s, size_t l, FILE *f) { - size_t i = 0; - size_t k = f->wend - f->wpos; + size_t i=0; + + if (!f->wend && __towrite(f)) return 0; + + if (l > f->wend - f->wpos) return f->write(f, s, l); - /* Handle line-buffered mode by breaking into 2 parts */ if (f->lbf >= 0) { /* Match /^(.*\n|)/ */ for (i=l; i && s[i-1] != '\n'; i--); if (i) { - f->lbf = EOF; - __fwritex(s, i, f); - f->lbf = '\n'; - __oflow(f); - return ferror(f) ? 0 : i + __fwritex(s+i, l-i, f); + if (f->write(f, s, i) < i) + return i; + s += i; + l -= i; } } - /* Buffer initial segment */ - if (k > l) k = l; - memcpy(f->wpos, s, k); - f->wpos += k; - if (f->wpos < f->wend) return l; - - /* If there's work left to do, flush buffer */ - __oflow(f); - if (ferror(f)) return 0; - - /* If the remainder will not fit in buffer, write it directly */ - if (l - k >= f->wend - f->wpos) - return k + f->write(f, s+k, l-k); - - /* Otherwise, buffer the remainder */ - memcpy(f->wpos, s+k, l-k); - f->wpos += l-k; - return l; + memcpy(f->wpos, s, l); + f->wpos += l; + return l+i; } size_t fwrite(const void *src, size_t size, size_t nmemb, FILE *f) { - size_t l = size*nmemb; + size_t k, l = size*nmemb; if (!l) return l; FLOCK(f); - l = __fwritex(src, l, f); + k = __fwritex(src, l, f); FUNLOCK(f); - return l/size; + return k==l ? nmemb : l/size; } weak_alias(fwrite, fwrite_unlocked); |