consolidate
[m6w6/libmemcached] / src / p9y / p9y.cpp
index 35ee8f010b4d190574f3e9e52931e45aef589f59..1c5c4ac982206582f005fae8d5319d02c3cd654a 100644 (file)
@@ -1 +1,148 @@
-// empty stub
+#include "libgen.hpp"
+#if defined P9Y_NEED_BASENAME
+# if defined _WIN32
+char *basename(const char *filename) {
+  static char base[_MAX_PATH * 2], ext[_MAX_PATH], *ptr;
+  (void) _splitpath_s(filename, NULL, 0, NULL, 0, base, _MAX_PATH, ext, _MAX_PATH);
+  strcat_s(base, _MAX_PATH * 2 - 1, ext);
+  return base;
+}
+# endif // _WIN32
+#endif // P9Y_NEED_BASENAME
+
+#include "realpath.hpp"
+#if defined P9Y_NEED_REALPATH
+# if defined _WIN32
+char *realpath(const char *path, char real[_MAX_PATH]) {
+  return _fullpath(real, path, _MAX_PATH);
+}
+# endif // _WIN32
+#endif // P9Y_NEED_REALPATH
+
+#include "gettimeofday.hpp"
+#if defined P9Y_NEED_GETTIMEOFDAY
+# include <chrono>
+int gettimeofday(struct timeval* tp, struct timezone*) {
+  using clock = std::chrono::system_clock;
+  auto as_sec = [] (auto d) {
+      return std::chrono::duration_cast<std::chrono::seconds>(d);
+  };
+  auto as_usec = [] (auto d) {
+      return std::chrono::duration_cast<std::chrono::microseconds>(d);
+  };
+
+  auto now = clock::now().time_since_epoch();
+  auto sec = as_sec(now);
+  auto usec = as_usec(now - sec);
+
+  tp->tv_sec = sec.count();
+  tp->tv_usec = usec.count();
+  return 0;
+}
+#endif // P9Y_NEED_GETTIMEOFDAY
+
+#include "socket.hpp"
+#if defined P9Y_NEED_GET_SOCKET_ERRNO
+# if defined _WIN32
+int get_socket_errno() {
+    int local_errno = WSAGetLastError();
+
+  switch (local_errno) {
+  case WSAEINVAL:
+    local_errno = EINPROGRESS;
+    break;
+  case WSAEALREADY:
+  case WSAEWOULDBLOCK:
+    local_errno = EAGAIN;
+    break;
+
+  case WSAECONNREFUSED:
+    local_errno = ECONNREFUSED;
+    break;
+
+  case WSAENETUNREACH:
+    local_errno = ENETUNREACH;
+    break;
+
+  case WSAETIMEDOUT:
+    local_errno = ETIMEDOUT;
+    break;
+
+  case WSAECONNRESET:
+    local_errno = ECONNRESET;
+    break;
+
+  case WSAEADDRINUSE:
+    local_errno = EADDRINUSE;
+    break;
+
+  case WSAEOPNOTSUPP:
+    local_errno = EOPNOTSUPP;
+    break;
+
+  case WSAENOPROTOOPT:
+    local_errno = ENOPROTOOPT;
+    break;
+
+  default:
+    break;
+  }
+
+  return local_errno;
+}
+# endif // _WIN32
+#endif // P9Y_NEED_GET_SOCKET_ERRNO
+
+#include "poll.hpp"
+#if defined P9Y_NEED_POLL
+int poll(struct pollfd fds[], nfds_t nfds, int tmo) {
+  fd_set readfds, writefds, errorfds;
+  FD_ZERO(&readfds);
+  FD_ZERO(&writefds);
+  FD_ZERO(&errorfds);
+
+  int maxfd = 0;
+
+  for (nfds_t x = 0; x < nfds; ++x) {
+    if (fds[x].events & (POLLIN | POLLOUT)) {
+#  ifndef _WIN32
+      if (fds[x].fd > maxfd) {
+        maxfd = fds[x].fd;
+      }
+#  endif
+      if (fds[x].events & POLLIN) {
+        FD_SET(fds[x].fd, &readfds);
+      }
+      if (fds[x].events & POLLOUT) {
+        FD_SET(fds[x].fd, &writefds);
+      }
+    }
+  }
+
+  struct timeval timeout = {tmo / 1000, (tmo % 1000) * 1000};
+  struct timeval *tp = &timeout;
+  if (tmo == -1) {
+    tp = NULL;
+  }
+  int ret = select(maxfd + 1, &readfds, &writefds, &errorfds, tp);
+  if (ret <= 0) {
+    return ret;
+  }
+
+  /* Iterate through all of them because I need to clear the revent map */
+  for (nfds_t x = 0; x < nfds; ++x) {
+    fds[x].revents = 0;
+    if (FD_ISSET(fds[x].fd, &readfds)) {
+      fds[x].revents |= POLLIN;
+    }
+    if (FD_ISSET(fds[x].fd, &writefds)) {
+      fds[x].revents |= POLLOUT;
+    }
+    if (FD_ISSET(fds[x].fd, &errorfds)) {
+      fds[x].revents |= POLLERR;
+    }
+  }
+
+  return ret;
+}
+#endif // P9Y_NEED_POLL