diff options
author | Steven <sluong@cisco.com> | 2017-10-04 13:47:38 -0700 |
---|---|---|
committer | Steven <sluong@cisco.com> | 2017-10-04 13:47:38 -0700 |
commit | dc217c26c9c950dd3849ae24f7e28ffcb6dce21e (patch) | |
tree | 1f7424d4c302b43032455299801c1bbb2e475062 | |
parent | 529ec1b1c1a76a2ac6c85f5c6d5c180280e139dd (diff) |
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 <sluong@cisco.com>
-rw-r--r-- | vcl-ldpreload/src/libvcl-ldpreload/vcom.c | 94 | ||||
-rw-r--r-- | vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.c | 16 | ||||
-rw-r--r-- | vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.h | 4 |
3 files changed, 106 insertions, 8 deletions
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 <dlfcn.h> #include <pthread.h> #include <time.h> - +#include <sys/uio.h> +#include <limits.h> +#define __need_IOV_MAX +#include <bits/stdio_lim.h> #include <stdarg.h> #include <libvcl-ldpreload/vcom_socket_wrapper.h> @@ -28,8 +31,6 @@ #include <uri/vppcom.h> #include <libvcl-ldpreload/vcom_socket.h> - - /* 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. diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.c b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.c index 8fe7e1d..c8b7ee6 100644 --- a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.c +++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.c @@ -578,6 +578,14 @@ libc_read (int fd, void *buf, size_t count) return swrap.libc.symbols._libc_read.f (fd, buf, count); } +ssize_t +libc_readv (int fd, const struct iovec *iov, int iovcnt) +{ + swrap_bind_symbol_libc (readv); + + return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt); +} + int libc_recv (int sockfd, void *buf, size_t len, int flags) { @@ -671,6 +679,14 @@ libc_write (int fd, const void *buf, size_t count) return swrap.libc.symbols._libc_write.f (fd, buf, count); } +ssize_t +libc_writev (int fd, const struct iovec *iov, int iovcnt) +{ + swrap_bind_symbol_libc (writev); + + return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt); +} + int libc_shutdown (int fd, int how) { diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.h b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.h index e3590d6..25aa609 100644 --- a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.h +++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.h @@ -142,6 +142,8 @@ int libc_listen (int sockfd, int backlog); int libc_read (int fd, void *buf, size_t count); +ssize_t libc_readv (int fd, const struct iovec *iov, int iovcnt); + int libc_recv (int sockfd, void *buf, size_t len, int flags); int @@ -173,6 +175,8 @@ int libc_socketpair (int domain, int type, int protocol, int sv[2]); ssize_t libc_write (int fd, const void *buf, size_t count); +ssize_t libc_writev (int fd, const struct iovec *iov, int iovcnt); + int libc_shutdown (int fd, int how); int |