1 #include "stdio_impl.h"
2 #include <sys/uio.h>
3 #include <string.h>
4 
__flush_buffer(FILE *f)5 ssize_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 
__stdio_write(FILE *f, const unsigned char *buf, size_t len)27 size_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