consolidate
[m6w6/libmemcached] / src / p9y / p9y.cpp
1 #include "libgen.hpp"
2 #if defined P9Y_NEED_BASENAME
3 # if defined _WIN32
4 char *basename(const char *filename) {
5 static char base[_MAX_PATH * 2], ext[_MAX_PATH], *ptr;
6 (void) _splitpath_s(filename, NULL, 0, NULL, 0, base, _MAX_PATH, ext, _MAX_PATH);
7 strcat_s(base, _MAX_PATH * 2 - 1, ext);
8 return base;
9 }
10 # endif // _WIN32
11 #endif // P9Y_NEED_BASENAME
12
13 #include "realpath.hpp"
14 #if defined P9Y_NEED_REALPATH
15 # if defined _WIN32
16 char *realpath(const char *path, char real[_MAX_PATH]) {
17 return _fullpath(real, path, _MAX_PATH);
18 }
19 # endif // _WIN32
20 #endif // P9Y_NEED_REALPATH
21
22 #include "gettimeofday.hpp"
23 #if defined P9Y_NEED_GETTIMEOFDAY
24 # include <chrono>
25 int gettimeofday(struct timeval* tp, struct timezone*) {
26 using clock = std::chrono::system_clock;
27 auto as_sec = [] (auto d) {
28 return std::chrono::duration_cast<std::chrono::seconds>(d);
29 };
30 auto as_usec = [] (auto d) {
31 return std::chrono::duration_cast<std::chrono::microseconds>(d);
32 };
33
34 auto now = clock::now().time_since_epoch();
35 auto sec = as_sec(now);
36 auto usec = as_usec(now - sec);
37
38 tp->tv_sec = sec.count();
39 tp->tv_usec = usec.count();
40 return 0;
41 }
42 #endif // P9Y_NEED_GETTIMEOFDAY
43
44 #include "socket.hpp"
45 #if defined P9Y_NEED_GET_SOCKET_ERRNO
46 # if defined _WIN32
47 int get_socket_errno() {
48 int local_errno = WSAGetLastError();
49
50 switch (local_errno) {
51 case WSAEINVAL:
52 local_errno = EINPROGRESS;
53 break;
54 case WSAEALREADY:
55 case WSAEWOULDBLOCK:
56 local_errno = EAGAIN;
57 break;
58
59 case WSAECONNREFUSED:
60 local_errno = ECONNREFUSED;
61 break;
62
63 case WSAENETUNREACH:
64 local_errno = ENETUNREACH;
65 break;
66
67 case WSAETIMEDOUT:
68 local_errno = ETIMEDOUT;
69 break;
70
71 case WSAECONNRESET:
72 local_errno = ECONNRESET;
73 break;
74
75 case WSAEADDRINUSE:
76 local_errno = EADDRINUSE;
77 break;
78
79 case WSAEOPNOTSUPP:
80 local_errno = EOPNOTSUPP;
81 break;
82
83 case WSAENOPROTOOPT:
84 local_errno = ENOPROTOOPT;
85 break;
86
87 default:
88 break;
89 }
90
91 return local_errno;
92 }
93 # endif // _WIN32
94 #endif // P9Y_NEED_GET_SOCKET_ERRNO
95
96 #include "poll.hpp"
97 #if defined P9Y_NEED_POLL
98 int poll(struct pollfd fds[], nfds_t nfds, int tmo) {
99 fd_set readfds, writefds, errorfds;
100 FD_ZERO(&readfds);
101 FD_ZERO(&writefds);
102 FD_ZERO(&errorfds);
103
104 int maxfd = 0;
105
106 for (nfds_t x = 0; x < nfds; ++x) {
107 if (fds[x].events & (POLLIN | POLLOUT)) {
108 # ifndef _WIN32
109 if (fds[x].fd > maxfd) {
110 maxfd = fds[x].fd;
111 }
112 # endif
113 if (fds[x].events & POLLIN) {
114 FD_SET(fds[x].fd, &readfds);
115 }
116 if (fds[x].events & POLLOUT) {
117 FD_SET(fds[x].fd, &writefds);
118 }
119 }
120 }
121
122 struct timeval timeout = {tmo / 1000, (tmo % 1000) * 1000};
123 struct timeval *tp = &timeout;
124 if (tmo == -1) {
125 tp = NULL;
126 }
127 int ret = select(maxfd + 1, &readfds, &writefds, &errorfds, tp);
128 if (ret <= 0) {
129 return ret;
130 }
131
132 /* Iterate through all of them because I need to clear the revent map */
133 for (nfds_t x = 0; x < nfds; ++x) {
134 fds[x].revents = 0;
135 if (FD_ISSET(fds[x].fd, &readfds)) {
136 fds[x].revents |= POLLIN;
137 }
138 if (FD_ISSET(fds[x].fd, &writefds)) {
139 fds[x].revents |= POLLOUT;
140 }
141 if (FD_ISSET(fds[x].fd, &errorfds)) {
142 fds[x].revents |= POLLERR;
143 }
144 }
145
146 return ret;
147 }
148 #endif // P9Y_NEED_POLL