]>
git.proxmox.com Git - qemu.git/blob - iov.c
2 * Helpers for getting linearized buffers from iov / filling buffers into iovs
4 * Copyright IBM, Corp. 2007, 2008
5 * Copyright (C) 2010 Red Hat, Inc.
8 * Anthony Liguori <aliguori@us.ibm.com>
9 * Amit Shah <amit.shah@redhat.com>
10 * Michael Tokarev <mjt@tls.msk.ru>
12 * This work is licensed under the terms of the GNU GPL, version 2. See
13 * the COPYING file in the top-level directory.
15 * Contributions after 2012-01-13 are licensed under the terms of the
16 * GNU GPL, version 2 or (at your option) any later version.
23 # include <winsock2.h>
25 # include <sys/types.h>
26 # include <sys/socket.h>
29 size_t iov_from_buf(struct iovec
*iov
, unsigned int iov_cnt
,
30 size_t offset
, const void *buf
, size_t bytes
)
34 for (i
= 0, done
= 0; (offset
|| done
< bytes
) && i
< iov_cnt
; i
++) {
35 if (offset
< iov
[i
].iov_len
) {
36 size_t len
= MIN(iov
[i
].iov_len
- offset
, bytes
- done
);
37 memcpy(iov
[i
].iov_base
+ offset
, buf
+ done
, len
);
41 offset
-= iov
[i
].iov_len
;
48 size_t iov_to_buf(const struct iovec
*iov
, const unsigned int iov_cnt
,
49 size_t offset
, void *buf
, size_t bytes
)
53 for (i
= 0, done
= 0; (offset
|| done
< bytes
) && i
< iov_cnt
; i
++) {
54 if (offset
< iov
[i
].iov_len
) {
55 size_t len
= MIN(iov
[i
].iov_len
- offset
, bytes
- done
);
56 memcpy(buf
+ done
, iov
[i
].iov_base
+ offset
, len
);
60 offset
-= iov
[i
].iov_len
;
67 size_t iov_memset(const struct iovec
*iov
, const unsigned int iov_cnt
,
68 size_t offset
, int fillc
, size_t bytes
)
72 for (i
= 0, done
= 0; (offset
|| done
< bytes
) && i
< iov_cnt
; i
++) {
73 if (offset
< iov
[i
].iov_len
) {
74 size_t len
= MIN(iov
[i
].iov_len
- offset
, bytes
- done
);
75 memset(iov
[i
].iov_base
+ offset
, fillc
, len
);
79 offset
-= iov
[i
].iov_len
;
86 size_t iov_size(const struct iovec
*iov
, const unsigned int iov_cnt
)
92 for (i
= 0; i
< iov_cnt
; i
++) {
93 len
+= iov
[i
].iov_len
;
98 /* helper function for iov_send_recv() */
100 do_send_recv(int sockfd
, struct iovec
*iov
, unsigned iov_cnt
, bool do_send
)
102 #if defined CONFIG_IOVEC && defined CONFIG_POSIX
105 memset(&msg
, 0, sizeof(msg
));
107 msg
.msg_iovlen
= iov_cnt
;
110 ? sendmsg(sockfd
, &msg
, 0)
111 : recvmsg(sockfd
, &msg
, 0);
112 } while (ret
< 0 && errno
== EINTR
);
115 /* else send piece-by-piece */
116 /*XXX Note: windows has WSASend() and WSARecv() */
119 for (i
= 0; i
< iov_cnt
; ++i
) {
121 ? send(sockfd
, iov
[i
].iov_base
, iov
[i
].iov_len
, 0)
122 : recv(sockfd
, iov
[i
].iov_base
, iov
[i
].iov_len
, 0);
127 } else if (errno
== EINTR
) {
130 /* else it is some "other" error,
131 * only return if there was no data processed. */
142 ssize_t
iov_send_recv(int sockfd
, struct iovec
*iov
, unsigned iov_cnt
,
143 size_t offset
, size_t bytes
,
147 unsigned si
, ei
; /* start and end indexes */
149 /* Find the start position, skipping `offset' bytes:
150 * first, skip all full-sized vector elements, */
151 for (si
= 0; si
< iov_cnt
&& offset
>= iov
[si
].iov_len
; ++si
) {
152 offset
-= iov
[si
].iov_len
;
155 assert(si
< iov_cnt
);
156 /* second, skip `offset' bytes from the (now) first element,
158 iov
[si
].iov_base
+= offset
;
159 iov
[si
].iov_len
-= offset
;
161 /* Find the end position skipping `bytes' bytes: */
162 /* first, skip all full-sized elements */
163 for (ei
= si
; ei
< iov_cnt
&& iov
[ei
].iov_len
<= bytes
; ++ei
) {
164 bytes
-= iov
[ei
].iov_len
;
167 /* second, fixup the last element, and remember
168 * the length we've cut from the end of it in `bytes' */
170 assert(ei
< iov_cnt
);
171 assert(iov
[ei
].iov_len
> bytes
);
172 tail
= iov
[ei
].iov_len
- bytes
;
173 iov
[ei
].iov_len
= bytes
;
174 bytes
= tail
; /* bytes is now equal to the tail size */
178 ret
= do_send_recv(sockfd
, iov
+ si
, ei
- si
, do_send
);
180 /* Undo the changes above */
182 iov
[si
].iov_base
-= offset
;
183 iov
[si
].iov_len
+= offset
;
186 iov
[ei
-1].iov_len
+= bytes
;
193 void iov_hexdump(const struct iovec
*iov
, const unsigned int iov_cnt
,
194 FILE *fp
, const char *prefix
, size_t limit
)
196 unsigned int i
, v
, b
;
200 for (i
= 0, v
= 0, b
= 0; b
< limit
; i
++, b
++) {
201 if (i
== iov
[v
].iov_len
) {
209 fprintf(fp
, "%s: %04x:", prefix
, b
);
214 fprintf(fp
, " %02x", c
[i
]);
215 if ((b
% 16) == 15) {