X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Fp9y%2Fp9y.cpp;h=1c5c4ac982206582f005fae8d5319d02c3cd654a;hb=7781e7d0bf9fc0d986308838a3e1e47d0df3c019;hp=35ee8f010b4d190574f3e9e52931e45aef589f59;hpb=118abd2f53e24a4f312ad0fcd484f6f8dbe5094c;p=awesomized%2Flibmemcached diff --git a/src/p9y/p9y.cpp b/src/p9y/p9y.cpp index 35ee8f01..1c5c4ac9 100644 --- a/src/p9y/p9y.cpp +++ b/src/p9y/p9y.cpp @@ -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 +int gettimeofday(struct timeval* tp, struct timezone*) { + using clock = std::chrono::system_clock; + auto as_sec = [] (auto d) { + return std::chrono::duration_cast(d); + }; + auto as_usec = [] (auto d) { + return std::chrono::duration_cast(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