xref: /plan9/sys/src/ape/lib/bsd/writev.c (revision 781103c4074deb8af160e8a0da2742ba6b29dc2b)
1219b2ee8SDavid du Colombier #include <sys/types.h>
2219b2ee8SDavid du Colombier #include <unistd.h>
3219b2ee8SDavid du Colombier #include <string.h>
4219b2ee8SDavid du Colombier 
5219b2ee8SDavid du Colombier /* bsd extensions */
6219b2ee8SDavid du Colombier #include <sys/uio.h>
7219b2ee8SDavid du Colombier #include <sys/socket.h>
8219b2ee8SDavid du Colombier 
9219b2ee8SDavid du Colombier #include "priv.h"
10219b2ee8SDavid du Colombier 
11219b2ee8SDavid du Colombier int
writev(int fd,struct iovec * v,int ent)12219b2ee8SDavid du Colombier writev(int fd, struct iovec *v, int ent)
13219b2ee8SDavid du Colombier {
14219b2ee8SDavid du Colombier 	int i, n, written;
15219b2ee8SDavid du Colombier 	char *t, *e, *f;
16219b2ee8SDavid du Colombier 	char buf[10*1024];
17219b2ee8SDavid du Colombier 
18*781103c4SDavid du Colombier 	written = 0;
19219b2ee8SDavid du Colombier 	t = buf;
20219b2ee8SDavid du Colombier 	e = buf+sizeof(buf);
21219b2ee8SDavid du Colombier 	for(;ent ; v++, ent--){
22219b2ee8SDavid du Colombier 		n = v->iov_len;
23219b2ee8SDavid du Colombier 		f = v->iov_base;
24219b2ee8SDavid du Colombier 		while(n > 0){
25219b2ee8SDavid du Colombier 			i = e-t;
26219b2ee8SDavid du Colombier 			if(n < i){
27219b2ee8SDavid du Colombier 				memmove(t, f, n);
28219b2ee8SDavid du Colombier 				t += n;
29219b2ee8SDavid du Colombier 				break;
30219b2ee8SDavid du Colombier 			}
31219b2ee8SDavid du Colombier 			memmove(t, f, i);
32219b2ee8SDavid du Colombier 			n -= i;
33219b2ee8SDavid du Colombier 			f += i;
34219b2ee8SDavid du Colombier 			i = write(fd, buf, sizeof(buf));
35219b2ee8SDavid du Colombier 			if(i < 0){
36219b2ee8SDavid du Colombier 				if(written > 0){
37219b2ee8SDavid du Colombier 					return written;
38219b2ee8SDavid du Colombier 				}else{
39219b2ee8SDavid du Colombier 					_syserrno();
40219b2ee8SDavid du Colombier 					return -1;
41219b2ee8SDavid du Colombier 				}
42219b2ee8SDavid du Colombier 			}
43219b2ee8SDavid du Colombier 			written += i;
44219b2ee8SDavid du Colombier 			if(i != sizeof(buf)) {
45219b2ee8SDavid du Colombier 				return written;
46219b2ee8SDavid du Colombier 			}
47219b2ee8SDavid du Colombier 			t = buf;
48219b2ee8SDavid du Colombier 		}
49219b2ee8SDavid du Colombier 	}
50219b2ee8SDavid du Colombier 	i = t - buf;
51219b2ee8SDavid du Colombier 	if(i > 0){
52219b2ee8SDavid du Colombier 		n = write(fd, buf, i);
53219b2ee8SDavid du Colombier 		if(n < 0){
54219b2ee8SDavid du Colombier 			if(written == 0){
55219b2ee8SDavid du Colombier 				_syserrno();
56219b2ee8SDavid du Colombier 				return -1;
57219b2ee8SDavid du Colombier 			}
58219b2ee8SDavid du Colombier 		} else
59219b2ee8SDavid du Colombier 			written += n;
60219b2ee8SDavid du Colombier 	}
61219b2ee8SDavid du Colombier 	return written;
62219b2ee8SDavid du Colombier }
63