aboutsummaryrefslogtreecommitdiffstats
path: root/vcl-ldpreload
diff options
context:
space:
mode:
Diffstat (limited to 'vcl-ldpreload')
-rw-r--r--vcl-ldpreload/src/libvcl-ldpreload/vcom.c94
-rw-r--r--vcl-ldpreload/src/libvcl-ldpreload/vcom.h4
-rw-r--r--vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c131
-rw-r--r--vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h4
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