mirror of
https://github.com/uselessd/alcove.git
synced 2026-04-15 17:25:33 +00:00
alcove_write: fix end of array check
This code looked fishy to me but I couldn't pinpoint why and it worked on
Ubuntu 12.04/armv7l, Ubuntu 12.04/amd64, OpenBSD 5.5/amd64 and FreeBSD
10/amd64. I forgot to test on Ubuntu 14.04/amd64 of course and
thankfully it failed there.
The code compares the number of bytes written by writev against each of
the iov_len fields in the iovec array and decrements the value
accordingly. So an iovec array that looks like:
iov[0].iov_len = 4
iov[1].iov_len = 6
number of bytes written = 10 bytes
Would be computed as follows:
count = 2
0: 10 >= iov[0].iov_len (4) -> 6
1: 6 >= iov[1].iov_len (6) -> 0
2: 0 >= iov[2].iov_len (undefined) -> ???
3: ...
Limit iteration to the size of the iovec array. Although this commit fixes
this issue, this code should either be further simplified or re-written.
This commit is contained in:
@@ -511,24 +511,24 @@ alcove_write(int fd, struct iovec *iov, int count)
|
||||
{
|
||||
ssize_t written = 0;
|
||||
ssize_t n = 0;
|
||||
int cur = 0;
|
||||
int offset = 0;
|
||||
|
||||
for ( ; ; ) {
|
||||
written = writev(fd, iov+cur, count-cur);
|
||||
do {
|
||||
iov[offset].iov_base = (char *)iov[offset].iov_base + written;
|
||||
iov[offset].iov_len -= written;
|
||||
|
||||
written = writev(fd, iov+offset, count-offset);
|
||||
if (written <= 0)
|
||||
return written;
|
||||
|
||||
n += written;
|
||||
|
||||
while (written >= iov[cur].iov_len)
|
||||
written -= iov[cur++].iov_len;
|
||||
for ( ; offset < count && written >= iov[offset].iov_len; offset++)
|
||||
written -= iov[offset].iov_len;
|
||||
|
||||
if (cur == count)
|
||||
return n;
|
||||
} while (offset < count);
|
||||
|
||||
iov[cur].iov_base = (char *)iov[cur].iov_base + written;
|
||||
iov[cur].iov_len -= written;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user