From dc217c26c9c950dd3849ae24f7e28ffcb6dce21e Mon Sep 17 00:00:00 2001 From: Steven Date: Wed, 4 Oct 2017 13:47:38 -0700 Subject: LDPRELOAD: Implement readv and writev Iteratively call vcom_read for readv and vcom_write for writev system call. Change-Id: I1d5795165e22c84b3303dde3273ce0cfa76abb4a Signed-off-by: Steven --- vcl-ldpreload/src/libvcl-ldpreload/vcom.c | 94 ++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 8 deletions(-) (limited to 'vcl-ldpreload/src/libvcl-ldpreload/vcom.c') diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom.c b/vcl-ldpreload/src/libvcl-ldpreload/vcom.c index 37cf936..564df1a 100644 --- a/vcl-ldpreload/src/libvcl-ldpreload/vcom.c +++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom.c @@ -18,7 +18,10 @@ #include #include #include - +#include +#include +#define __need_IOV_MAX +#include #include #include @@ -28,8 +31,6 @@ #include #include - - /* GCC have printf type attribute check. */ #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT #define PRINTF_ATTRIBUTE(a,b) \ @@ -62,11 +63,6 @@ #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE #endif - - - - - #define VCOM_SOCKET_FD_MAX 0x10000 static char vcom_app_name[MAX_VCOM_APP_NAME]; @@ -260,6 +256,47 @@ read (int __fd, void *__buf, size_t __nbytes) return libc_read (__fd, __buf, __nbytes); } +ssize_t +readv (int __fd, const struct iovec * __iov, int __iovcnt) +{ + size_t len = 0; + ssize_t total = 0; + + if (is_vcom_socket_fd (__fd)) + { + if (__iov == 0 || __iovcnt == 0 || __iovcnt > IOV_MAX) + return -EINVAL; + + /* Sanity check */ + for (int i = 0; i < __iovcnt; ++i) + { + if (SSIZE_MAX - len < __iov[i].iov_len) + return -EINVAL; + len += __iov[i].iov_len; + } + + for (int i = 0; i < __iovcnt; ++i) + { + len = vcom_read (__fd, __iov[i].iov_base, __iov[i].iov_len); + if (len < 0) + { + if (total > 0) + return total; + else + { + errno = len;; + return -1; + } + } + else + total += len; + } + return (total); + } + else + return libc_readv (__fd, __iov, __iovcnt); +} + /* Write N bytes of BUF to FD. Return the number written, or -1. This function is a cancellation point and therefore @@ -307,6 +344,47 @@ write (int __fd, const void *__buf, size_t __n) return libc_write (__fd, __buf, __n); } +ssize_t +writev (int __fd, const struct iovec * __iov, int __iovcnt) +{ + size_t len = 0; + ssize_t total = 0; + + if (is_vcom_socket_fd (__fd)) + { + if (__iov == 0 || __iovcnt == 0 || __iovcnt > IOV_MAX) + return -EINVAL; + + /* Sanity check */ + for (int i = 0; i < __iovcnt; ++i) + { + if (SSIZE_MAX - len < __iov[i].iov_len) + return -EINVAL; + len += __iov[i].iov_len; + } + + for (int i = 0; i < __iovcnt; ++i) + { + len = vcom_write (__fd, __iov[i].iov_base, __iov[i].iov_len); + if (len < 0) + { + if (total > 0) + return total; + else + { + errno = len;; + return -1; + } + } + else + total += len; + } + return (total); + } + else + return libc_writev (__fd, __iov, __iovcnt); +} + /* Do the file control operation described by CMD on FD. The remaining arguments are interpreted depending on CMD. -- cgit 1.2.3-korg