diff options
Diffstat (limited to 'vcl-ldpreload')
-rw-r--r-- | vcl-ldpreload/src/libvcl-ldpreload/vcom.c | 94 | ||||
-rw-r--r-- | vcl-ldpreload/src/libvcl-ldpreload/vcom.h | 4 | ||||
-rw-r--r-- | vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c | 131 | ||||
-rw-r--r-- | vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h | 4 |
4 files changed, 173 insertions, 60 deletions
diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom.c b/vcl-ldpreload/src/libvcl-ldpreload/vcom.c index eb5e8d1..7a13249 100644 --- a/vcl-ldpreload/src/libvcl-ldpreload/vcom.c +++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom.c @@ -18,10 +18,6 @@ #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> @@ -264,41 +260,30 @@ read (int __fd, void *__buf, size_t __nbytes) } ssize_t +vcom_readv (int __fd, const struct iovec * __iov, int __iovcnt) +{ + if (vcom_init () != 0) + { + return -1; + } + + return vcom_socket_readv (__fd, __iov, __iovcnt); +} + +ssize_t readv (int __fd, const struct iovec * __iov, int __iovcnt) { - size_t len = 0; - ssize_t total = 0; + ssize_t size = 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) + size = vcom_readv (__fd, __iov, __iovcnt); + if (size < 0) { - 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; + errno = -size; + return -1; } - return (total); + return size; } else return libc_readv (__fd, __iov, __iovcnt); @@ -352,41 +337,30 @@ write (int __fd, const void *__buf, size_t __n) } ssize_t +vcom_writev (int __fd, const struct iovec * __iov, int __iovcnt) +{ + if (vcom_init () != 0) + { + return -1; + } + + return vcom_socket_writev (__fd, __iov, __iovcnt); +} + +ssize_t writev (int __fd, const struct iovec * __iov, int __iovcnt) { - size_t len = 0; - ssize_t total = 0; + ssize_t size = 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) + size = vcom_writev (__fd, __iov, __iovcnt); + if (size < 0) { - 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; + errno = -size; + return -1; } - return (total); + return size; } else return libc_writev (__fd, __iov, __iovcnt); diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom.h b/vcl-ldpreload/src/libvcl-ldpreload/vcom.h index d751fe1..1706c0e 100644 --- a/vcl-ldpreload/src/libvcl-ldpreload/vcom.h +++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom.h @@ -44,6 +44,10 @@ extern ssize_t __wur vcom_read (int __fd, void *__buf, size_t __nbytes); extern ssize_t __wur vcom_write (int __fd, const void *__buf, size_t __n); +extern ssize_t __wur vcom_readv (int __fd, const struct iovec * __iov, int __iovcnt); + +extern ssize_t __wur vcom_writev (int __fd, const struct iovec * __iov, int __iovcnt); + /* * vpp implementation of glibc APIs from <fcntl.h> */ diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c index 9d2b795..415d277 100644 --- a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c +++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c @@ -14,6 +14,10 @@ */ #include <unistd.h> #include <stdio.h> +#include <sys/uio.h> +#include <limits.h> +#define __need_IOV_MAX +#include <bits/stdio_lim.h> #include <vppinfra/types.h> #include <vppinfra/hash.h> @@ -471,6 +475,93 @@ vcom_socket_read (int __fd, void *__buf, size_t __nbytes) } ssize_t +vcom_socket_readv (int __fd, const struct iovec * __iov, int __iovcnt) +{ + int rv; + vcom_socket_main_t *vsm = &vcom_socket_main; + uword *p; + vcom_socket_t *vsock; + ssize_t total = 0, len = 0; + + p = hash_get (vsm->sockidx_by_fd, __fd); + if (!p) + return -EBADF; + + vsock = pool_elt_at_index (vsm->vsockets, p[0]); + if (!vsock) + return -ENOTSOCK; + + if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND) + return -EINVAL; + + 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; + } + + rv = vcom_fcntl (__fd, F_GETFL, 0); + if (rv < 0) + { + return rv; + } + + /* is blocking */ + if (!(rv & O_NONBLOCK)) + { + do + { + for (int i = 0; i < __iovcnt; ++i) + { + rv = vppcom_session_read (vsock->sid, __iov[i].iov_base, + __iov[i].iov_len); + if (rv < 0) + break; + else + { + total += rv; + if (rv < __iov[i].iov_len) + /* Read less than buffer provided, no point to continue */ + break; + } + } + } + while ((rv == -EAGAIN || rv == -EWOULDBLOCK) && total == 0); + return total; + } + + /* is non blocking */ + for (int i = 0; i < __iovcnt; ++i) + { + rv = vppcom_session_read (vsock->sid, __iov[i].iov_base, + __iov[i].iov_len); + if (rv < 0) + { + if (total > 0) + break; + else + { + errno = rv; + return rv; + } + } + else + { + total += rv; + if (rv < __iov[i].iov_len) + /* Read less than buffer provided, no point to continue */ + break; + } + } + return total; +} + +ssize_t vcom_socket_write (int __fd, const void *__buf, size_t __n) { int rv = -1; @@ -498,6 +589,46 @@ vcom_socket_write (int __fd, const void *__buf, size_t __n) return rv; } +ssize_t +vcom_socket_writev (int __fd, const struct iovec * __iov, int __iovcnt) +{ + int rv = -1; + ssize_t total = 0; + vcom_socket_main_t *vsm = &vcom_socket_main; + uword *p; + vcom_socket_t *vsock; + + p = hash_get (vsm->sockidx_by_fd, __fd); + if (!p) + return -EBADF; + + vsock = pool_elt_at_index (vsm->vsockets, p[0]); + if (!vsock) + return -ENOTSOCK; + + if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND) + return -EINVAL; + + if (__iov == 0 || __iovcnt == 0 || __iovcnt > IOV_MAX) + return -EINVAL; + + for (int i = 0; i < __iovcnt; ++i) + { + rv = vppcom_session_write (vsock->sid, __iov[i].iov_base, + __iov[i].iov_len); + if (rv < 0) + { + if (total > 0) + break; + else + return rv; + } + else + total += rv; + } + return total; +} + /* * RETURN: 0 - invalid cmd * 1 - cmd not handled by vcom and vppcom diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h index 1592075..56539d1 100644 --- a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h +++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h @@ -340,8 +340,12 @@ int vcom_socket_close (int __fd); ssize_t vcom_socket_read (int __fd, void *__buf, size_t __nbytes); +ssize_t vcom_socket_readv (int __fd, const struct iovec * __iov, int __iovcnt); + ssize_t vcom_socket_write (int __fd, const void *__buf, size_t __n); +ssize_t vcom_socket_writev (int __fd, const struct iovec * __iov, int __iovcnt); + int vcom_socket_fcntl_va (int __fd, int __cmd, va_list __ap); int |