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