VCL-LDPRELOAD: statically link vppcom into libvcl-ldpreload.so
[vpp.git] / extras / vcl-ldpreload / src / libvcl-ldpreload / vcom.c
diff --git a/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.c b/extras/vcl-ldpreload/src/libvcl-ldpreload/vcom.c
deleted file mode 100644 (file)
index 6ddb245..0000000
+++ /dev/null
@@ -1,3331 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <unistd.h>
-#include <stdio.h>
-#include <signal.h>
-#include <dlfcn.h>
-#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>
-#include <sys/time.h>
-
-#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)                       \
-    __attribute__ ((__format__ (__printf__, a, b)))
-#else
-#define PRINTF_ATTRIBUTE(a,b)
-#endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
-
-#define HAVE_CONSTRUCTOR_ATTRIBUTE
-#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
-#define CONSTRUCTOR_ATTRIBUTE                       \
-    __attribute__ ((constructor))
-#else
-#define CONSTRUCTOR_ATTRIBUTE
-#endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
-
-#define HAVE_DESTRUCTOR_ATTRIBUTE
-#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
-#define DESTRUCTOR_ATTRIBUTE                        \
-    __attribute__ ((destructor))
-#else
-#define DESTRUCTOR_ATTRIBUTE
-#endif
-
-#define HAVE_ADDRESS_SANITIZER_ATTRIBUTE
-#ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE
-#define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE           \
-    __attribute__((no_sanitize_address))
-#else
-#define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE
-#endif
-
-#define VCOM_SOCKET_FD_MAX  0x10000
-
-static char vcom_app_name[MAX_VCOM_APP_NAME];
-
-/*
- * RETURN:  0 on success or -1 on error.
- * */
-int
-vcom_set_app_name (char *__app_name)
-{
-  return snprintf (vcom_app_name, MAX_VCOM_APP_NAME, "vcom-%s-%d",
-                  __app_name, getpid ()) < 0 ? -1 : 0;
-}
-
-static char *
-vcom_get_app_name ()
-{
-  if (vcom_app_name[0] == '\0')
-    {
-      snprintf (vcom_app_name, MAX_VCOM_APP_NAME, "vcom-app-%d", getpid ());
-    }
-  return vcom_app_name;
-}
-
-/*
- * 1 if init, 0 otherwise
- */
-static int is_vcom_init;
-
-/*
- * TBD: Make it thread safe
- */
-
-/*
- * constructor function called before main is called
- * RETURN: 0 on success -1 on failure
- * */
-static inline int
-vcom_init ()
-{
-  pid_t pid = getpid ();
-
-  if (!is_vcom_init)
-    {
-      if (vppcom_app_create (vcom_get_app_name ()) != 0)
-       {
-         printf ("\n[%d] vcom_init...failed!\n", pid);
-         if (VCOM_DEBUG > 0)
-           fprintf (stderr,
-                    "[%d] vcom_init: vppcom_app_create failed!\n", pid);
-         return -1;
-       }
-      if (vcom_socket_main_init () != 0)
-       {
-         printf ("\n[%d] vcom_init...failed!\n", pid);
-         if (VCOM_DEBUG > 0)
-           fprintf (stderr,
-                    "[%d] vcom_init: vcom_socket_main_init failed!\n", pid);
-         return -1;
-       }
-
-      is_vcom_init = 1;
-      printf ("\n[%d] vcom_init...done!\n", pid);
-    }
-  return 0;
-}
-
-static inline void
-vcom_destroy (void)
-{
-  pid_t pid = getpid ();
-
-  if (is_vcom_init)
-    {
-      vcom_socket_main_destroy ();
-      vppcom_app_destroy ();
-      is_vcom_init = 0;
-      fprintf (stderr, "\n[%d] vcom_destroy...done!\n", pid);
-    }
-}
-
-static inline int
-is_vcom_socket_fd (int fd)
-{
-  return vcom_socket_is_vcom_fd (fd);
-}
-
-static inline int
-is_vcom_epfd (int epfd)
-{
-  return vcom_socket_is_vcom_epfd (epfd);
-}
-
-
-/*
- *
- * Generic glibc fd api
- *
- */
-
-/* Close the file descriptor FD.
-
-   This function is a cancellation point and therefore
-   not marked with __THROW.  */
-/*
- * PRE:     is_vcom_socket_fd(__fd) == 1
- * RETURN:  0 on success and -1 for errors.
- * */
-int
-vcom_close (int __fd)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  if (vcom_socket_close (__fd) != 0)
-    {
-      return -1;
-    }
-
-  return 0;
-}
-
-/*
- * RETURN:  0 on success, or -1 on error
- */
-int
-close (int __fd)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd) || is_vcom_epfd (__fd))
-    {
-      if (VCOM_DEBUG > 0)
-       vcom_socket_main_show ();
-      rv = vcom_close (__fd);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr, "[%d] close: " "'%04d'='%04d'\n", pid, rv, __fd);
-      if (VCOM_DEBUG > 0)
-       vcom_socket_main_show ();
-      if (rv != 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return 0;
-    }
-  return libc_close (__fd);
-}
-
-/* Read NBYTES into BUF from FD.  Return the
-   number read, -1 for errors or 0 for EOF.
-
-   This function is a cancellation point and therefore
-   not marked with __THROW.  */
-ssize_t
-vcom_read (int __fd, void *__buf, size_t __nbytes)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_read (__fd, __buf, __nbytes);
-}
-
-ssize_t
-read (int __fd, void *__buf, size_t __nbytes)
-{
-  ssize_t size = 0;
-  pid_t pid = getpid ();
-  pthread_t tid = pthread_self ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      if (VCOM_DEBUG > 2)
-       fprintf (stderr,
-                "[%d][%lu (0x%lx)] read:1 "
-                "'%04d'='%04d', '%p', '%04d'\n",
-                pid, (unsigned long) tid, (unsigned long) tid,
-                (int) size, __fd, __buf, (int) __nbytes);
-      size = vcom_read (__fd, __buf, __nbytes);
-      if (VCOM_DEBUG > 2)
-       fprintf (stderr,
-                "[%d][%lu (0x%lx)] read:2 "
-                "'%04d'='%04d', '%p', '%04d'\n",
-                pid, (unsigned long) tid, (unsigned long) tid,
-                (int) size, __fd, __buf, (int) __nbytes);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_read (__fd, __buf, __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)
-{
-  ssize_t size = 0;
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_readv (__fd, __iov, __iovcnt);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  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
-   not marked with __THROW.  */
-ssize_t
-vcom_write (int __fd, const void *__buf, size_t __n)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_write (__fd, (void *) __buf, __n);
-}
-
-ssize_t
-write (int __fd, const void *__buf, size_t __n)
-{
-  ssize_t size = 0;
-  pid_t pid = getpid ();
-  pthread_t tid = pthread_self ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      if (VCOM_DEBUG > 2)
-       fprintf (stderr,
-                "[%d][%lu (0x%lx)] write:1 "
-                "'%04d'='%04d', '%p', '%04d'\n",
-                pid, (unsigned long) tid, (unsigned long) tid,
-                (int) size, __fd, __buf, (int) __n);
-      size = vcom_write (__fd, __buf, __n);
-      if (VCOM_DEBUG > 2)
-       fprintf (stderr,
-                "[%d][%lu (0x%lx)] write:2 "
-                "'%04d'='%04d', '%p', '%04d'\n",
-                pid, (unsigned long) tid, (unsigned long) tid,
-                (int) size, __fd, __buf, (int) __n);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_write (__fd, __buf, __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)
-{
-  ssize_t size = 0;
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_writev (__fd, __iov, __iovcnt);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  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.
-
-   This function is a cancellation point and therefore
-   not marked with __THROW.  */
-int
-vcom_fcntl_va (int __fd, int __cmd, va_list __ap)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_fcntl_va (__fd, __cmd, __ap);
-}
-
-int
-vcom_fcntl (int __fd, int __cmd, ...)
-{
-  int rv = -1;
-  va_list ap;
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      va_start (ap, __cmd);
-      rv = vcom_fcntl_va (__fd, __cmd, ap);
-      va_end (ap);
-    }
-  return rv;
-}
-
-int
-fcntl (int __fd, int __cmd, ...)
-{
-  int rv;
-  va_list ap;
-  pid_t pid = getpid ();
-
-  va_start (ap, __cmd);
-  if (is_vcom_socket_fd (__fd))
-    {
-      rv = vcom_fcntl_va (__fd, __cmd, ap);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] fcntl: "
-                "'%04d'='%04d', '%04d'\n", pid, rv, __fd, __cmd);
-      if (rv < 0)
-       {
-         errno = -rv;
-         rv = -1;
-       }
-      goto out;
-    }
-  rv = libc_vfcntl (__fd, __cmd, ap);
-
-out:
-  va_end (ap);
-  return rv;
-}
-
-int
-vcom_ioctl_va (int __fd, unsigned long int __cmd, va_list __ap)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_ioctl_va (__fd, __cmd, __ap);
-}
-
-int
-vcom_ioctl (int __fd, unsigned long int __cmd, ...)
-{
-  int rv = -1;
-  va_list ap;
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      va_start (ap, __cmd);
-      rv = vcom_ioctl_va (__fd, __cmd, ap);
-      va_end (ap);
-    }
-  return rv;
-}
-
-int
-ioctl (int __fd, unsigned long int __cmd, ...)
-{
-  int rv;
-  va_list ap;
-  pid_t pid = getpid ();
-
-  va_start (ap, __cmd);
-  if (is_vcom_socket_fd (__fd))
-    {
-      rv = vcom_ioctl_va (__fd, __cmd, ap);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] ioctl: "
-                "'%04d'='%04d', '%04ld'\n", pid, rv, __fd, __cmd);
-      if (rv < 0)
-       {
-         errno = -rv;
-         rv = -1;
-       }
-      goto out;
-    }
-  rv = libc_vioctl (__fd, __cmd, ap);
-
-out:
-  va_end (ap);
-  return rv;
-}
-
-/*
- * Check the first NFDS descriptors each in READFDS (if not NULL) for
- *  read readiness, in WRITEFDS (if not NULL) for write readiness,
- *  and in EXCEPTFDS (if not NULL) for exceptional conditions.
- *  If TIMEOUT is not NULL, time out after waiting the interval
- *  specified therein.  Returns the number of ready descriptors,
- *  or -1 for errors.
- *
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-
-/*
- * clear all vcom FDs from fd_sets __readfds, __writefds and
- * __exceptfds and update the new nfds
- *
- * new nfds is the highest-numbered file descriptor
- * in any of the three sets, plus 1
- *
- * Return the number of file descriptors contained in the
- * three descriptor sets. ie. the total number of the bits
- * that are set in  __readfds, __writefds and __exceptfds
- */
-static inline int
-vcom_fd_clear (int __nfds,
-              int *__new_nfds,
-              fd_set * __restrict __readfds,
-              fd_set * __restrict __writefds,
-              fd_set * __restrict __exceptfds)
-{
-  int fd;
-  /* invalid max_fd is -1 */
-  int max_fd = -1;
-  int nfd = 0;
-
-
-  /* clear all vcom fd from the sets */
-  for (fd = 0; fd < __nfds; fd++)
-    {
-
-      /* clear vcom fd from set */
-      /*
-       * F fd set
-       */
-#define _(F)                                    \
-      if ((F) && FD_ISSET (fd, (F)))            \
-        {                                       \
-          if (is_vcom_socket_fd (fd))           \
-            {                                   \
-              FD_CLR (fd, (F));                 \
-            }                                   \
-        }
-
-
-      _(__readfds);
-      _(__writefds);
-      _(__exceptfds);
-#undef _
-    }
-
-  /*
-   *  compute nfd and __new_nfds
-   */
-  for (fd = 0; fd < __nfds; fd++)
-    {
-
-      /*
-       * F fd set
-       */
-#define _(F)                                    \
-      if ((F) && FD_ISSET (fd, (F)))            \
-        {                                       \
-          if (fd > max_fd)                      \
-            {                                   \
-              max_fd = fd;                      \
-            }                                   \
-          ++nfd;                                \
-        }
-
-
-      _(__readfds);
-      _(__writefds);
-      _(__exceptfds);
-#undef _
-    }
-
-  *__new_nfds = max_fd != -1 ? max_fd + 1 : 0;
-  return nfd;
-}
-
-/*
- * Return the number of file descriptors contained in the
- * three descriptor sets. ie. the total number of the bits
- * that are set in  __readfds, __writefds and __exceptfds
- */
-static inline int
-vcom_fd_set (int __nfds,
-            /* dest */
-            int *__new_nfds,
-            fd_set * __restrict __readfds,
-            fd_set * __restrict __writefds, fd_set * __restrict __exceptfds,
-            /* src */
-            fd_set * __restrict __saved_readfds,
-            fd_set * __restrict __saved_writefds,
-            fd_set * __restrict __saved_exceptfds)
-{
-  int fd;
-  /* invalid max_fd is -1 */
-  int max_fd = -1;
-  int nfd = 0;
-
-  for (fd = 0; fd < __nfds; fd++)
-    {
-      /*
-       * F fd set
-       * S saved fd set
-       */
-#define _(S,F)                                  \
-      if ((F) && (S) && FD_ISSET (fd, (S)))     \
-        {                                       \
-          if (is_vcom_socket_fd (fd))           \
-            {                                   \
-              FD_SET (fd, (F));                 \
-            }                                   \
-        }
-
-
-      _(__saved_readfds, __readfds);
-      _(__saved_writefds, __writefds);
-#undef _
-    }
-
-
-  /*
-   *  compute nfd and __new_nfds
-   */
-  for (fd = 0; fd < __nfds; fd++)
-    {
-
-      /*
-       * F fd set
-       */
-#define _(F)                                    \
-      if ((F) && FD_ISSET (fd, (F)))            \
-        {                                       \
-          if (fd > max_fd)                      \
-            {                                   \
-              max_fd = fd;                      \
-            }                                   \
-          ++nfd;                                \
-        }
-
-
-      _(__readfds);
-      _(__writefds);
-      _(__exceptfds);
-#undef _
-    }
-
-  *__new_nfds = max_fd != -1 ? max_fd + 1 : 0;
-  return nfd;
-}
-
-/*
- * split select sets(src) into
- * vcom sets(dest1) and libc sets(dest2)
- */
-static inline void
-vcom_fd_set_split (
-                   /* src, select sets */
-                   int nfds,
-                   fd_set * __restrict readfds,
-                   fd_set * __restrict writefds,
-                   fd_set * __restrict exceptfds,
-                   /* dest1, vcom sets */
-                   int *vcom_nfds,
-                   fd_set * __restrict vcom_readfds,
-                   fd_set * __restrict vcom_writefds,
-                   fd_set * __restrict vcom_exceptfds, int *vcom_nfd,
-                   /* dest2, libc sets */
-                   int *libc_nfds,
-                   fd_set * __restrict libc_readfds,
-                   fd_set * __restrict libc_writefds,
-                   fd_set * __restrict libc_exceptfds, int *libc_nfd)
-{
-  int fd;
-
-  /* vcom */
-  /* invalid max_fd is -1 */
-  int vcom_max_fd = -1;
-  int vcom_nfd2 = 0;
-
-  /* libc */
-  /* invalid max_fd is -1 */
-  int libc_max_fd = -1;
-  int libc_nfd2 = 0;
-
-
-  for (fd = 0; fd < nfds; fd++)
-    {
-      /*
-       * S select fd set
-       * V vcom fd set
-       * L libc fd set
-       */
-#define _(S,V,L)                            \
-      if ((S) && FD_ISSET (fd, (S)))        \
-        {                                   \
-          if (is_vcom_socket_fd (fd))       \
-            {                               \
-              if ((V))                      \
-                {                           \
-                  FD_SET(fd, (V));          \
-                  if (fd > vcom_max_fd)     \
-                    {                       \
-                      vcom_max_fd = fd;     \
-                    }                       \
-                  ++vcom_nfd2;              \
-                }                           \
-            }                               \
-          else                              \
-            {                               \
-              if ((L))                      \
-                {                           \
-                  FD_SET(fd, (L));          \
-                  if (fd > libc_max_fd)     \
-                    {                       \
-                      libc_max_fd = fd;     \
-                    }                       \
-                  ++libc_nfd2;              \
-                }                           \
-            }                               \
-        }
-
-
-      _(readfds, vcom_readfds, libc_readfds);
-      _(writefds, vcom_writefds, libc_writefds);
-      _(exceptfds, vcom_exceptfds, libc_exceptfds);
-#undef _
-    }
-
-  if (vcom_nfds)
-    *vcom_nfds = vcom_max_fd != -1 ? vcom_max_fd + 1 : 0;
-  if (vcom_nfd)
-    *vcom_nfd = vcom_nfd2;
-  if (libc_nfds)
-    *libc_nfds = libc_max_fd != -1 ? libc_max_fd + 1 : 0;
-  if (libc_nfd)
-    *libc_nfd = libc_nfd2;
-}
-
-/*
- * merge vcom sets(src1) and libc sets(src2)
- * into select sets(dest)
- */
-static inline void
-vcom_fd_set_merge (
-                   /* dest, select sets */
-                   int *nfds,
-                   fd_set * __restrict readfds,
-                   fd_set * __restrict writefds,
-                   fd_set * __restrict exceptfds, int *nfd,
-                   /* src1, vcom sets */
-                   int vcom_nfds,
-                   fd_set * __restrict vcom_readfds,
-                   fd_set * __restrict vcom_writefds,
-                   fd_set * __restrict vcom_exceptfds, int vcom_nfd,
-                   /* src2, libc sets */
-                   int libc_nfds,
-                   fd_set * __restrict libc_readfds,
-                   fd_set * __restrict libc_writefds,
-                   fd_set * __restrict libc_exceptfds, int libc_nfd)
-{
-  int fd;
-  /* invalid max_fd is -1 */
-  int max_fd = -1;
-  int nfd2 = 0;
-
-
-  /* FD_BIT_OR
-   *
-   * dest |= src at current bit index
-   * update MAX and NFD of dest fd set
-   *
-   *
-   * FS source fd set
-   * FD dest fd set
-   * BI bit index
-   * MAX current max_fd of dest fd sets
-   * NFD current nfd of dest fd sets
-   * N  nfds of source fd set
-   */
-#define FD_BIT_OR(FD,FS,BI,          \
-                  MAX,NFD)           \
-  if ((FS) && (FD) && FD_ISSET ((BI), (FS)))    \
-    {                                           \
-      FD_SET ((BI), (FD));                      \
-      if ((BI) > (MAX))                         \
-        {                                       \
-          (MAX) = (BI);                         \
-        }                                       \
-      ++(NFD);                                  \
-    }
-
-
-  /* FD_RWE_SET_OR */
-  /*
-   * SR,SW,SE source RWE fd sets
-   * DR,DW,DE dest RWE fd sets
-   * BI bit index
-   * NFDS  nfds of source fd sets
-   * MAX current max_fd of dest fd sets
-   * NFD current nfd of dest fd sets
-   */
-#define FD_RWE_SETS_OR(DR,DW,DE,      \
-                      SR,SW,SE,       \
-                      BI,NFDS,        \
-                      MAX,NFD)        \
-  do                                                      \
-    {                                                     \
-      for ((BI) = 0; (BI) < (NFDS); (BI)++)               \
-        {                                                 \
-          FD_BIT_OR((DR), (SR), (BI), (MAX), (NFD));      \
-          FD_BIT_OR((DW), (SW), (BI), (MAX), (NFD));      \
-          FD_BIT_OR((DE), (SE), (BI), (MAX), (NFD));      \
-        }                                                 \
-      }                                                   \
-    while (0);
-
-
-  /* source(vcom) to dest(select) rwe fd sets */
-  FD_RWE_SETS_OR (readfds, writefds, exceptfds,
-                 vcom_readfds, vcom_writefds, vcom_exceptfds,
-                 fd, vcom_nfds, max_fd, nfd2);
-
-  /* source(libc) to dest(select) rwe fd sets */
-  FD_RWE_SETS_OR (readfds, writefds, exceptfds,
-                 libc_readfds, libc_writefds, libc_exceptfds,
-                 fd, libc_nfds, max_fd, nfd2);
-
-#undef FD_RWE_SETS_OR
-#undef FD_BIT_OR
-
-  if (nfds)
-    *nfds = max_fd != -1 ? max_fd + 1 : 0;
-  if (nfd)
-    *nfd = nfd2;
-}
-
-/*
- * RETURN 1 if fds is NULL or empty. 0 otherwise
- */
-static inline int
-fd_set_iszero (fd_set * __restrict fds)
-{
-  int fd;
-
-  /* NULL fds */
-  if (!fds)
-    return 1;
-
-  for (fd = 0; fd < FD_SETSIZE; fd++)
-    {
-      if (FD_ISSET (fd, fds))
-       {
-         /* non-empty fds */
-         return 0;
-       }
-    }
-  /* empty fds */
-  return 1;
-}
-
-
-/*
- * ################
- * kernel time64.h
- * ################
- * */
-typedef long int s64;
-typedef unsigned long int u64;
-
-typedef long long int __s64;
-typedef unsigned long long int __u64;
-
-typedef __s64 time64_t;
-typedef __u64 timeu64_t;
-
-/* Parameters used to convert the timespec values: */
-#define MSEC_PER_SEC    1000L
-#define USEC_PER_MSEC   1000L
-#define NSEC_PER_USEC   1000L
-#define NSEC_PER_MSEC   1000000L
-#define USEC_PER_SEC    1000000L
-#define NSEC_PER_SEC    1000000000L
-#define FSEC_PER_SEC    1000000000000000LL
-
-
-/*
- * ################
- * kernel time.h
- * ################
- * */
-
-
-#define TIME_T_MAX      (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
-
-static inline int
-timespec_equal (const struct timespec *a, const struct timespec *b)
-{
-  return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
-}
-
-/*
- * lhs < rhs:  return <0
- * lhs == rhs: return 0
- * lhs > rhs:  return >0
- */
-static inline int
-timespec_compare (const struct timespec *lhs, const struct timespec *rhs)
-{
-  if (lhs->tv_sec < rhs->tv_sec)
-    return -1;
-  if (lhs->tv_sec > rhs->tv_sec)
-    return 1;
-  return lhs->tv_nsec - rhs->tv_nsec;
-}
-
-static inline int
-timeval_compare (const struct timeval *lhs, const struct timeval *rhs)
-{
-  if (lhs->tv_sec < rhs->tv_sec)
-    return -1;
-  if (lhs->tv_sec > rhs->tv_sec)
-    return 1;
-  return lhs->tv_usec - rhs->tv_usec;
-}
-
-extern void set_normalized_timespec (struct timespec *ts, time_t sec,
-                                    s64 nsec);
-
-
-static inline struct timespec
-timespec_add (struct timespec lhs, struct timespec rhs)
-{
-  struct timespec ts_delta;
-  set_normalized_timespec (&ts_delta, lhs.tv_sec + rhs.tv_sec,
-                          lhs.tv_nsec + rhs.tv_nsec);
-  return ts_delta;
-}
-
-/*
- * sub = lhs - rhs, in normalized form
- */
-static inline struct timespec
-timespec_sub (struct timespec lhs, struct timespec rhs)
-{
-  struct timespec ts_delta;
-  set_normalized_timespec (&ts_delta, lhs.tv_sec - rhs.tv_sec,
-                          lhs.tv_nsec - rhs.tv_nsec);
-  return ts_delta;
-}
-
-/*
- * ################
- * kernel time.c
- * ################
- * */
-
-
-/**
- * set_normalized_timespec - set timespec sec and nsec parts and normalize
- *
- * @ts:         pointer to timespec variable to be set
- * @sec:        seconds to set
- * @nsec:       nanoseconds to set
- *
- * Set seconds and nanoseconds field of a timespec variable and
- * normalize to the timespec storage format
- *
- * Note: The tv_nsec part is always in the range of
- *      0 <= tv_nsec < NSEC_PER_SEC
- * For negative values only the tv_sec field is negative !
- */
-void
-set_normalized_timespec (struct timespec *ts, time_t sec, s64 nsec)
-{
-  while (nsec >= NSEC_PER_SEC)
-    {
-      /*
-       * The following asm() prevents the compiler from
-       * optimising this loop into a modulo operation. See
-       * also __iter_div_u64_rem() in include/linux/time.h
-       */
-    asm ("":"+rm" (nsec));
-      nsec -= NSEC_PER_SEC;
-      ++sec;
-    }
-  while (nsec < 0)
-    {
-    asm ("":"+rm" (nsec));
-      nsec += NSEC_PER_SEC;
-      --sec;
-    }
-  ts->tv_sec = sec;
-  ts->tv_nsec = nsec;
-}
-
-#define vcom_timerisvalid(tvp)        (!((tvp)->tv_sec < 0 || (tvp)->tv_usec < 0))
-
-/* Macros for converting between `struct timeval' and `struct timespec'.  */
-#define VCOM_TIMEVAL_TO_TIMESPEC(tv, ts) {                             \
-        (ts)->tv_sec = (tv)->tv_sec;                                    \
-        (ts)->tv_nsec = (tv)->tv_usec * 1000;                           \
-}
-#define VCOM_TIMESPEC_TO_TIMEVAL(tv, ts) {                             \
-        (tv)->tv_sec = (ts)->tv_sec;                                    \
-        (tv)->tv_usec = (ts)->tv_nsec / 1000;                           \
-}
-
-static inline int
-vcom_select_impl (int vcom_nfds, fd_set * __restrict vcom_readfds,
-                 fd_set * __restrict vcom_writefds,
-                 fd_set * __restrict vcom_exceptfds,
-                 struct timeval *__restrict timeout)
-{
-  return vcom_socket_select (vcom_nfds, vcom_readfds,
-                            vcom_writefds, vcom_exceptfds, timeout);
-}
-
-int
-vcom_select (int __nfds, fd_set * __restrict __readfds,
-            fd_set * __restrict __writefds,
-            fd_set * __restrict __exceptfds,
-            struct timeval *__restrict __timeout)
-{
-  int rv;
-  int rv2 = 0;
-  pid_t pid = getpid ();
-
-  int timedout = 0;
-  /* block indefinitely */
-  int no_timeout = 0;
-  int first_clock_gettime_failed = 0;
-  /* timeout value in units of timespec */
-  struct timespec timeout_ts;
-  struct timespec start_time, now, end_time;
-
-  /* select sets attributes - after merge */
-  int new_nfds = 0;
-  int new_nfd = -1;
-
-  /* vcom */
-  int vcom_nfds = 0;
-  fd_set vcom_readfds;
-  fd_set vcom_writefds;
-  fd_set vcom_exceptfds;
-  int vcom_nfd = -1;
-
-  /* libc */
-  int libc_nfds = 0;
-  fd_set libc_readfds;
-  fd_set libc_writefds;
-  fd_set libc_exceptfds;
-  int libc_nfd = -1;
-
-  /* for polling */
-  struct timeval tv = {.tv_sec = 0,.tv_usec = 0 };
-
-  /* validate __timeout */
-  if (__timeout)
-    {
-      /* validate tv_sec */
-      /* bogus */
-      if (!vcom_timerisvalid (__timeout))
-       {
-         rv = -EINVAL;
-         goto select_done;
-       }
-
-      /* validate tv_usec */
-      /* TBD: */
-      /* init timeout_ts */
-      VCOM_TIMEVAL_TO_TIMESPEC (__timeout, &timeout_ts);
-      set_normalized_timespec (&timeout_ts,
-                              timeout_ts.tv_sec, timeout_ts.tv_nsec);
-    }
-
-  rv = clock_gettime (CLOCK_MONOTONIC, &start_time);
-  if (rv == -1)
-    {
-      rv = -errno;
-      first_clock_gettime_failed = 1;
-      goto select_done;
-    }
-
-  /* init end_time */
-  if (__timeout)
-    {
-      if (timerisset (__timeout))
-       {
-         end_time = timespec_add (start_time, timeout_ts);
-       }
-      else
-       {
-         /*
-          * if both fields of the timeout structure are zero,
-          * then select returns immediately
-          * */
-         end_time = start_time;
-       }
-    }
-  else
-    {
-      /* block indefinitely */
-      no_timeout = 1;
-    }
-
-
-
-  if (vcom_init () != 0)
-    {
-      rv = -1;
-      goto select_done;
-    }
-
-  /* validate __nfds */
-  if (__nfds < 0 || __nfds > FD_SETSIZE)
-    {
-      rv = -EINVAL;
-      goto select_done;
-    }
-
-
-  /*
-   * usleep(3) emulation
-   * */
-
-  /* call libc_select() with a finite timeout and
-   * no file descriptors or empty fd sets and
-   * zero nfds */
-  if (__nfds == 0 &&
-      (!__readfds || fd_set_iszero (__readfds)) &&
-      (!__writefds || fd_set_iszero (__writefds)) &&
-      (!__exceptfds || fd_set_iszero (__exceptfds)))
-    {
-      if (__timeout)
-       {
-         rv = libc_select (__nfds,
-                           __readfds, __writefds, __exceptfds, __timeout);
-         if (rv == -1)
-           rv = -errno;
-       }
-      else
-       {
-         /* TBD: block indefinitely or return -EINVAL */
-         rv = -EINVAL;
-       }
-      goto select_done;
-    }
-
-  /* init once before the polling loop */
-
-  /* zero vcom and libc fd sets */
-  /*
-   * S select fd set
-   * V vcom fd set
-   * L libc fd set
-   */
-#define _(S,V,L)      \
-  if ((S))            \
-    {                 \
-      FD_ZERO ((V));  \
-      FD_ZERO ((L));  \
-    }
-
-
-  _(__readfds, &vcom_readfds, &libc_readfds);
-  _(__writefds, &vcom_writefds, &libc_writefds);
-  _(__exceptfds, &vcom_exceptfds, &libc_exceptfds);
-#undef _
-  new_nfds = 0;
-  new_nfd = -1;
-
-  vcom_nfds = 0;
-  vcom_nfd = -1;
-  libc_nfds = 0;
-  libc_nfd = -1;
-
-  vcom_fd_set_split (
-                     /* src, select sets */
-                     __nfds, __readfds, __writefds, __exceptfds,
-                     /* dest1, vcom sets */
-                     __readfds || __writefds || __exceptfds ?
-                     &vcom_nfds : NULL,
-                     __readfds ? &vcom_readfds : NULL,
-                     __writefds ? &vcom_writefds : NULL,
-                     __exceptfds ? &vcom_exceptfds : NULL,
-                     __readfds || __writefds || __exceptfds ?
-                     &vcom_nfd : NULL,
-                     /* dest2, libc sets */
-                     __readfds || __writefds || __exceptfds ?
-                     &libc_nfds : NULL,
-                     __readfds ? &libc_readfds : NULL,
-                     __writefds ? &libc_writefds : NULL,
-                     __exceptfds ? &libc_exceptfds : NULL,
-                     __readfds || __writefds || __exceptfds ?
-                     &libc_nfd : NULL);
-
-  /*
-   * polling loop
-   * */
-  do
-    {
-      new_nfd = -1;
-      vcom_nfd = -1;
-      libc_nfd = -1;
-
-      /*
-       * if both fields of timeval structure are zero,
-       * vcom_select_impl and libc_select returns immediately.
-       * useful for polling and ensure fairness among
-       * file descriptors watched.
-       */
-
-      /* for polling */
-      tv.tv_sec = 0;
-      tv.tv_usec = 0;
-
-      /* select on vcom fds */
-      if (vcom_nfds)
-       {
-         vcom_nfd = vcom_select_impl (vcom_nfds,
-                                      __readfds ? &vcom_readfds : NULL,
-                                      __writefds ? &vcom_writefds : NULL,
-                                      __exceptfds ? &vcom_exceptfds : NULL,
-                                      &tv);
-         if (VCOM_DEBUG > 2)
-           fprintf (stderr,
-                    "[%d] select vcom: "
-                    "'%04d'='%04d'\n", pid, vcom_nfd, vcom_nfds);
-
-         if (vcom_nfd < 0)
-           {
-             rv = vcom_nfd;
-             goto select_done;
-           }
-       }
-      /* select on libc fds */
-      if (libc_nfds)
-       {
-         libc_nfd = libc_select (libc_nfds,
-                                 __readfds ? &libc_readfds : NULL,
-                                 __writefds ? &libc_writefds : NULL,
-                                 __exceptfds ? &libc_exceptfds : NULL, &tv);
-         if (VCOM_DEBUG > 2)
-           fprintf (stderr,
-                    "[%d] select libc: "
-                    "'%04d'='%04d'\n", pid, libc_nfd, libc_nfds);
-
-         if (libc_nfd < 0)
-           {
-             /* tv becomes undefined */
-             libc_nfd = errno;
-             rv = libc_nfd;
-             goto select_done;
-           }
-       }
-
-      /* check if any file descriptors changed status */
-      if ((vcom_nfds && vcom_nfd > 0) || (libc_nfds && libc_nfd > 0))
-       {
-         /* zero the sets before merge and exit */
-
-         /*
-          * F fd set
-          */
-#define _(F)                  \
-          if ((F))            \
-            {                 \
-              FD_ZERO ((F));  \
-            }
-
-
-         _(__readfds);
-         _(__writefds);
-         _(__exceptfds);
-#undef _
-         new_nfds = 0;
-         new_nfd = -1;
-
-         /*
-          * on exit, sets are modified in place to indicate which
-          * file descriptors actually changed status
-          * */
-         vcom_fd_set_merge (
-                             /* dest, select sets */
-                             __readfds || __writefds || __exceptfds ?
-                             &new_nfds : NULL,
-                             __readfds,
-                             __writefds,
-                             __exceptfds,
-                             __readfds || __writefds || __exceptfds ?
-                             &new_nfd : NULL,
-                             /* src1, vcom sets */
-                             vcom_nfds,
-                             __readfds ? &vcom_readfds : NULL,
-                             __writefds ? &vcom_writefds : NULL,
-                             __exceptfds ? &vcom_exceptfds : NULL, vcom_nfd,
-                             /* src2, libc sets */
-                             libc_nfds,
-                             __readfds ? &libc_readfds : NULL,
-                             __writefds ? &libc_writefds : NULL,
-                             __exceptfds ? &libc_exceptfds : NULL, libc_nfd);
-         /*
-          * return the number of file descriptors contained in the
-          * three returned sets
-          * */
-         rv = 0;
-         /*
-          * for documentation
-          *
-          * if(vcom_nfd > 0)
-          *   rv += vcom_nfd;
-          * if(libc_nfd > 0)
-          *   rv += libc_nfd;
-          */
-
-         rv = new_nfd == -1 ? 0 : new_nfd;
-         goto select_done;
-       }
-
-      rv = clock_gettime (CLOCK_MONOTONIC, &now);
-      if (rv == -1)
-       {
-         rv = -errno;
-         goto select_done;
-       }
-    }
-  while (no_timeout || timespec_compare (&now, &end_time) < 0);
-
-  /* timeout expired before anything interesting happened */
-  timedout = 1;
-  rv = 0;
-
-select_done:
-  if (VCOM_DEBUG > 2)
-    fprintf (stderr, "[%d] vselect1: " "'%04d'='%04d'\n", pid, rv, __nfds);
-  /*
-   * modify timeout parameter to reflect the amount of time not slept
-   * */
-  if (__timeout)
-    {
-      if (vcom_timerisvalid (__timeout))
-       {
-         /* timeout expired */
-         if (timedout)
-           {
-             timerclear (__timeout);
-           }
-         else if (!first_clock_gettime_failed)
-           {
-             rv2 = clock_gettime (CLOCK_MONOTONIC, &now);
-             if (rv2 == -1)
-               {
-                 rv = -errno;
-               }
-             else
-               {
-                 struct timespec ts_delta;
-                 ts_delta = timespec_sub (end_time, now);
-                 VCOM_TIMESPEC_TO_TIMEVAL (__timeout, &ts_delta);
-               }
-           }
-       }
-    }
-  if (VCOM_DEBUG > 2)
-    fprintf (stderr, "[%d] vselect2: " "'%04d',='%04d'\n", pid, rv, __nfds);
-
-  return rv;
-}
-
-int
-vcom_select_internal (int __nfds, fd_set * __restrict __readfds,
-                     fd_set * __restrict __writefds,
-                     fd_set * __restrict __exceptfds,
-                     struct timeval *__restrict __timeout)
-{
-  int rv;
-  int new_nfds = 0;
-  int nfd = 0;
-  pid_t pid = getpid ();
-
-  fd_set saved_readfds;
-  fd_set saved_writefds;
-  fd_set saved_exceptfds;
-
-  /* validate __nfds */
-  if (__nfds < 0)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-  /* validate __timeout */
-  if (__timeout)
-    {
-      /* validate tv_sec */
-      /* bogus */
-      if (__timeout->tv_sec < 0 || __timeout->tv_usec < 0)
-       {
-         errno = EINVAL;
-         return -1;
-       }
-
-      /* validate tv_usec */
-      /* TBD: */
-    }
-
-  /* init saved_x fds */
-  if (__readfds)
-    {
-      saved_readfds = *__readfds;
-      /*
-         memcpy (&saved_readfds, __readfds, sizeof (*__readfds));
-       */
-    }
-  else
-    {
-      FD_ZERO (&saved_readfds);
-    }
-
-  if (__writefds)
-    {
-      saved_writefds = *__writefds;
-      /*
-         memcpy (&saved_writefds, __writefds, sizeof (*__writefds));
-       */
-
-    }
-  else
-    {
-      FD_ZERO (&saved_writefds);
-    }
-
-  if (__exceptfds)
-    {
-      saved_exceptfds = *__exceptfds;
-      /*
-         memcpy (&saved_exceptfds, __exceptfds, sizeof (*__exceptfds));
-       */
-
-    }
-  else
-    {
-      FD_ZERO (&saved_exceptfds);
-    }
-
-  /* clear vcom fds */
-  nfd = vcom_fd_clear (__nfds, &new_nfds, __readfds, __writefds, __exceptfds);
-
-  /* set to an invalid value */
-  rv = -2;
-  /* have kernel fds */
-  if (new_nfds)
-    rv = libc_select (new_nfds, __readfds,
-                     __writefds, __exceptfds, __timeout);
-
-  if (new_nfds && rv == -1)
-    {
-      /* on error, the file descriptor sets are unmodified */
-      if (__readfds)
-       *__readfds = saved_readfds;
-      if (__writefds)
-       *__writefds = saved_writefds;
-      if (__exceptfds)
-       *__exceptfds = saved_exceptfds;
-      return rv;
-    }
-  else if ((new_nfds && rv != -1) || (rv == -2))
-    {
-      /* restore vcom fds */
-      nfd = vcom_fd_set (__nfds,
-                        &new_nfds,
-                        __readfds,
-                        __writefds,
-                        __exceptfds,
-                        &saved_readfds, &saved_writefds, &saved_exceptfds);
-      rv = nfd;
-    }
-
-  if (VCOM_DEBUG > 0)
-    fprintf (stderr, "[%d] select: " "'%04d'='%04d'\n", pid, rv, __nfds);
-  return rv;
-}
-
-int
-select (int __nfds, fd_set * __restrict __readfds,
-       fd_set * __restrict __writefds,
-       fd_set * __restrict __exceptfds, struct timeval *__restrict __timeout)
-{
-  int rv = 0;
-  pid_t pid = getpid ();
-
-  if (VCOM_DEBUG > 2)
-    fprintf (stderr, "[%d] select1: " "'%04d'='%04d'\n", pid, rv, __nfds);
-  rv = vcom_select (__nfds, __readfds, __writefds, __exceptfds, __timeout);
-  if (VCOM_DEBUG > 2)
-    fprintf (stderr, "[%d] select2: " "'%04d'='%04d'\n", pid, rv, __nfds);
-  if (rv < 0)
-    {
-      errno = -rv;
-      return -1;
-    }
-  return rv;
-}
-
-#ifdef __USE_XOPEN2K
-/*
- * Same as above only that the TIMEOUT value is given with higher
- * resolution and a sigmask which is been set temporarily.  This
- * version should be used.
- *
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-int
-vcom_pselect (int __nfds, fd_set * __restrict __readfds,
-             fd_set * __restrict __writefds,
-             fd_set * __restrict __exceptfds,
-             const struct timespec *__restrict __timeout,
-             const __sigset_t * __restrict __sigmask)
-{
-  int fd;
-  int vcom_nfds = 0;
-
-  for (fd = 0; fd < __nfds; fd++)
-    {
-      if (__readfds && FD_ISSET (fd, __readfds))
-       {
-         if (is_vcom_socket_fd (fd))
-           {
-             vcom_nfds++;
-           }
-       }
-
-      if (__writefds && FD_ISSET (fd, __writefds))
-       {
-         if (is_vcom_socket_fd (fd))
-           {
-             vcom_nfds++;
-           }
-       }
-      if (__exceptfds && FD_ISSET (fd, __exceptfds))
-       {
-         if (is_vcom_socket_fd (fd))
-           {
-             FD_CLR (fd, __exceptfds);
-           }
-       }
-    }
-  return vcom_nfds;
-}
-
-int
-pselect (int __nfds, fd_set * __restrict __readfds,
-        fd_set * __restrict __writefds,
-        fd_set * __restrict __exceptfds,
-        const struct timespec *__restrict __timeout,
-        const __sigset_t * __restrict __sigmask)
-{
-  int rv;
-  int new_nfds = 0;
-  int nfd = 0;
-  pid_t pid = getpid ();
-
-  fd_set saved_readfds;
-  fd_set saved_writefds;
-  fd_set saved_exceptfds;
-
-  /* validate __nfds */
-  if (__nfds < 0)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-  /* validate __timeout */
-  if (__timeout)
-    {
-      /* validate tv_sec */
-      /* bogus */
-      if (__timeout->tv_sec < 0 || __timeout->tv_nsec < 0)
-       {
-         errno = EINVAL;
-         return -1;
-       }
-
-      /* validate tv_usec */
-      /* TBD: */
-    }
-
-  /* init saved fds */
-  if (__readfds)
-    {
-      saved_readfds = *__readfds;
-      /*
-         memcpy (&saved_readfds, __readfds, sizeof (*__readfds));
-       */
-    }
-  else
-    {
-      FD_ZERO (&saved_readfds);
-    }
-
-  if (__writefds)
-    {
-      saved_writefds = *__writefds;
-      /*
-         memcpy (&saved_writefds, __writefds, sizeof (*__writefds));
-       */
-
-    }
-  else
-    {
-      FD_ZERO (&saved_writefds);
-    }
-
-  if (__exceptfds)
-    {
-      saved_exceptfds = *__exceptfds;
-      /*
-         memcpy (&saved_exceptfds, __exceptfds, sizeof (*__exceptfds));
-       */
-
-    }
-  else
-    {
-      FD_ZERO (&saved_exceptfds);
-    }
-
-  /* clear vcom fds */
-  nfd = vcom_fd_clear (__nfds, &new_nfds, __readfds, __writefds, __exceptfds);
-
-  /* set to an invalid value */
-  rv = -2;
-  if (new_nfds)
-    rv = libc_pselect (new_nfds,
-                      __readfds,
-                      __writefds, __exceptfds, __timeout, __sigmask);
-
-  if (new_nfds && rv == -1)
-    {
-      /* on error, the file descriptor sets are unmodified */
-      if (__readfds)
-       *__readfds = saved_readfds;
-      if (__writefds)
-       *__writefds = saved_writefds;
-      if (__exceptfds)
-       *__exceptfds = saved_exceptfds;
-      return rv;
-    }
-  else if ((new_nfds && rv != -1) || (rv == -2))
-    {
-      /* restore vcom fds */
-      nfd = vcom_fd_set (__nfds,
-                        &new_nfds,
-                        __readfds,
-                        __writefds,
-                        __exceptfds,
-                        &saved_readfds, &saved_writefds, &saved_exceptfds);
-      rv = nfd;
-    }
-
-  if (VCOM_DEBUG > 2)
-    fprintf (stderr, "[%d] pselect: " "'%04d'='%04d'\n", pid, rv, __nfds);
-  return rv;
-}
-#endif
-
-/*
- *
- * Socket specific glibc api
- *
- */
-
-/* Create a new socket of type TYPE in domain DOMAIN, using
- * protocol PROTOCOL.  If PROTOCOL is zero, one is chosen
- * automatically. Returns a file descriptor for the new socket,
- * or -1 for errors.
- * RETURN:  a valid file descriptor for the new socket,
- * or -1 for errors.
- * */
-
-int
-vcom_socket (int __domain, int __type, int __protocol)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_socket (__domain, __type, __protocol);
-}
-
-int
-socket (int __domain, int __type, int __protocol)
-{
-  int rv;
-  pid_t pid = getpid ();
-  pthread_t tid = pthread_self ();
-
-  /* handle domains implemented by vpp */
-  switch (__domain)
-    {
-    case AF_INET:
-    case AF_INET6:
-      /* handle types implemented by vpp */
-      switch (__type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
-       {
-       case SOCK_STREAM:
-       case SOCK_DGRAM:
-         if (VCOM_DEBUG > 0)
-           vcom_socket_main_show ();
-         rv = vcom_socket (__domain, __type, __protocol);
-         if (VCOM_DEBUG > 0)
-           fprintf (stderr,
-                    "[%d][%lu (0x%lx)] socket: "
-                    "'%04d'= D='%04d', T='%04d', P='%04d'\n",
-                    pid, (unsigned long) tid, (unsigned long) tid,
-                    rv, __domain, __type, __protocol);
-         if (VCOM_DEBUG > 0)
-           vcom_socket_main_show ();
-         if (rv < 0)
-           {
-             errno = -rv;
-             return -1;
-           }
-         return rv;
-         break;
-
-       default:
-         goto CALL_GLIBC_SOCKET_API;
-         break;
-       }
-
-      break;
-
-    default:
-      goto CALL_GLIBC_SOCKET_API;
-      break;
-    }
-
-CALL_GLIBC_SOCKET_API:
-  return libc_socket (__domain, __type, __protocol);
-}
-
-/*
- * Create two new sockets, of type TYPE in domain DOMAIN and using
- * protocol PROTOCOL, which are connected to each other, and put file
- * descriptors for them in FDS[0] and FDS[1].  If PROTOCOL is zero,
- * one will be chosen automatically.
- * Returns 0 on success, -1 for errors.
- * */
-int
-vcom_socketpair (int __domain, int __type, int __protocol, int __fds[2])
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_socketpair (__domain, __type, __protocol, __fds);
-}
-
-int
-socketpair (int __domain, int __type, int __protocol, int __fds[2])
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  /* handle domains implemented by vpp */
-  switch (__domain)
-    {
-    case AF_INET:
-    case AF_INET6:
-      /* handle types implemented by vpp */
-      switch (__type)
-       {
-       case SOCK_STREAM:
-       case SOCK_DGRAM:
-         rv = vcom_socketpair (__domain, __type, __protocol, __fds);
-         if (VCOM_DEBUG > 0)
-           fprintf (stderr,
-                    "[%d] socketpair: "
-                    "'%04d'= D='%04d', T='%04d', P='%04d'\n",
-                    pid, rv, __domain, __type, __protocol);
-         if (rv < 0)
-           {
-             errno = -rv;
-             return -1;
-           }
-         return 0;
-         break;
-
-       default:
-         goto CALL_GLIBC_SOCKET_API;
-         break;
-       }
-
-      break;
-
-    default:
-      goto CALL_GLIBC_SOCKET_API;
-      break;
-    }
-
-CALL_GLIBC_SOCKET_API:
-  return libc_socketpair (__domain, __type, __protocol, __fds);
-}
-
-/*
- * Give the socket FD the local address ADDR
- * (which is LEN bytes long).
- * */
-int
-vcom_bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
-{
-  int rv;
-
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  /* validate __len */
-  switch (__addr->sa_family)
-    {
-    case AF_INET:
-      if (__len != sizeof (struct sockaddr_in))
-       return -EINVAL;
-      break;
-    case AF_INET6:
-      if (__len != sizeof (struct sockaddr_in6))
-       return -EINVAL;
-      break;
-
-    default:
-      return -1;
-      break;
-    }
-
-  /* handle domains implemented by vpp */
-  switch (__addr->sa_family)
-    {
-    case AF_INET:
-    case AF_INET6:
-      rv = vcom_socket_bind (__fd, __addr, __len);
-      return rv;
-      break;
-
-    default:
-      return -1;
-      break;
-    }
-
-  return -1;
-}
-
-int
-bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-
-      rv = vcom_bind (__fd, __addr, __len);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] bind: "
-                "'%04d'='%04d', '%p', '%04d'\n",
-                pid, rv, __fd, __addr, __len);
-      if (rv != 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return 0;
-    }
-  return libc_bind (__fd, __addr, __len);
-}
-
-/*
- * Put the local address of FD into *ADDR and its length in *LEN.
- * */
-int
-vcom_getsockname (int __fd, __SOCKADDR_ARG __addr,
-                 socklen_t * __restrict __len)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_getsockname (__fd, __addr, __len);
-}
-
-int
-getsockname (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __len)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      rv = vcom_getsockname (__fd, __addr, __len);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] getsockname: "
-                "'%04d'='%04d', '%p', '%p'\n", pid, rv, __fd, __addr, __len);
-      if (rv != 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return 0;
-    }
-  return libc_getsockname (__fd, __addr, __len);
-}
-
-/*
- * Open a connection on socket FD to peer at ADDR
- * (which LEN bytes long). For connectionless socket types, just set
- * the default address to send to and the only address from which to
- * accept transmissions. Return 0 on success, -1 for errors.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-int
-vcom_connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
-{
-  int rv = -1;
-
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  /* validate __len */
-  switch (__addr->sa_family)
-    {
-    case AF_INET:
-      if (__len != INET_ADDRSTRLEN)
-       return -1;
-      break;
-    case AF_INET6:
-      if (__len != INET6_ADDRSTRLEN)
-       return -1;
-      break;
-
-    default:
-      return -1;
-      break;
-    }
-
-  /* handle domains implemented by vpp */
-  switch (__addr->sa_family)
-    {
-    case AF_INET:
-    case AF_INET6:
-      rv = vcom_socket_connect (__fd, __addr, __len);
-      break;
-
-    default:
-      return -1;
-      break;
-    }
-
-  return rv;
-}
-
-int
-connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len)
-{
-  int rv;
-  pid_t pid = getpid ();
-  pthread_t tid = pthread_self ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      rv = vcom_connect (__fd, __addr, __len);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d][%lu (0x%lx)] connect: "
-                "'%04d'='%04d', '%p', '%04d'\n",
-                pid, (unsigned long) tid, (unsigned long) tid,
-                rv, __fd, __addr, __len);
-      if (rv != 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return 0;
-    }
-
-  return libc_connect (__fd, __addr, __len);
-}
-
-/*
- * Put the address of the peer connected to socket FD into *ADDR
- * (which is *LEN bytes long), and its actual length into *LEN.
- * */
-int
-vcom_getpeername (int __fd, __SOCKADDR_ARG __addr,
-                 socklen_t * __restrict __len)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_getpeername (__fd, __addr, __len);
-}
-
-int
-getpeername (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __len)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      rv = vcom_getpeername (__fd, __addr, __len);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] getpeername: "
-                "'%04d'='%04d', '%p', '%p'\n", pid, rv, __fd, __addr, __len);
-      if (rv != 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return 0;
-    }
-  return libc_getpeername (__fd, __addr, __len);
-}
-
-/*
- * Send N bytes of BUF to socket FD.  Returns the number sent or -1.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-ssize_t
-vcom_send (int __fd, const void *__buf, size_t __n, int __flags)
-{
-
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_send (__fd, (void *) __buf, (int) __n, __flags);
-}
-
-ssize_t
-send (int __fd, const void *__buf, size_t __n, int __flags)
-{
-  ssize_t size;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_send (__fd, __buf, __n, __flags);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] send: "
-                "'%04d'='%04d', '%p', '%04d', '%04x'\n",
-                pid, (int) size, __fd, __buf, (int) __n, __flags);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_send (__fd, __buf, __n, __flags);
-}
-
-/*
- * Read N bytes into BUF from socket FD.
- * Returns the number read or -1 for errors.
- * This function is a cancellation point and therefore not marked
- *  with __THROW.
- *  */
-ssize_t
-vcom_recv (int __fd, void *__buf, size_t __n, int __flags)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_recv (__fd, __buf, __n, __flags);
-}
-
-ssize_t
-recv (int __fd, void *__buf, size_t __n, int __flags)
-{
-  ssize_t size;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_recv (__fd, __buf, __n, __flags);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] recv: "
-                "'%04d'='%04d', '%p', '%04d', '%04x'\n",
-                pid, (int) size, __fd, __buf, (int) __n, __flags);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_recv (__fd, __buf, __n, __flags);
-}
-
-/*
- * Send N bytes of BUF on socket FD to peer at address ADDR (which is
- * ADDR_LEN bytes long).  Returns the number sent, or -1 for errors.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-ssize_t
-vcom_sendto (int __fd, const void *__buf, size_t __n, int __flags,
-            __CONST_SOCKADDR_ARG __addr, socklen_t __addr_len)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_sendto (__fd, __buf, __n, __flags, __addr, __addr_len);
-}
-
-ssize_t
-sendto (int __fd, const void *__buf, size_t __n, int __flags,
-       __CONST_SOCKADDR_ARG __addr, socklen_t __addr_len)
-{
-  ssize_t size;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_sendto (__fd, __buf, __n, __flags, __addr, __addr_len);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] sendto: "
-                "'%04d'='%04d', '%p', '%04d', '%04x', "
-                "'%p', '%04d'\n",
-                pid, (int) size, __fd, __buf, (int) __n, __flags,
-                __addr, __addr_len);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_sendto (__fd, __buf, __n, __flags, __addr, __addr_len);
-}
-
-/*
- * Read N bytes into BUF through socket FD.
- * If ADDR is not NULL, fill in *ADDR_LEN bytes of it with the
- * address of the sender, and store the actual size of the address
- * in *ADDR_LEN.
- * Returns the number of bytes read or -1 for errors.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-ssize_t
-vcom_recvfrom (int __fd, void *__restrict __buf, size_t __n,
-              int __flags,
-              __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_recvfrom (__fd, __buf, __n, __flags, __addr, __addr_len);
-}
-
-ssize_t
-recvfrom (int __fd, void *__restrict __buf, size_t __n,
-         int __flags,
-         __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len)
-{
-  ssize_t size;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_recvfrom (__fd, __buf, __n, __flags, __addr, __addr_len);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] recvfrom: "
-                "'%04d'='%04d', '%p', '%04d', '%04x', "
-                "'%p', '%p'\n",
-                pid, (int) size, __fd, __buf, (int) __n, __flags,
-                __addr, __addr_len);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_recvfrom (__fd, __buf, __n, __flags, __addr, __addr_len);
-}
-
-/*
- * Send a message described MESSAGE on socket FD.
- * Returns the number of bytes sent, or -1 for errors.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-ssize_t
-vcom_sendmsg (int __fd, const struct msghdr * __message, int __flags)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_sendmsg (__fd, __message, __flags);
-}
-
-ssize_t
-sendmsg (int __fd, const struct msghdr * __message, int __flags)
-{
-  ssize_t size;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_sendmsg (__fd, __message, __flags);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] sendmsg: "
-                "'%04d'='%04d', '%p', '%04x'\n",
-                pid, (int) size, __fd, __message, __flags);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_sendmsg (__fd, __message, __flags);
-}
-
-#ifdef __USE_GNU
-/*
- * Send a VLEN messages as described by VMESSAGES to socket FD.
- * Returns the number of datagrams successfully written
- * or -1 for errors.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-int
-vcom_sendmmsg (int __fd, struct mmsghdr *__vmessages,
-              unsigned int __vlen, int __flags)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_sendmmsg (__fd, __message, __vlen, __flags);
-}
-
-int
-sendmmsg (int __fd, struct mmsghdr *__vmessages,
-         unsigned int __vlen, int __flags)
-{
-  ssize_t size;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_sendmmsg (__fd, __message, __vlen, __flags);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] sendmmsg: "
-                "'%04d'='%04d', '%p', '%04d', '%04x'\n",
-                pid, (int) size, __fd, __vmessages, __vlen, __flags);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_sendmmsg (__fd, __message, __vlen, __flags);
-}
-
-#endif
-
-/*
- * Receive a message as described by MESSAGE from socket FD.
- * Returns the number of bytes read or -1 for errors.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-ssize_t
-vcom_recvmsg (int __fd, struct msghdr * __message, int __flags)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_recvmsg (__fd, __message, __flags);
-}
-
-ssize_t
-recvmsg (int __fd, struct msghdr * __message, int __flags)
-{
-  ssize_t size;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_recvmsg (__fd, __message, __flags);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] recvmsg: "
-                "'%04d'='%04d', '%p', '%04x'\n",
-                pid, (int) size, __fd, __message, __flags);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_recvmsg (__fd, __message, __flags);
-}
-
-#ifdef __USE_GNU
-/*
- * Receive up to VLEN messages as described by VMESSAGES from socket FD.
- * Returns the number of messages received or -1 for errors.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-int
-vcom_recvmmsg (int __fd, struct mmsghdr *__vmessages,
-              unsigned int __vlen, int __flags, struct timespec *__tmo)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_recvmmsg (__fd, __message, __vlen, __flags, __tmo);
-}
-
-int
-recvmmsg (int __fd, struct mmsghdr *__vmessages,
-         unsigned int __vlen, int __flags, struct timespec *__tmo)
-{
-  ssize_t size;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      size = vcom_recvmmsg (__fd, __message, __vlen, __flags, __tmo);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] recvmmsg: "
-                "'%04d'='%04d', '%p', "
-                "'%04d', '%04x', '%p'\n",
-                pid, (int) size, __fd, __vmessages, __vlen, __flags, __tmo);
-      if (size < 0)
-       {
-         errno = -size;
-         return -1;
-       }
-      return size;
-    }
-  return libc_recvmmsg (__fd, __message, __vlen, __flags, __tmo);
-}
-
-#endif
-
-/*
- * Put the current value for socket FD's option OPTNAME
- * at protocol level LEVEL into OPTVAL (which is *OPTLEN bytes long),
- * and set *OPTLEN to the value's actual length.
- * Returns 0 on success, -1 for errors.
- * */
-int
-vcom_getsockopt (int __fd, int __level, int __optname,
-                void *__restrict __optval, socklen_t * __restrict __optlen)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_getsockopt (__fd, __level, __optname,
-                                __optval, __optlen);
-}
-
-int
-getsockopt (int __fd, int __level, int __optname,
-           void *__restrict __optval, socklen_t * __restrict __optlen)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      rv = vcom_getsockopt (__fd, __level, __optname, __optval, __optlen);
-      if (VCOM_DEBUG > 2)
-       fprintf (stderr,
-                "[%d] getsockopt: "
-                "'%04d'='%04d', '%04d', '%04d', "
-                "'%p', '%p'\n",
-                pid, rv, __fd, __level, __optname, __optval, __optlen);
-      if (rv != 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return 0;
-    }
-  return libc_getsockopt (__fd, __level, __optname, __optval, __optlen);
-}
-
-/*
- * Set socket FD's option OPTNAME at protocol level LEVEL
- * to *OPTVAL (which is OPTLEN bytes long).
- * Returns 0 on success, -1 for errors.
- * */
-int
-vcom_setsockopt (int __fd, int __level, int __optname,
-                const void *__optval, socklen_t __optlen)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_setsockopt (__fd, __level, __optname,
-                                __optval, __optlen);
-}
-
-int
-setsockopt (int __fd, int __level, int __optname,
-           const void *__optval, socklen_t __optlen)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      rv = vcom_setsockopt (__fd, __level, __optname, __optval, __optlen);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] setsockopt: "
-                "'%04d'='%04d', '%04d', '%04d', "
-                "'%p', '%04d'\n",
-                pid, rv, __fd, __level, __optname, __optval, __optlen);
-      if (rv != 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return 0;
-    }
-  return libc_setsockopt (__fd, __level, __optname, __optval, __optlen);
-}
-
-/*
- * Prepare to accept connections on socket FD.
- * N connection requests will be queued before further
- * requests are refused.
- * Returns 0 on success, -1 for errors.
- * */
-int
-vcom_listen (int __fd, int __n)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_listen (__fd, __n);
-}
-
-int
-listen (int __fd, int __n)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      rv = vcom_listen (__fd, __n);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] listen: "
-                "'%04d'='%04d', '%04d'\n", pid, rv, __fd, __n);
-      if (rv != 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return 0;
-    }
-  return libc_listen (__fd, __n);
-}
-
-/*
- * Await a connection on socket FD.
- * When a connection arrives, open a new socket to communicate
- * with it, set *ADDR (which is *ADDR_LEN bytes long) to the address
- * of the connecting peer and *ADDR_LEN to the address's actual
- * length, and return the new socket's descriptor, or -1 for errors.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-int
-vcom_accept (int __fd, __SOCKADDR_ARG __addr,
-            socklen_t * __restrict __addr_len)
-{
-
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-  return vcom_socket_accept (__fd, __addr, __addr_len);
-}
-
-int
-accept (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len)
-{
-  int rv = -1;
-  pid_t pid = getpid ();
-  pthread_t tid = pthread_self ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      if (VCOM_DEBUG > 0)
-       vcom_socket_main_show ();
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d][%lu (0x%lx)] accept1: "
-                "'%04d'='%04d', '%p', '%p'\n",
-                pid, (unsigned long) tid, (unsigned long) tid,
-                rv, __fd, __addr, __addr_len);
-      rv = vcom_accept (__fd, __addr, __addr_len);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d][%lu (0x%lx)] accept2: "
-                "'%04d'='%04d', '%p', '%p'\n",
-                pid, (unsigned long) tid, (unsigned long) tid,
-                rv, __fd, __addr, __addr_len);
-      if (VCOM_DEBUG > 0)
-       vcom_socket_main_show ();
-      if (rv < 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return rv;
-    }
-  return libc_accept (__fd, __addr, __addr_len);
-}
-
-#ifdef __USE_GNU
-/*
- * Similar to 'accept' but takes an additional parameter to specify
- * flags.
- * This function is a cancellation point and therefore not marked
- * with __THROW.
- * */
-int
-vcom_accept4 (int __fd, __SOCKADDR_ARG __addr,
-             socklen_t * __restrict __addr_len, int __flags)
-{
-
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_socket_accept4 (__fd, __addr, __addr_len, __flags);
-}
-
-int
-accept4 (int __fd, __SOCKADDR_ARG __addr,
-        socklen_t * __restrict __addr_len, int __flags)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      if (VCOM_DEBUG > 0)
-       vcom_socket_main_show ();
-      rv = vcom_accept4 (__fd, __addr, __addr_len, __flags);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] accept4: "
-                "'%04d'='%04d', '%p', '%p', '%04x'\n",
-                pid, rv, __fd, __addr, __addr_len, __flags);
-      if (VCOM_DEBUG > 0)
-       vcom_socket_main_show ();
-      if (rv < 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return rv;
-    }
-  return libc_accept4 (__fd, __addr, __addr_len, __flags);
-}
-
-#endif
-
-/*
- * Shut down all or part of the connection open on socket FD.
- * HOW determines what to shut down:
- *   SHUT_RD   = No more receptions;
- *   SHUT_WR   = No more transmissions;
- *   SHUT_RDWR = No more receptions or transmissions.
- * Returns 0 on success, -1 for errors.
- * */
-int
-vcom_shutdown (int __fd, int __how)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-  return vcom_socket_shutdown (__fd, __how);
-}
-
-int
-shutdown (int __fd, int __how)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_socket_fd (__fd))
-    {
-      rv = vcom_shutdown (__fd, __how);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] shutdown: "
-                "'%04d'='%04d', '%04d'\n", pid, rv, __fd, __how);
-      if (rv != 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return 0;
-    }
-  return libc_shutdown (__fd, __how);
-}
-
-int
-vcom_epoll_create (int __size)
-{
-
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  if (__size <= 0)
-    {
-      return -EINVAL;
-    }
-
-  /* __size argument is ignored "thereafter" */
-  return vcom_epoll_create1 (0);
-}
-
-/*
- * __size argument is ignored, but must be greater than zero
- */
-int
-epoll_create (int __size)
-{
-  int rv = 0;
-  pid_t pid = getpid ();
-
-  rv = vcom_epoll_create (__size);
-  if (VCOM_DEBUG > 0)
-    fprintf (stderr,
-            "[%d] epoll_create: " "'%04d'='%04d'\n", pid, rv, __size);
-  if (rv < 0)
-    {
-      errno = -rv;
-      return -1;
-    }
-  return rv;
-}
-
-int
-vcom_epoll_create1 (int __flags)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  if (__flags < 0)
-    {
-      return -EINVAL;
-    }
-  if (__flags & ~EPOLL_CLOEXEC)
-    {
-      return -EINVAL;
-    }
-  /* __flags can be either zero or EPOLL_CLOEXEC */
-  /* implementation */
-  return vcom_socket_epoll_create1 (__flags);
-}
-
-/*
- * __flags can be either zero or EPOLL_CLOEXEC
- * */
-int
-epoll_create1 (int __flags)
-{
-  int rv = 0;
-  pid_t pid = getpid ();
-
-  rv = vcom_epoll_create1 (__flags);
-  if (VCOM_DEBUG > 0)
-    fprintf (stderr,
-            "[%d] epoll_create: " "'%04d'='%08x'\n", pid, rv, __flags);
-  if (rv < 0)
-    {
-      errno = -rv;
-      return -1;
-    }
-  return rv;
-}
-
-static inline int
-ep_op_has_event (int op)
-{
-  return op != EPOLL_CTL_DEL;
-}
-
-int
-vcom_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  /*
-   * the requested operation __op is not supported
-   * by this interface */
-  if (!((__op == EPOLL_CTL_ADD) ||
-       (__op == EPOLL_CTL_MOD) || (__op == EPOLL_CTL_DEL)))
-    {
-      return -EINVAL;
-    }
-
-  /* op is ADD or MOD but event parameter is NULL */
-  if ((ep_op_has_event (__op) && !__event))
-    {
-      return -EFAULT;
-    }
-
-  /* fd is same as epfd */
-  /* do not permit adding an epoll file descriptor inside itself */
-  if (__epfd == __fd)
-    {
-      return -EINVAL;
-    }
-
-  /* implementation */
-  return vcom_socket_epoll_ctl (__epfd, __op, __fd, __event);
-}
-
-/*
- * implement the controller interface for epoll
- * that enables the insertion/removal/change of
- * file descriptors inside the interest set.
- */
-int
-epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (is_vcom_epfd (__epfd))
-    {
-      /* TBD: currently limiting epoll to support only vcom fds */
-      if (is_vcom_socket_fd (__fd))
-       {
-         rv = vcom_epoll_ctl (__epfd, __op, __fd, __event);
-         if (VCOM_DEBUG > 0)
-           fprintf (stderr,
-                    "[%d] epoll_ctl: "
-                    "'%04d'='%04d', '%04d', '%04d'\n",
-                    pid, rv, __epfd, __op, __fd);
-         if (rv != 0)
-           {
-             errno = -rv;
-             return -1;
-           }
-         return 0;
-       }
-      else
-       {
-         /*
-          * TBD: currently epoll does not support kernel fds
-          * or epoll fds */
-         errno = EBADF;
-         return -1;
-       }
-    }
-  else
-    {
-      /* epfd is not an epoll file descriptor */
-      errno = EINVAL;
-      return -1;
-    }
-  return 0;
-}
-
-int
-vcom_epoll_wait (int __epfd, struct epoll_event *__events,
-                int __maxevents, int __timeout)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return vcom_epoll_pwait (__epfd, __events, __maxevents, __timeout, NULL);
-}
-
-int
-epoll_wait (int __epfd, struct epoll_event *__events,
-           int __maxevents, int __timeout)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (__maxevents <= 0 || __maxevents > EP_MAX_EVENTS)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-  if (is_vcom_epfd (__epfd))
-    {
-      rv = vcom_epoll_wait (__epfd, __events, __maxevents, __timeout);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] epoll_wait: "
-                "'%04d'='%04d', '%p', "
-                "'%04d', '%04d'\n",
-                pid, rv, __epfd, __events, __maxevents, __timeout);
-      if (rv < 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return rv;
-    }
-  else
-    {
-      errno = EINVAL;
-      return -1;
-    }
-  return 0;
-}
-
-
-int
-vcom_epoll_pwait (int __epfd, struct epoll_event *__events,
-                 int __maxevents, int __timeout, const __sigset_t * __ss)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  /* implementation */
-  return vcom_socket_epoll_pwait (__epfd, __events,
-                                 __maxevents, __timeout, __ss);
-}
-
-int
-epoll_pwait (int __epfd, struct epoll_event *__events,
-            int __maxevents, int __timeout, const __sigset_t * __ss)
-{
-  int rv;
-  pid_t pid = getpid ();
-
-  if (__maxevents <= 0 || __maxevents > EP_MAX_EVENTS)
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-  if (is_vcom_epfd (__epfd))
-    {
-      rv = vcom_epoll_pwait (__epfd, __events, __maxevents, __timeout, __ss);
-      if (VCOM_DEBUG > 0)
-       fprintf (stderr,
-                "[%d] epoll_pwait: "
-                "'%04d'='%04d', '%p', "
-                "'%04d', '%04d', "
-                "'%p'\n",
-                pid, rv, __epfd, __events, __maxevents, __timeout, __ss);
-      if (rv < 0)
-       {
-         errno = -rv;
-         return -1;
-       }
-      return rv;
-    }
-  else
-    {
-      errno = EINVAL;
-      return -1;
-    }
-
-  return 0;
-}
-
-/* Poll the file descriptors described by the NFDS structures starting at
-   FDS.  If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for
-   an event to occur; if TIMEOUT is -1, block until an event occurs.
-   Returns the number of file descriptors with events, zero if timed out,
-   or -1 for errors.
-
-   This function is a cancellation point and therefore not marked with
-   __THROW.  */
-
-int
-vcom_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
-{
-  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)
-    {
-      rv = -errno;
-      goto poll_done;
-    }
-
-  /* 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 > 2)
-           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 > 2)
-           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 > 2)
-    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 ();
-
-
-  if (VCOM_DEBUG > 2)
-    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 > 2)
-    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;
-}
-
-#ifdef __USE_GNU
-/* Like poll, but before waiting the threads signal mask is replaced
-   with that specified in the fourth parameter.  For better usability,
-   the timeout value is specified using a TIMESPEC object.
-
-   This function is a cancellation point and therefore not marked with
-   __THROW.  */
-int
-vcom_ppoll (struct pollfd *__fds, nfds_t __nfds,
-           const struct timespec *__timeout, const __sigset_t * __ss)
-{
-  if (vcom_init () != 0)
-    {
-      return -1;
-    }
-
-  return -EOPNOTSUPP;
-}
-
-int
-ppoll (struct pollfd *__fds, nfds_t __nfds,
-       const struct timespec *__timeout, const __sigset_t * __ss)
-{
-  int rv = 0;
-
-  errno = EOPNOTSUPP;
-  rv = -1;
-  return rv;
-}
-#endif
-
-void CONSTRUCTOR_ATTRIBUTE vcom_constructor (void);
-
-void DESTRUCTOR_ATTRIBUTE vcom_destructor (void);
-
-void
-vcom_constructor (void)
-{
-  pid_t pid = getpid ();
-
-  swrap_constructor ();
-  if (vcom_init () != 0)
-    {
-      printf ("\n[%d] vcom_constructor...failed!\n", pid);
-    }
-  else
-    {
-      printf ("\n[%d] vcom_constructor...done!\n", pid);
-    }
-}
-
-/*
- * This function is called when the library is unloaded
- */
-void
-vcom_destructor (void)
-{
-  pid_t pid = getpid ();
-
-  vcom_destroy ();
-  swrap_destructor ();
-  printf ("\n[%d] vcom_destructor...done!\n", pid);
-}
-
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */