On 01.06.21 18:10, Olaf Hering wrote: > Read a batch of iovec's. > > In the common case of short reads, finish individual iov's with read_exact. > > Signed-off-by: Olaf Hering > --- > tools/libs/ctrl/xc_private.c | 55 +++++++++++++++++++++++++++++++++++- > tools/libs/ctrl/xc_private.h | 1 + > 2 files changed, 55 insertions(+), 1 deletion(-) > > diff --git a/tools/libs/ctrl/xc_private.c b/tools/libs/ctrl/xc_private.c > index d94f846686..ea420b9ba8 100644 > --- a/tools/libs/ctrl/xc_private.c > +++ b/tools/libs/ctrl/xc_private.c > @@ -659,8 +659,23 @@ int write_exact(int fd, const void *data, size_t size) > > #if defined(__MINIOS__) > /* > - * MiniOS's libc doesn't know about writev(). Implement it as multiple write()s. > + * MiniOS's libc doesn't know about readv/writev(). > + * Implement it as multiple read/write()s. > */ > +int readv_exact(int fd, const struct iovec *iov, int iovcnt) > +{ > + int rc, i; > + > + for ( i = 0; i < iovcnt; ++i ) > + { > + rc = read_exact(fd, iov[i].iov_base, iov[i].iov_len); > + if ( rc ) > + return rc; > + } > + > + return 0; > +} > + > int writev_exact(int fd, const struct iovec *iov, int iovcnt) > { > int rc, i; > @@ -675,6 +690,44 @@ int writev_exact(int fd, const struct iovec *iov, int iovcnt) > return 0; > } > #else > +int readv_exact(int fd, const struct iovec *iov, int iovcnt) > +{ > + int rc = 0, idx = 0; > + ssize_t len; > + > + while ( idx < iovcnt ) > + { > + len = readv(fd, &iov[idx], min(iovcnt - idx, IOV_MAX)); > + if ( len == -1 && errno == EINTR ) > + continue; > + if ( len <= 0 ) > + { > + rc = -1; Is EOF really an error? > + goto out; > + } > + while ( len > 0 && idx < iovcnt ) > + { > + if ( len >= iov[idx].iov_len ) > + { > + len -= iov[idx].iov_len; > + } > + else > + { > + void *p = iov[idx].iov_base + len; > + size_t l = iov[idx].iov_len - len; > + > + rc = read_exact(fd, p, l); > + if ( rc ) > + goto out; > + len = 0; This will stop the loop, even if idx hasn't reached iovcnt. > + } > + idx++; > + } > + } > +out: > + return rc; > +} > + Juergen