LD_PRELOAD poll implementation
- add poll implementation
- implementation based on vppcom_poll
- implementation based on vppcom_select
- currently vppcom_select implementation is picked
Change-Id: If6c2862ae72e9969335aca5b8085957c98287dc0
Signed-off-by: shrinivasan ganapathy <shrinivasanganapathy@gmail.com>
Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
diff --git a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.c b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.c
index d5b3e12..35dbf57 100644
--- a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.c
+++ b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.c
@@ -19,6 +19,7 @@
#include <pthread.h>
#include <time.h>
#include <stdarg.h>
+#include <sys/resource.h>
#include <libvcl-ldpreload/vcom_socket_wrapper.h>
#include <libvcl-ldpreload/vcom.h>
@@ -2940,24 +2941,319 @@
This function is a cancellation point and therefore not marked with
__THROW. */
+
int
vcom_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
{
- if (vcom_init () != 0)
+ int rv = 0;
+ pid_t pid = getpid ();
+
+ struct rlimit nofile_limit;
+ struct pollfd vcom_fds[MAX_POLL_NFDS_DEFAULT];
+ nfds_t fds_idx = 0;
+
+ /* actual set of file descriptors to be monitored */
+ nfds_t libc_nfds = 0;
+ nfds_t vcom_nfds = 0;
+
+ /* ready file descriptors
+ *
+ * number of structures which have nonzero revents fields
+ * in other words, descriptors with events or errors reported.
+ * */
+ /* after call to libc_poll () */
+ int rlibc_nfds = 0;
+ /* after call to vcom_socket_poll () */
+ int rvcom_nfds = 0;
+
+
+ /* timeout value in units of timespec */
+ struct timespec timeout_ts;
+ struct timespec start_time, now, end_time;
+
+
+ /* get start_time */
+ rv = clock_gettime (CLOCK_MONOTONIC, &start_time);
+ if (rv == -1)
{
- return -1;
+ rv = -errno;
+ goto poll_done;
}
- return -EOPNOTSUPP;
+ /* set timeout_ts & end_time */
+ if (__timeout >= 0)
+ {
+ /* set timeout_ts */
+ timeout_ts.tv_sec = __timeout / MSEC_PER_SEC;
+ timeout_ts.tv_nsec = (__timeout % MSEC_PER_SEC) * NSEC_PER_MSEC;
+ set_normalized_timespec (&timeout_ts,
+ timeout_ts.tv_sec, timeout_ts.tv_nsec);
+ /* set end_time */
+ if (__timeout)
+ {
+ end_time = timespec_add (start_time, timeout_ts);
+ }
+ else
+ {
+ end_time = start_time;
+ }
+ }
+
+ if (vcom_init () != 0)
+ {
+ rv = -1;
+ goto poll_done;
+ }
+
+ /* validate __fds */
+ if (!__fds)
+ {
+ rv = -EFAULT;
+ goto poll_done;
+ }
+
+ /* validate __nfds */
+ /*TBD: call getrlimit once when vcl-ldpreload library is init */
+ rv = getrlimit (RLIMIT_NOFILE, &nofile_limit);
+ if (rv != 0)
+ {
+ rv = -errno;
+ goto poll_done;
+ }
+ if (__nfds >= nofile_limit.rlim_cur || __nfds < 0)
+ {
+ rv = -EINVAL;
+ goto poll_done;
+ }
+
+ /*
+ * for the POC, it's fair to assume that nfds is less than 1024
+ * */
+ if (__nfds >= MAX_POLL_NFDS_DEFAULT)
+ {
+ rv = -EINVAL;
+ goto poll_done;
+ }
+
+ /* set revents field (output parameter)
+ * to zero
+ * */
+ for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
+ {
+ __fds[fds_idx].revents = 0;
+ }
+
+#if 0
+ /* set revents field (output parameter)
+ * to zero for user ignored fds
+ * */
+ for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
+ {
+ /*
+ * if negative fd, ignore events field
+ * and set output parameter (revents field) to zero */
+ if (__fds[fds_idx].fd < 0)
+ {
+ __fds[fds_idx].revents = 0;
+ }
+ }
+#endif
+
+ /*
+ * 00. prepare __fds and vcom_fds for polling
+ * copy __fds to vcom_fds
+ * 01. negate all except libc fds in __fds,
+ * ignore user negated fds
+ * 02. negate all except vcom_fds in vocm fds,
+ * ignore user negated fds
+ * ignore fd 0 by setting it to negative number
+ * */
+ memcpy (vcom_fds, __fds, sizeof (*__fds) * __nfds);
+ libc_nfds = 0;
+ vcom_nfds = 0;
+ for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
+ {
+ /* ignore negative fds */
+ if (__fds[fds_idx].fd < 0)
+ {
+ continue;
+ }
+
+ /*
+ * 00. ignore vcom fds in __fds
+ * 01. ignore libc fds in vcom_fds,
+ * ignore fd 0 by setting it to negative number.
+ * as fd 0 cannot be ignored.
+ */
+ if (is_vcom_socket_fd (__fds[fds_idx].fd) ||
+ is_vcom_epfd (__fds[fds_idx].fd))
+ {
+ __fds[fds_idx].fd = -__fds[fds_idx].fd;
+ vcom_nfds++;
+ }
+ else
+ {
+ libc_nfds++;
+ /* ignore fd 0 by setting it to negative number */
+ if (!vcom_fds[fds_idx].fd)
+ {
+ vcom_fds[fds_idx].fd = -1;
+ }
+ vcom_fds[fds_idx].fd = -vcom_fds[fds_idx].fd;
+ }
+ }
+
+ /*
+ * polling loop
+ *
+ * poll on libc fds and vcom fds
+ *
+ * specifying a timeout of zero causes libc_poll() and
+ * vcom_socket_poll() to return immediately, even if no
+ * file descriptors are ready
+ * */
+ do
+ {
+ rlibc_nfds = 0;
+ rvcom_nfds = 0;
+
+ /*
+ * timeout parameter for libc_poll () set to zero
+ * to poll on libc fds
+ * */
+
+ /* poll on libc fds */
+ if (libc_nfds)
+ {
+ /*
+ * a timeout of zero causes libc_poll()
+ * to return immediately
+ * */
+ rlibc_nfds = libc_poll (__fds, __nfds, 0);
+ if (VCOM_DEBUG > 0)
+ fprintf (stderr,
+ "[%d] poll libc: "
+ "'%04d'='%08lu'\n", pid, rlibc_nfds, __nfds);
+
+ if (rlibc_nfds < 0)
+ {
+ rv = -errno;
+ goto poll_done_update_nfds;
+ }
+ }
+
+ /*
+ * timeout parameter for vcom_socket_poll () set to zero
+ * to poll on vcom fds
+ * */
+
+ /* poll on vcom fds */
+ if (vcom_nfds)
+ {
+ /*
+ * a timeout of zero causes vcom_socket_poll()
+ * to return immediately
+ * */
+ rvcom_nfds = vcom_socket_poll (vcom_fds, __nfds, 0);
+ if (VCOM_DEBUG > 0)
+ fprintf (stderr,
+ "[%d] poll vcom: "
+ "'%04d'='%08lu'\n", pid, rvcom_nfds, __nfds);
+ if (rvcom_nfds < 0)
+ {
+ rv = rvcom_nfds;
+ goto poll_done_update_nfds;
+ }
+ }
+
+ /* check if any file descriptors changed status */
+ if ((libc_nfds && rlibc_nfds > 0) || (vcom_nfds && rvcom_nfds > 0))
+ {
+ /* something interesting happened */
+ rv = rlibc_nfds + rvcom_nfds;
+ goto poll_done_update_nfds;
+ }
+
+ rv = clock_gettime (CLOCK_MONOTONIC, &now);
+ if (rv == -1)
+ {
+ rv = -errno;
+ goto poll_done_update_nfds;
+ }
+ }
+
+ /* block indefinitely || timeout elapsed */
+ while ((__timeout < 0) || timespec_compare (&now, &end_time) < 0);
+
+ /* timeout expired before anything interesting happened */
+ rv = 0;
+
+poll_done_update_nfds:
+ for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
+ {
+ /* ignore negative fds in vcom_fds
+ * 00. user negated fds
+ * 01. libc fds
+ * */
+ if (vcom_fds[fds_idx].fd < 0)
+ {
+ continue;
+ }
+
+ /* from here on handle positive vcom fds */
+ /*
+ * restore vcom fds to positive number in __fds
+ * and update revents in __fds with the events
+ * that actually occurred in vcom fds
+ * */
+ __fds[fds_idx].fd = -__fds[fds_idx].fd;
+ if (rvcom_nfds)
+ {
+ __fds[fds_idx].revents = vcom_fds[fds_idx].revents;
+ }
+ }
+
+poll_done:
+ if (VCOM_DEBUG > 0)
+ fprintf (stderr, "[%d] vpoll: " "'%04d'='%08lu'\n", pid, rv, __nfds);
+ return rv;
}
+/*
+ * 00. The field __fds[i].fd contains a file descriptor for an
+ * open file.
+ * If this field is negative, then the corresponding
+ * events field is ignored and the revents field returns zero.
+ * The field __fds[i].events is an input parameter.
+ * The field __fds[i].revents is an output parameter.
+ * 01. Specifying a negative value in timeout
+ * means an infinite timeout.
+ * Specifying a timeout of zero causes poll() to return
+ * immediately, even if no file descriptors are ready.
+ *
+ * NOTE: observed __nfds is less than 128 from kubecon strace files
+ */
+
+
int
poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
{
int rv = 0;
+ pid_t pid = getpid ();
- errno = EOPNOTSUPP;
- rv = -1;
+
+ if (VCOM_DEBUG > 0)
+ fprintf (stderr, "[%d] poll1: " "'%04d'='%08lu, %d, 0x%x'\n",
+ pid, rv, __nfds, __fds[0].fd, __fds[0].events);
+ rv = vcom_poll (__fds, __nfds, __timeout);
+ if (VCOM_DEBUG > 0)
+ fprintf (stderr, "[%d] poll2: " "'%04d'='%08lu, %d, 0x%x'\n",
+ pid, rv, __nfds, __fds[0].fd, __fds[0].revents);
+ if (rv < 0)
+ {
+ errno = -rv;
+ return -1;
+ }
return rv;
}
diff --git a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.h b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.h
index bedeef8..5871b52 100644
--- a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.h
+++ b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.h
@@ -178,6 +178,12 @@
vcom_epoll_pwait (int __epfd, struct epoll_event *__events,
int __maxevents, int __timeout, const __sigset_t * __ss);
+/*
+ * NOTE: observed __nfds is less than 128 from kubecon strace files
+ * for the POC, it's fair to assume that nfds is less than 1024.
+ * TBD: make it thread safe and design to scale.
+ * */
+#define MAX_POLL_NFDS_DEFAULT 1024
extern int vcom_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
#ifdef __USE_GNU
diff --git a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_glibc_socket.h b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_glibc_socket.h
index 0f1b174..4eb60fb 100644
--- a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_glibc_socket.h
+++ b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_glibc_socket.h
@@ -23,6 +23,8 @@
#include <fcntl.h>
#include <sys/epoll.h>
+
+#include <signal.h>
#include <poll.h>
/*
diff --git a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c
index 96108af..4a5f285 100644
--- a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c
+++ b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c
@@ -2793,6 +2793,395 @@
return rv;
}
+static inline void
+vcom_pollfds_2_selectfds (
+ /* src */
+ struct pollfd *__fds, nfds_t __nfds,
+ /* dest */
+ int vcom_nfds,
+ fd_set * __restrict vcom_readfds,
+ fd_set * __restrict vcom_writefds,
+ fd_set * __restrict vcom_exceptfds)
+{
+ nfds_t fds_idx = 0;
+
+ for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
+ {
+ /* ignore negative fds */
+ if (__fds[fds_idx].fd < 0)
+ {
+ continue;
+ }
+
+ /* for POLLRDHUP, POLLERR, POLLHUP and POLLNVAL */
+ FD_SET (__fds[fds_idx].fd, vcom_exceptfds);
+
+ /* requested events */
+ if (__fds[fds_idx].events)
+ {
+ if (__fds[fds_idx].events & POLLIN)
+ {
+ FD_SET (__fds[fds_idx].fd, vcom_readfds);
+ }
+ if (__fds[fds_idx].events & POLLPRI)
+ {
+ FD_SET (__fds[fds_idx].fd, vcom_readfds);
+ }
+ if (__fds[fds_idx].events & POLLOUT)
+ {
+ FD_SET (__fds[fds_idx].fd, vcom_writefds);
+ }
+#if defined __USE_XOPEN || defined __USE_XOPEN2K8
+ if (__fds[fds_idx].events & POLLRDNORM)
+ {
+ FD_SET (__fds[fds_idx].fd, vcom_readfds);
+ }
+ if (__fds[fds_idx].events & POLLRDBAND)
+ {
+ FD_SET (__fds[fds_idx].fd, vcom_readfds);
+ }
+ if (__fds[fds_idx].events & POLLWRNORM)
+ {
+ FD_SET (__fds[fds_idx].fd, vcom_writefds);
+ }
+ if (__fds[fds_idx].events & POLLWRBAND)
+ {
+ FD_SET (__fds[fds_idx].fd, vcom_writefds);
+ }
+#endif
+ }
+ } /* for (fds_idx = 0; fds_idx < __nfds; fds_idx++) */
+}
+
+static inline void
+vcom_selectfds_2_pollfds (
+ /* dest */
+ struct pollfd *__fds, nfds_t __nfds, int *nfd,
+ /* src */
+ int vcom_nfds,
+ fd_set * __restrict vcom_readfds,
+ fd_set * __restrict vcom_writefds,
+ fd_set * __restrict vcom_exceptfds)
+{
+ nfds_t fds_idx = 0;
+
+
+ for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
+ {
+ /* ignore negative fds */
+ if (__fds[fds_idx].fd < 0)
+ {
+ __fds[fds_idx].revents = 0;
+ }
+
+ /* for POLLRDHUP, POLLERR, POLLHUP and POLLNVAL */
+ if (FD_ISSET (__fds[fds_idx].fd, vcom_exceptfds))
+ {
+ /*
+ * TBD: for now any select exception
+ * is flagged as POLLERR
+ * */
+ __fds[fds_idx].revents |= POLLERR;
+ }
+
+ /* requested events */
+ if (__fds[fds_idx].events & POLLIN)
+ {
+ if (FD_ISSET (__fds[fds_idx].fd, vcom_readfds))
+ {
+ __fds[fds_idx].revents |= POLLIN;
+ }
+ }
+ if (__fds[fds_idx].events & POLLPRI)
+ {
+ if (FD_ISSET (__fds[fds_idx].fd, vcom_readfds))
+ {
+ __fds[fds_idx].revents |= POLLIN;
+ }
+ }
+ if (__fds[fds_idx].events & POLLOUT)
+ {
+ if (FD_ISSET (__fds[fds_idx].fd, vcom_writefds))
+ {
+ __fds[fds_idx].revents |= POLLOUT;
+ }
+ }
+#if defined __USE_XOPEN || defined __USE_XOPEN2K8
+ if (__fds[fds_idx].events & POLLRDNORM)
+ {
+ if (FD_ISSET (__fds[fds_idx].fd, vcom_readfds))
+ {
+ __fds[fds_idx].revents |= POLLRDNORM;
+ }
+ }
+ if (__fds[fds_idx].events & POLLRDBAND)
+ {
+ if (FD_ISSET (__fds[fds_idx].fd, vcom_readfds))
+ {
+ __fds[fds_idx].revents |= POLLRDBAND;
+ }
+ }
+ if (__fds[fds_idx].events & POLLWRNORM)
+ {
+ if (FD_ISSET (__fds[fds_idx].fd, vcom_writefds))
+ {
+ __fds[fds_idx].revents |= POLLWRNORM;
+ }
+ }
+ if (__fds[fds_idx].events & POLLWRBAND)
+ {
+ if (FD_ISSET (__fds[fds_idx].fd, vcom_writefds))
+ {
+ __fds[fds_idx].revents |= POLLWRBAND;
+ }
+ }
+#endif
+ } /* for (fds_idx = 0; fds_idx < __nfds; fds_idx++) */
+
+ /*
+ * nfd:
+ * the number of structures which have nonzero revents fields
+ * (in other words, those descriptors with events or
+ * errors reported)
+ * */
+ *nfd = 0;
+ for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
+ {
+ /* ignore negative fds */
+ if (__fds[fds_idx].fd < 0)
+ {
+ continue;
+ }
+
+ if (__fds[fds_idx].revents)
+ {
+ (*nfd)++;
+ }
+ }
+}
+
+/*
+ * PRE: parameters are validated,
+ * vcom_socket_poll is always called with __timeout set to zero
+ * hence returns immediately
+ *
+ * ACTION: handle non negative validated vcom fds and ignore rest
+ */
+
+/*
+ * implements vcom_socket_poll () interface
+ *
+ * internally uses vcom_socket_select ()
+ * to realize the behavior
+ * */
+int
+vcom_socket_poll_select_impl (struct pollfd *__fds, nfds_t __nfds,
+ int __timeout)
+{
+ int rv;
+ pid_t pid = getpid ();
+
+ nfds_t fds_idx = 0;
+ int nfd = 0;
+
+ /* vcom */
+ int vcom_nfds = 0;
+ fd_set vcom_readfds;
+ fd_set vcom_writefds;
+ fd_set vcom_exceptfds;
+ int vcom_nfd = -1;
+ /* invalid max_vcom_fd is -1 */
+ int max_vcom_fd = -1;
+
+ /* __timeout is zero to get ready events and return immediately */
+ struct timeval tv = {.tv_sec = 0,.tv_usec = 0 };
+
+ /* validate __nfds from select perspective */
+ if (__nfds < 0 || __nfds > FD_SETSIZE)
+ {
+ rv = -EINVAL;
+ goto poll_done;
+ }
+
+ /* zero vcom fd sets */
+ /*
+ * V vcom fd set
+ */
+#define _(V) \
+ FD_ZERO ((V))
+
+ _(&vcom_readfds);
+ _(&vcom_writefds);
+ _(&vcom_exceptfds);
+#undef _
+
+ vcom_nfds = 0;
+ vcom_nfd = -1;
+
+
+ for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
+ {
+ /* ignore negative fds */
+ if (__fds[fds_idx].fd < 0)
+ {
+ continue;
+ }
+
+ /* non negative validated vcom fds */
+ if (__fds[fds_idx].fd > FD_SETSIZE)
+ {
+ rv = -EINVAL;
+ goto poll_done;
+ }
+
+ /* max_vcom_fd and vcom_nfd */
+ if (__fds[fds_idx].fd > max_vcom_fd)
+ {
+ /* requested events */
+ if (__fds[fds_idx].events)
+ {
+ max_vcom_fd = __fds[fds_idx].fd;
+ }
+ }
+ ++vcom_nfd;
+ }
+
+ vcom_nfds = max_vcom_fd != -1 ? max_vcom_fd + 1 : 0;
+
+ if (!vcom_nfds)
+ {
+ rv = vcom_nfds;
+ goto poll_done;
+ }
+
+ vcom_pollfds_2_selectfds (
+ /* src */
+ __fds, __nfds,
+ /* dest */
+ vcom_nfds,
+ &vcom_readfds, &vcom_writefds, &vcom_exceptfds);
+
+ /* select on vcom fds */
+ vcom_nfd = vcom_socket_select (vcom_nfds,
+ &vcom_readfds,
+ &vcom_writefds, &vcom_exceptfds, &tv);
+ if (VCOM_DEBUG > 0)
+ fprintf (stderr,
+ "[%d] vcom_socket_select: "
+ "'%04d'='%04d'\n", pid, vcom_nfd, vcom_nfds);
+
+ if (vcom_nfd < 0)
+ {
+ rv = vcom_nfd;
+ goto poll_done;
+ }
+
+ vcom_selectfds_2_pollfds (
+ /* dest */
+ __fds, __nfds, &nfd,
+ /* src */
+ vcom_nfds,
+ &vcom_readfds, &vcom_writefds, &vcom_exceptfds);
+
+ rv = nfd;
+
+poll_done:
+ return rv;
+}
+
+/*
+ * TBD: remove this static function once vppcom
+ * has an implementation in place
+ *
+ * ACTION:
+ */
+static int
+vppcom_poll (struct pollfd *__fds, nfds_t __nfds, double time_to_wait)
+{
+ return -EOPNOTSUPP;
+}
+
+int
+vcom_socket_poll_vppcom_impl (struct pollfd *__fds, nfds_t __nfds,
+ int __timeout)
+{
+ nfds_t fds_idx = 0;
+
+ /* in seconds eg. 3.123456789 seconds */
+ double time_to_wait = (double) 0;
+
+ i32 sid;
+ i32 vep_idx;
+
+ /* replace vcom fd with session idx */
+ for (fds_idx = 0; fds_idx < __nfds; fds_idx++)
+ {
+ /* ignore negative fds */
+ if (__fds[fds_idx].fd < 0)
+ {
+ continue;
+ }
+
+ /* non negative validated vcom fds */
+ sid = vcom_socket_get_sid (__fds[fds_idx].fd);
+ if (sid != INVALID_SESSION_ID)
+ {
+ __fds[fds_idx].fd = sid;
+ }
+ else
+ {
+ /* get vep_idx */
+ vep_idx = vcom_socket_get_vep_idx (__fds[fds_idx].fd);
+ if (vep_idx != INVALID_VEP_IDX)
+ {
+ __fds[fds_idx].fd = vep_idx;
+ }
+ else
+ {
+ return -EBADF;
+ }
+ }
+ }
+
+ /* validate __timeout */
+ if (__timeout > 0)
+ {
+ time_to_wait = (double) __timeout / (double) 1000;
+ }
+ else if (__timeout == 0)
+ {
+ time_to_wait = (double) 0;
+ }
+ else if (__timeout < 0)
+ {
+ time_to_wait = ~0;
+ }
+ else
+ {
+ return -EBADF;
+ }
+
+ return vppcom_poll (__fds, __nfds, time_to_wait);
+}
+
+int
+vcom_socket_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
+{
+ /* select an implementation */
+
+ /* return vcom_socket_poll_vppcom_impl (__fds, __nfds, __timeout); */
+ return vcom_socket_poll_select_impl (__fds, __nfds, __timeout);
+}
+
+#ifdef __USE_GNU
+int
+vcom_socket_ppoll (struct pollfd *__fds, nfds_t __nfds,
+ const struct timespec *__timeout, const __sigset_t * __ss)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
int
vcom_socket_main_init (void)
{
diff --git a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h
index ef57646..9dc18f5 100644
--- a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h
+++ b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h
@@ -448,6 +448,17 @@
int __maxevents, int __timeout,
const __sigset_t * __ss);
+/*
+ * handle only vcom fds
+ */
+int vcom_socket_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
+
+#ifdef __USE_GNU
+int
+vcom_socket_ppoll (struct pollfd *__fds, nfds_t __nfds,
+ const struct timespec *__timeout, const __sigset_t * __ss);
+#endif
+
#endif /* included_vcom_socket_h */
/*
diff --git a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.c b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.c
index 087cd6b..9b961af 100644
--- a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.c
+++ b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.c
@@ -263,6 +263,15 @@
int __maxevents, int __timeout,
const __sigset_t * __ss);
+typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
+ int __timeout);
+
+#ifdef __USE_GNU
+typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
+ const struct timespec * __timeout,
+ const __sigset_t * __ss);
+#endif
+
#define SWRAP_SYMBOL_ENTRY(i) \
union { \
@@ -334,6 +343,10 @@
SWRAP_SYMBOL_ENTRY (epoll_ctl);
SWRAP_SYMBOL_ENTRY (epoll_wait);
SWRAP_SYMBOL_ENTRY (epoll_pwait);
+ SWRAP_SYMBOL_ENTRY (poll);
+#ifdef __USE_GNU
+ SWRAP_SYMBOL_ENTRY (ppoll);
+#endif
};
struct swrap
@@ -811,6 +824,25 @@
__ss);
}
+int
+libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
+{
+ swrap_bind_symbol_libc (poll);
+
+ return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
+}
+
+#ifdef __USE_GNU
+int
+libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
+ const struct timespec *__timeout, const __sigset_t * __ss)
+{
+ swrap_bind_symbol_libc (ppoll);
+
+ return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
+}
+#endif
+
static void
swrap_thread_prepare (void)
{
diff --git a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.h b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.h
index 49ee7ee..9e85ecf 100644
--- a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.h
+++ b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket_wrapper.h
@@ -63,6 +63,7 @@
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/epoll.h>
+#include <poll.h>
#include <sys/uio.h>
#include <stdlib.h>
@@ -212,6 +213,13 @@
int __maxevents, int __timeout,
const __sigset_t * __ss);
+int libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
+
+#ifdef __USE_GNU
+int libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
+ const struct timespec *__timeout, const __sigset_t * __ss);
+#endif
+
void swrap_constructor (void);
void swrap_destructor (void);