initial check-in, version 0.5.0
[musl] / src / stdio / fwrite.c
1 #include "stdio_impl.h"
2
3 size_t __fwritex(const unsigned char *s, size_t l, FILE *f)
4 {
5         size_t i = 0;
6         size_t k = f->wend - f->wpos;
7
8         /* Handle line-buffered mode by breaking into 2 parts */
9         if (f->lbf >= 0) {
10                 /* Match /^(.*\n|)/ */
11                 for (i=l; i && s[i-1] != '\n'; i--);
12                 if (i) {
13                         f->lbf = EOF;
14                         __fwritex(s, i, f);
15                         f->lbf = '\n';
16                         __oflow(f);
17                         return ferror(f) ? 0 : i + __fwritex(s+i, l-i, f);
18                 }
19         }
20
21         /* Buffer initial segment */
22         if (k > l) k = l;
23         memcpy(f->wpos, s, k);
24         f->wpos += k;
25         if (f->wpos < f->wend) return l;
26
27         /* If there's work left to do, flush buffer */
28         __oflow(f);
29         if (ferror(f)) return 0;
30
31         /* If the remainder will not fit in buffer, write it directly */
32         if (l - k >= f->wend - f->wpos)
33                 return k + f->write(f, s+k, l-k);
34
35         /* Otherwise, buffer the remainder */
36         memcpy(f->wpos, s+k, l-k);
37         f->wpos += l-k;
38         return l;
39 }
40
41 size_t fwrite(const void *src, size_t size, size_t nmemb, FILE *f)
42 {
43         size_t l = size*nmemb;
44         if (!l) return l;
45         FLOCK(f);
46         l = __fwritex(src, l, f);
47         FUNLOCK(f);
48         return l/size;
49 }
50
51 weak_alias(fwrite, fwrite_unlocked);