xref: /aosp_15_r20/external/musl/src/stdio/__stdio_write.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
1*c9945492SAndroid Build Coastguard Worker #include "stdio_impl.h"
2*c9945492SAndroid Build Coastguard Worker #include <sys/uio.h>
3*c9945492SAndroid Build Coastguard Worker 
__stdio_write(FILE * f,const unsigned char * buf,size_t len)4*c9945492SAndroid Build Coastguard Worker size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
5*c9945492SAndroid Build Coastguard Worker {
6*c9945492SAndroid Build Coastguard Worker 	struct iovec iovs[2] = {
7*c9945492SAndroid Build Coastguard Worker 		{ .iov_base = f->wbase, .iov_len = f->wpos-f->wbase },
8*c9945492SAndroid Build Coastguard Worker 		{ .iov_base = (void *)buf, .iov_len = len }
9*c9945492SAndroid Build Coastguard Worker 	};
10*c9945492SAndroid Build Coastguard Worker 	struct iovec *iov = iovs;
11*c9945492SAndroid Build Coastguard Worker 	size_t rem = iov[0].iov_len + iov[1].iov_len;
12*c9945492SAndroid Build Coastguard Worker 	int iovcnt = 2;
13*c9945492SAndroid Build Coastguard Worker 	ssize_t cnt;
14*c9945492SAndroid Build Coastguard Worker 	for (;;) {
15*c9945492SAndroid Build Coastguard Worker 		cnt = syscall(SYS_writev, f->fd, iov, iovcnt);
16*c9945492SAndroid Build Coastguard Worker 		if (cnt == rem) {
17*c9945492SAndroid Build Coastguard Worker 			f->wend = f->buf + f->buf_size;
18*c9945492SAndroid Build Coastguard Worker 			f->wpos = f->wbase = f->buf;
19*c9945492SAndroid Build Coastguard Worker 			return len;
20*c9945492SAndroid Build Coastguard Worker 		}
21*c9945492SAndroid Build Coastguard Worker 		if (cnt < 0) {
22*c9945492SAndroid Build Coastguard Worker 			f->wpos = f->wbase = f->wend = 0;
23*c9945492SAndroid Build Coastguard Worker 			f->flags |= F_ERR;
24*c9945492SAndroid Build Coastguard Worker 			return iovcnt == 2 ? 0 : len-iov[0].iov_len;
25*c9945492SAndroid Build Coastguard Worker 		}
26*c9945492SAndroid Build Coastguard Worker 		rem -= cnt;
27*c9945492SAndroid Build Coastguard Worker 		if (cnt > iov[0].iov_len) {
28*c9945492SAndroid Build Coastguard Worker 			cnt -= iov[0].iov_len;
29*c9945492SAndroid Build Coastguard Worker 			iov++; iovcnt--;
30*c9945492SAndroid Build Coastguard Worker 		}
31*c9945492SAndroid Build Coastguard Worker 		iov[0].iov_base = (char *)iov[0].iov_base + cnt;
32*c9945492SAndroid Build Coastguard Worker 		iov[0].iov_len -= cnt;
33*c9945492SAndroid Build Coastguard Worker 	}
34*c9945492SAndroid Build Coastguard Worker }
35