xref: /third_party/musl/src/stdio/__stdio_write.c (revision 570af302)
1#include "stdio_impl.h"
2#include <sys/uio.h>
3#include <string.h>
4
5ssize_t __flush_buffer(FILE *f)
6{
7	ssize_t cnt = 0;
8	char *wbase = (char *)f->wbase;
9	size_t rem = f->wpos - f->wbase;
10	while (rem > 0) {
11		cnt = syscall(SYS_write, f->fd, wbase, rem);
12		if (cnt < 0) {
13			f->wpos = f->wbase = f->wend = 0;
14			f->flags |= F_ERR;
15			return cnt;
16		}
17		wbase += cnt;
18		rem -= cnt;
19	}
20
21	/* reset file buffer */
22	f->wend = f->buf + f->buf_size;
23	f->wpos = f->wbase = f->buf;
24	return cnt;
25}
26
27size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
28{
29	size_t rem = len;
30	unsigned char *wbuf = (unsigned char *)buf;
31
32	/* flush buffer first */
33	ssize_t cnt = __flush_buffer(f);
34	if (cnt < 0) {
35		return 0;
36	}
37
38	for (;;) {
39		if (f->lbf < 0 && rem <= f->wend - f->wpos) {
40			memcpy(f->wpos, wbuf, rem);
41			f->wpos += rem;
42			return len;
43		}
44
45		/* write directly if
46		 * 1. file buffer < rem
47		 * 2. line buffer mode
48		 */
49		cnt = syscall(SYS_write, f->fd, wbuf, rem);
50		if (cnt < 0) {
51			f->wpos = f->wbase = f->wend = 0;
52			f->flags |= F_ERR;
53			return len - rem;
54		}
55
56		rem -= cnt;
57		wbuf += cnt;
58		if (rem == 0) {
59			break;
60		}
61	}
62
63	return len;
64}
65