xref: /plan9/sys/src/ape/lib/bsd/writev.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1*219b2ee8SDavid du Colombier #include <sys/types.h>
2*219b2ee8SDavid du Colombier #include <unistd.h>
3*219b2ee8SDavid du Colombier #include <string.h>
4*219b2ee8SDavid du Colombier 
5*219b2ee8SDavid du Colombier /* bsd extensions */
6*219b2ee8SDavid du Colombier #include <sys/uio.h>
7*219b2ee8SDavid du Colombier #include <sys/socket.h>
8*219b2ee8SDavid du Colombier 
9*219b2ee8SDavid du Colombier #include "priv.h"
10*219b2ee8SDavid du Colombier 
11*219b2ee8SDavid du Colombier int
12*219b2ee8SDavid du Colombier writev(int fd, struct iovec *v, int ent)
13*219b2ee8SDavid du Colombier {
14*219b2ee8SDavid du Colombier 	int i, n, written;
15*219b2ee8SDavid du Colombier 	char *t, *e, *f;
16*219b2ee8SDavid du Colombier 	char buf[10*1024];
17*219b2ee8SDavid du Colombier 
18*219b2ee8SDavid du Colombier 	written = n = 0;
19*219b2ee8SDavid du Colombier 	t = buf;
20*219b2ee8SDavid du Colombier 	e = buf+sizeof(buf);
21*219b2ee8SDavid du Colombier 	for(;ent ; v++, ent--){
22*219b2ee8SDavid du Colombier 		n = v->iov_len;
23*219b2ee8SDavid du Colombier 		f = v->iov_base;
24*219b2ee8SDavid du Colombier 		while(n > 0){
25*219b2ee8SDavid du Colombier 			i = e-t;
26*219b2ee8SDavid du Colombier 			if(n < i){
27*219b2ee8SDavid du Colombier 				memmove(t, f, n);
28*219b2ee8SDavid du Colombier 				t += n;
29*219b2ee8SDavid du Colombier 				break;
30*219b2ee8SDavid du Colombier 			}
31*219b2ee8SDavid du Colombier 			memmove(t, f, i);
32*219b2ee8SDavid du Colombier 			n -= i;
33*219b2ee8SDavid du Colombier 			f += i;
34*219b2ee8SDavid du Colombier 			i = write(fd, buf, sizeof(buf));
35*219b2ee8SDavid du Colombier 			if(i < 0){
36*219b2ee8SDavid du Colombier 				if(written > 0){
37*219b2ee8SDavid du Colombier 					return written;
38*219b2ee8SDavid du Colombier 				}else{
39*219b2ee8SDavid du Colombier 					_syserrno();
40*219b2ee8SDavid du Colombier 					return -1;
41*219b2ee8SDavid du Colombier 				}
42*219b2ee8SDavid du Colombier 			}
43*219b2ee8SDavid du Colombier 			written += i;
44*219b2ee8SDavid du Colombier 			if(i != sizeof(buf)) {
45*219b2ee8SDavid du Colombier 				return written;
46*219b2ee8SDavid du Colombier 			}
47*219b2ee8SDavid du Colombier 			t = buf;
48*219b2ee8SDavid du Colombier 		}
49*219b2ee8SDavid du Colombier 	}
50*219b2ee8SDavid du Colombier 	i = t - buf;
51*219b2ee8SDavid du Colombier 	if(i > 0){
52*219b2ee8SDavid du Colombier 		n = write(fd, buf, i);
53*219b2ee8SDavid du Colombier 		if(n < 0){
54*219b2ee8SDavid du Colombier 			if(written == 0){
55*219b2ee8SDavid du Colombier 				_syserrno();
56*219b2ee8SDavid du Colombier 				return -1;
57*219b2ee8SDavid du Colombier 			}
58*219b2ee8SDavid du Colombier 		} else
59*219b2ee8SDavid du Colombier 			written += n;
60*219b2ee8SDavid du Colombier 	}
61*219b2ee8SDavid du Colombier 	return written;
62*219b2ee8SDavid du Colombier }
63