redis-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +190 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +23 -0
  5. data/Gemfile.lock +67 -0
  6. data/LICENSE.md +21 -0
  7. data/README.md +347 -0
  8. data/Rakefile +86 -0
  9. data/ext/redis_client/hiredis/extconf.rb +54 -0
  10. data/ext/redis_client/hiredis/hiredis_connection.c +696 -0
  11. data/ext/redis_client/hiredis/vendor/.gitignore +9 -0
  12. data/ext/redis_client/hiredis/vendor/.travis.yml +131 -0
  13. data/ext/redis_client/hiredis/vendor/CHANGELOG.md +364 -0
  14. data/ext/redis_client/hiredis/vendor/CMakeLists.txt +165 -0
  15. data/ext/redis_client/hiredis/vendor/COPYING +29 -0
  16. data/ext/redis_client/hiredis/vendor/Makefile +308 -0
  17. data/ext/redis_client/hiredis/vendor/README.md +664 -0
  18. data/ext/redis_client/hiredis/vendor/adapters/ae.h +130 -0
  19. data/ext/redis_client/hiredis/vendor/adapters/glib.h +156 -0
  20. data/ext/redis_client/hiredis/vendor/adapters/ivykis.h +84 -0
  21. data/ext/redis_client/hiredis/vendor/adapters/libev.h +179 -0
  22. data/ext/redis_client/hiredis/vendor/adapters/libevent.h +175 -0
  23. data/ext/redis_client/hiredis/vendor/adapters/libuv.h +117 -0
  24. data/ext/redis_client/hiredis/vendor/adapters/macosx.h +115 -0
  25. data/ext/redis_client/hiredis/vendor/adapters/qt.h +135 -0
  26. data/ext/redis_client/hiredis/vendor/alloc.c +86 -0
  27. data/ext/redis_client/hiredis/vendor/alloc.h +91 -0
  28. data/ext/redis_client/hiredis/vendor/appveyor.yml +24 -0
  29. data/ext/redis_client/hiredis/vendor/async.c +887 -0
  30. data/ext/redis_client/hiredis/vendor/async.h +147 -0
  31. data/ext/redis_client/hiredis/vendor/async_private.h +75 -0
  32. data/ext/redis_client/hiredis/vendor/dict.c +352 -0
  33. data/ext/redis_client/hiredis/vendor/dict.h +126 -0
  34. data/ext/redis_client/hiredis/vendor/fmacros.h +12 -0
  35. data/ext/redis_client/hiredis/vendor/hiredis-config.cmake.in +13 -0
  36. data/ext/redis_client/hiredis/vendor/hiredis.c +1174 -0
  37. data/ext/redis_client/hiredis/vendor/hiredis.h +336 -0
  38. data/ext/redis_client/hiredis/vendor/hiredis.pc.in +12 -0
  39. data/ext/redis_client/hiredis/vendor/hiredis_ssl-config.cmake.in +13 -0
  40. data/ext/redis_client/hiredis/vendor/hiredis_ssl.h +157 -0
  41. data/ext/redis_client/hiredis/vendor/hiredis_ssl.pc.in +12 -0
  42. data/ext/redis_client/hiredis/vendor/net.c +612 -0
  43. data/ext/redis_client/hiredis/vendor/net.h +56 -0
  44. data/ext/redis_client/hiredis/vendor/read.c +739 -0
  45. data/ext/redis_client/hiredis/vendor/read.h +129 -0
  46. data/ext/redis_client/hiredis/vendor/sds.c +1289 -0
  47. data/ext/redis_client/hiredis/vendor/sds.h +278 -0
  48. data/ext/redis_client/hiredis/vendor/sdsalloc.h +44 -0
  49. data/ext/redis_client/hiredis/vendor/sockcompat.c +248 -0
  50. data/ext/redis_client/hiredis/vendor/sockcompat.h +92 -0
  51. data/ext/redis_client/hiredis/vendor/ssl.c +544 -0
  52. data/ext/redis_client/hiredis/vendor/test.c +1401 -0
  53. data/ext/redis_client/hiredis/vendor/test.sh +78 -0
  54. data/ext/redis_client/hiredis/vendor/win32.h +56 -0
  55. data/lib/redis-client.rb +3 -0
  56. data/lib/redis_client/buffered_io.rb +149 -0
  57. data/lib/redis_client/config.rb +174 -0
  58. data/lib/redis_client/connection.rb +86 -0
  59. data/lib/redis_client/hiredis_connection.rb +78 -0
  60. data/lib/redis_client/pooled.rb +86 -0
  61. data/lib/redis_client/resp3.rb +225 -0
  62. data/lib/redis_client/sentinel_config.rb +134 -0
  63. data/lib/redis_client/version.rb +5 -0
  64. data/lib/redis_client.rb +438 -0
  65. data/redis-client.gemspec +34 -0
  66. metadata +125 -0
@@ -0,0 +1,278 @@
1
+ /* SDSLib 2.0 -- A C dynamic strings library
2
+ *
3
+ * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
4
+ * Copyright (c) 2015, Oran Agra
5
+ * Copyright (c) 2015, Redis Labs, Inc
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright notice,
12
+ * this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ * * Neither the name of Redis nor the names of its contributors may be used
17
+ * to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+ #ifndef __SDS_H
34
+ #define __SDS_H
35
+
36
+ #define SDS_MAX_PREALLOC (1024*1024)
37
+ #ifdef _MSC_VER
38
+ #define __attribute__(x)
39
+ typedef long long ssize_t;
40
+ #define SSIZE_MAX (LLONG_MAX >> 1)
41
+ #endif
42
+
43
+ #include <sys/types.h>
44
+ #include <stdarg.h>
45
+ #include <stdint.h>
46
+
47
+ typedef char *sds;
48
+
49
+ /* Note: sdshdr5 is never used, we just access the flags byte directly.
50
+ * However is here to document the layout of type 5 SDS strings. */
51
+ struct __attribute__ ((__packed__)) sdshdr5 {
52
+ unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
53
+ char buf[];
54
+ };
55
+ struct __attribute__ ((__packed__)) sdshdr8 {
56
+ uint8_t len; /* used */
57
+ uint8_t alloc; /* excluding the header and null terminator */
58
+ unsigned char flags; /* 3 lsb of type, 5 unused bits */
59
+ char buf[];
60
+ };
61
+ struct __attribute__ ((__packed__)) sdshdr16 {
62
+ uint16_t len; /* used */
63
+ uint16_t alloc; /* excluding the header and null terminator */
64
+ unsigned char flags; /* 3 lsb of type, 5 unused bits */
65
+ char buf[];
66
+ };
67
+ struct __attribute__ ((__packed__)) sdshdr32 {
68
+ uint32_t len; /* used */
69
+ uint32_t alloc; /* excluding the header and null terminator */
70
+ unsigned char flags; /* 3 lsb of type, 5 unused bits */
71
+ char buf[];
72
+ };
73
+ struct __attribute__ ((__packed__)) sdshdr64 {
74
+ uint64_t len; /* used */
75
+ uint64_t alloc; /* excluding the header and null terminator */
76
+ unsigned char flags; /* 3 lsb of type, 5 unused bits */
77
+ char buf[];
78
+ };
79
+
80
+ #define SDS_TYPE_5 0
81
+ #define SDS_TYPE_8 1
82
+ #define SDS_TYPE_16 2
83
+ #define SDS_TYPE_32 3
84
+ #define SDS_TYPE_64 4
85
+ #define SDS_TYPE_MASK 7
86
+ #define SDS_TYPE_BITS 3
87
+ #define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)));
88
+ #define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
89
+ #define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)
90
+
91
+ static inline size_t sdslen(const sds s) {
92
+ unsigned char flags = s[-1];
93
+ switch(flags&SDS_TYPE_MASK) {
94
+ case SDS_TYPE_5:
95
+ return SDS_TYPE_5_LEN(flags);
96
+ case SDS_TYPE_8:
97
+ return SDS_HDR(8,s)->len;
98
+ case SDS_TYPE_16:
99
+ return SDS_HDR(16,s)->len;
100
+ case SDS_TYPE_32:
101
+ return SDS_HDR(32,s)->len;
102
+ case SDS_TYPE_64:
103
+ return SDS_HDR(64,s)->len;
104
+ }
105
+ return 0;
106
+ }
107
+
108
+ static inline size_t sdsavail(const sds s) {
109
+ unsigned char flags = s[-1];
110
+ switch(flags&SDS_TYPE_MASK) {
111
+ case SDS_TYPE_5: {
112
+ return 0;
113
+ }
114
+ case SDS_TYPE_8: {
115
+ SDS_HDR_VAR(8,s);
116
+ return sh->alloc - sh->len;
117
+ }
118
+ case SDS_TYPE_16: {
119
+ SDS_HDR_VAR(16,s);
120
+ return sh->alloc - sh->len;
121
+ }
122
+ case SDS_TYPE_32: {
123
+ SDS_HDR_VAR(32,s);
124
+ return sh->alloc - sh->len;
125
+ }
126
+ case SDS_TYPE_64: {
127
+ SDS_HDR_VAR(64,s);
128
+ return sh->alloc - sh->len;
129
+ }
130
+ }
131
+ return 0;
132
+ }
133
+
134
+ static inline void sdssetlen(sds s, size_t newlen) {
135
+ unsigned char flags = s[-1];
136
+ switch(flags&SDS_TYPE_MASK) {
137
+ case SDS_TYPE_5:
138
+ {
139
+ unsigned char *fp = ((unsigned char*)s)-1;
140
+ *fp = (unsigned char)(SDS_TYPE_5 | (newlen << SDS_TYPE_BITS));
141
+ }
142
+ break;
143
+ case SDS_TYPE_8:
144
+ SDS_HDR(8,s)->len = (uint8_t)newlen;
145
+ break;
146
+ case SDS_TYPE_16:
147
+ SDS_HDR(16,s)->len = (uint16_t)newlen;
148
+ break;
149
+ case SDS_TYPE_32:
150
+ SDS_HDR(32,s)->len = (uint32_t)newlen;
151
+ break;
152
+ case SDS_TYPE_64:
153
+ SDS_HDR(64,s)->len = (uint64_t)newlen;
154
+ break;
155
+ }
156
+ }
157
+
158
+ static inline void sdsinclen(sds s, size_t inc) {
159
+ unsigned char flags = s[-1];
160
+ switch(flags&SDS_TYPE_MASK) {
161
+ case SDS_TYPE_5:
162
+ {
163
+ unsigned char *fp = ((unsigned char*)s)-1;
164
+ unsigned char newlen = SDS_TYPE_5_LEN(flags)+(unsigned char)inc;
165
+ *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
166
+ }
167
+ break;
168
+ case SDS_TYPE_8:
169
+ SDS_HDR(8,s)->len += (uint8_t)inc;
170
+ break;
171
+ case SDS_TYPE_16:
172
+ SDS_HDR(16,s)->len += (uint16_t)inc;
173
+ break;
174
+ case SDS_TYPE_32:
175
+ SDS_HDR(32,s)->len += (uint32_t)inc;
176
+ break;
177
+ case SDS_TYPE_64:
178
+ SDS_HDR(64,s)->len += (uint64_t)inc;
179
+ break;
180
+ }
181
+ }
182
+
183
+ /* sdsalloc() = sdsavail() + sdslen() */
184
+ static inline size_t sdsalloc(const sds s) {
185
+ unsigned char flags = s[-1];
186
+ switch(flags&SDS_TYPE_MASK) {
187
+ case SDS_TYPE_5:
188
+ return SDS_TYPE_5_LEN(flags);
189
+ case SDS_TYPE_8:
190
+ return SDS_HDR(8,s)->alloc;
191
+ case SDS_TYPE_16:
192
+ return SDS_HDR(16,s)->alloc;
193
+ case SDS_TYPE_32:
194
+ return SDS_HDR(32,s)->alloc;
195
+ case SDS_TYPE_64:
196
+ return SDS_HDR(64,s)->alloc;
197
+ }
198
+ return 0;
199
+ }
200
+
201
+ static inline void sdssetalloc(sds s, size_t newlen) {
202
+ unsigned char flags = s[-1];
203
+ switch(flags&SDS_TYPE_MASK) {
204
+ case SDS_TYPE_5:
205
+ /* Nothing to do, this type has no total allocation info. */
206
+ break;
207
+ case SDS_TYPE_8:
208
+ SDS_HDR(8,s)->alloc = (uint8_t)newlen;
209
+ break;
210
+ case SDS_TYPE_16:
211
+ SDS_HDR(16,s)->alloc = (uint16_t)newlen;
212
+ break;
213
+ case SDS_TYPE_32:
214
+ SDS_HDR(32,s)->alloc = (uint32_t)newlen;
215
+ break;
216
+ case SDS_TYPE_64:
217
+ SDS_HDR(64,s)->alloc = (uint64_t)newlen;
218
+ break;
219
+ }
220
+ }
221
+
222
+ sds sdsnewlen(const void *init, size_t initlen);
223
+ sds sdsnew(const char *init);
224
+ sds sdsempty(void);
225
+ sds sdsdup(const sds s);
226
+ void sdsfree(sds s);
227
+ sds sdsgrowzero(sds s, size_t len);
228
+ sds sdscatlen(sds s, const void *t, size_t len);
229
+ sds sdscat(sds s, const char *t);
230
+ sds sdscatsds(sds s, const sds t);
231
+ sds sdscpylen(sds s, const char *t, size_t len);
232
+ sds sdscpy(sds s, const char *t);
233
+
234
+ sds sdscatvprintf(sds s, const char *fmt, va_list ap);
235
+ #ifdef __GNUC__
236
+ sds sdscatprintf(sds s, const char *fmt, ...)
237
+ __attribute__((format(printf, 2, 3)));
238
+ #else
239
+ sds sdscatprintf(sds s, const char *fmt, ...);
240
+ #endif
241
+
242
+ sds sdscatfmt(sds s, char const *fmt, ...);
243
+ sds sdstrim(sds s, const char *cset);
244
+ int sdsrange(sds s, ssize_t start, ssize_t end);
245
+ void sdsupdatelen(sds s);
246
+ void sdsclear(sds s);
247
+ int sdscmp(const sds s1, const sds s2);
248
+ sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
249
+ void sdsfreesplitres(sds *tokens, int count);
250
+ void sdstolower(sds s);
251
+ void sdstoupper(sds s);
252
+ sds sdsfromlonglong(long long value);
253
+ sds sdscatrepr(sds s, const char *p, size_t len);
254
+ sds *sdssplitargs(const char *line, int *argc);
255
+ sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
256
+ sds sdsjoin(char **argv, int argc, char *sep);
257
+ sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
258
+
259
+ /* Low level functions exposed to the user API */
260
+ sds sdsMakeRoomFor(sds s, size_t addlen);
261
+ void sdsIncrLen(sds s, int incr);
262
+ sds sdsRemoveFreeSpace(sds s);
263
+ size_t sdsAllocSize(sds s);
264
+ void *sdsAllocPtr(sds s);
265
+
266
+ /* Export the allocator used by SDS to the program using SDS.
267
+ * Sometimes the program SDS is linked to, may use a different set of
268
+ * allocators, but may want to allocate or free things that SDS will
269
+ * respectively free or allocate. */
270
+ void *sds_malloc(size_t size);
271
+ void *sds_realloc(void *ptr, size_t size);
272
+ void sds_free(void *ptr);
273
+
274
+ #ifdef REDIS_TEST
275
+ int sdsTest(int argc, char *argv[]);
276
+ #endif
277
+
278
+ #endif
@@ -0,0 +1,44 @@
1
+ /* SDSLib 2.0 -- A C dynamic strings library
2
+ *
3
+ * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
4
+ * Copyright (c) 2015, Oran Agra
5
+ * Copyright (c) 2015, Redis Labs, Inc
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright notice,
12
+ * this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ * * Neither the name of Redis nor the names of its contributors may be used
17
+ * to endorse or promote products derived from this software without
18
+ * specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+ /* SDS allocator selection.
34
+ *
35
+ * This file is used in order to change the SDS allocator at compile time.
36
+ * Just define the following defines to what you want to use. Also add
37
+ * the include of your alternate allocator if needed (not needed in order
38
+ * to use the default libc allocator). */
39
+
40
+ #include "alloc.h"
41
+
42
+ #define s_malloc hi_malloc
43
+ #define s_realloc hi_realloc
44
+ #define s_free hi_free
@@ -0,0 +1,248 @@
1
+ /*
2
+ * Copyright (c) 2019, Marcus Geelnard <m at bitsnbites dot eu>
3
+ *
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of Redis nor the names of its contributors may be used
15
+ * to endorse or promote products derived from this software without
16
+ * specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ * POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #define REDIS_SOCKCOMPAT_IMPLEMENTATION
32
+ #include "sockcompat.h"
33
+
34
+ #ifdef _WIN32
35
+ static int _wsaErrorToErrno(int err) {
36
+ switch (err) {
37
+ case WSAEWOULDBLOCK:
38
+ return EWOULDBLOCK;
39
+ case WSAEINPROGRESS:
40
+ return EINPROGRESS;
41
+ case WSAEALREADY:
42
+ return EALREADY;
43
+ case WSAENOTSOCK:
44
+ return ENOTSOCK;
45
+ case WSAEDESTADDRREQ:
46
+ return EDESTADDRREQ;
47
+ case WSAEMSGSIZE:
48
+ return EMSGSIZE;
49
+ case WSAEPROTOTYPE:
50
+ return EPROTOTYPE;
51
+ case WSAENOPROTOOPT:
52
+ return ENOPROTOOPT;
53
+ case WSAEPROTONOSUPPORT:
54
+ return EPROTONOSUPPORT;
55
+ case WSAEOPNOTSUPP:
56
+ return EOPNOTSUPP;
57
+ case WSAEAFNOSUPPORT:
58
+ return EAFNOSUPPORT;
59
+ case WSAEADDRINUSE:
60
+ return EADDRINUSE;
61
+ case WSAEADDRNOTAVAIL:
62
+ return EADDRNOTAVAIL;
63
+ case WSAENETDOWN:
64
+ return ENETDOWN;
65
+ case WSAENETUNREACH:
66
+ return ENETUNREACH;
67
+ case WSAENETRESET:
68
+ return ENETRESET;
69
+ case WSAECONNABORTED:
70
+ return ECONNABORTED;
71
+ case WSAECONNRESET:
72
+ return ECONNRESET;
73
+ case WSAENOBUFS:
74
+ return ENOBUFS;
75
+ case WSAEISCONN:
76
+ return EISCONN;
77
+ case WSAENOTCONN:
78
+ return ENOTCONN;
79
+ case WSAETIMEDOUT:
80
+ return ETIMEDOUT;
81
+ case WSAECONNREFUSED:
82
+ return ECONNREFUSED;
83
+ case WSAELOOP:
84
+ return ELOOP;
85
+ case WSAENAMETOOLONG:
86
+ return ENAMETOOLONG;
87
+ case WSAEHOSTUNREACH:
88
+ return EHOSTUNREACH;
89
+ case WSAENOTEMPTY:
90
+ return ENOTEMPTY;
91
+ default:
92
+ /* We just return a generic I/O error if we could not find a relevant error. */
93
+ return EIO;
94
+ }
95
+ }
96
+
97
+ static void _updateErrno(int success) {
98
+ errno = success ? 0 : _wsaErrorToErrno(WSAGetLastError());
99
+ }
100
+
101
+ static int _initWinsock() {
102
+ static int s_initialized = 0;
103
+ if (!s_initialized) {
104
+ static WSADATA wsadata;
105
+ int err = WSAStartup(MAKEWORD(2,2), &wsadata);
106
+ if (err != 0) {
107
+ errno = _wsaErrorToErrno(err);
108
+ return 0;
109
+ }
110
+ s_initialized = 1;
111
+ }
112
+ return 1;
113
+ }
114
+
115
+ int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
116
+ /* Note: This function is likely to be called before other functions, so run init here. */
117
+ if (!_initWinsock()) {
118
+ return EAI_FAIL;
119
+ }
120
+
121
+ switch (getaddrinfo(node, service, hints, res)) {
122
+ case 0: return 0;
123
+ case WSATRY_AGAIN: return EAI_AGAIN;
124
+ case WSAEINVAL: return EAI_BADFLAGS;
125
+ case WSAEAFNOSUPPORT: return EAI_FAMILY;
126
+ case WSA_NOT_ENOUGH_MEMORY: return EAI_MEMORY;
127
+ case WSAHOST_NOT_FOUND: return EAI_NONAME;
128
+ case WSATYPE_NOT_FOUND: return EAI_SERVICE;
129
+ case WSAESOCKTNOSUPPORT: return EAI_SOCKTYPE;
130
+ default: return EAI_FAIL; /* Including WSANO_RECOVERY */
131
+ }
132
+ }
133
+
134
+ const char *win32_gai_strerror(int errcode) {
135
+ switch (errcode) {
136
+ case 0: errcode = 0; break;
137
+ case EAI_AGAIN: errcode = WSATRY_AGAIN; break;
138
+ case EAI_BADFLAGS: errcode = WSAEINVAL; break;
139
+ case EAI_FAMILY: errcode = WSAEAFNOSUPPORT; break;
140
+ case EAI_MEMORY: errcode = WSA_NOT_ENOUGH_MEMORY; break;
141
+ case EAI_NONAME: errcode = WSAHOST_NOT_FOUND; break;
142
+ case EAI_SERVICE: errcode = WSATYPE_NOT_FOUND; break;
143
+ case EAI_SOCKTYPE: errcode = WSAESOCKTNOSUPPORT; break;
144
+ default: errcode = WSANO_RECOVERY; break; /* Including EAI_FAIL */
145
+ }
146
+ return gai_strerror(errcode);
147
+ }
148
+
149
+ void win32_freeaddrinfo(struct addrinfo *res) {
150
+ freeaddrinfo(res);
151
+ }
152
+
153
+ SOCKET win32_socket(int domain, int type, int protocol) {
154
+ SOCKET s;
155
+
156
+ /* Note: This function is likely to be called before other functions, so run init here. */
157
+ if (!_initWinsock()) {
158
+ return INVALID_SOCKET;
159
+ }
160
+
161
+ _updateErrno((s = socket(domain, type, protocol)) != INVALID_SOCKET);
162
+ return s;
163
+ }
164
+
165
+ int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp) {
166
+ int ret = ioctlsocket(fd, (long)request, argp);
167
+ _updateErrno(ret != SOCKET_ERROR);
168
+ return ret != SOCKET_ERROR ? ret : -1;
169
+ }
170
+
171
+ int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) {
172
+ int ret = bind(sockfd, addr, addrlen);
173
+ _updateErrno(ret != SOCKET_ERROR);
174
+ return ret != SOCKET_ERROR ? ret : -1;
175
+ }
176
+
177
+ int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) {
178
+ int ret = connect(sockfd, addr, addrlen);
179
+ _updateErrno(ret != SOCKET_ERROR);
180
+
181
+ /* For Winsock connect(), the WSAEWOULDBLOCK error means the same thing as
182
+ * EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX
183
+ * logic consistent. */
184
+ if (errno == EWOULDBLOCK) {
185
+ errno = EINPROGRESS;
186
+ }
187
+
188
+ return ret != SOCKET_ERROR ? ret : -1;
189
+ }
190
+
191
+ int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen) {
192
+ int ret = 0;
193
+ if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) {
194
+ if (*optlen >= sizeof (struct timeval)) {
195
+ struct timeval *tv = optval;
196
+ DWORD timeout = 0;
197
+ socklen_t dwlen = 0;
198
+ ret = getsockopt(sockfd, level, optname, (char *)&timeout, &dwlen);
199
+ tv->tv_sec = timeout / 1000;
200
+ tv->tv_usec = (timeout * 1000) % 1000000;
201
+ } else {
202
+ ret = WSAEFAULT;
203
+ }
204
+ *optlen = sizeof (struct timeval);
205
+ } else {
206
+ ret = getsockopt(sockfd, level, optname, (char*)optval, optlen);
207
+ }
208
+ _updateErrno(ret != SOCKET_ERROR);
209
+ return ret != SOCKET_ERROR ? ret : -1;
210
+ }
211
+
212
+ int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen) {
213
+ int ret = 0;
214
+ if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) {
215
+ const struct timeval *tv = optval;
216
+ DWORD timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
217
+ ret = setsockopt(sockfd, level, optname, (const char*)&timeout, sizeof(DWORD));
218
+ } else {
219
+ ret = setsockopt(sockfd, level, optname, (const char*)optval, optlen);
220
+ }
221
+ _updateErrno(ret != SOCKET_ERROR);
222
+ return ret != SOCKET_ERROR ? ret : -1;
223
+ }
224
+
225
+ int win32_close(SOCKET fd) {
226
+ int ret = closesocket(fd);
227
+ _updateErrno(ret != SOCKET_ERROR);
228
+ return ret != SOCKET_ERROR ? ret : -1;
229
+ }
230
+
231
+ ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags) {
232
+ int ret = recv(sockfd, (char*)buf, (int)len, flags);
233
+ _updateErrno(ret != SOCKET_ERROR);
234
+ return ret != SOCKET_ERROR ? ret : -1;
235
+ }
236
+
237
+ ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags) {
238
+ int ret = send(sockfd, (const char*)buf, (int)len, flags);
239
+ _updateErrno(ret != SOCKET_ERROR);
240
+ return ret != SOCKET_ERROR ? ret : -1;
241
+ }
242
+
243
+ int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
244
+ int ret = WSAPoll(fds, nfds, timeout);
245
+ _updateErrno(ret != SOCKET_ERROR);
246
+ return ret != SOCKET_ERROR ? ret : -1;
247
+ }
248
+ #endif /* _WIN32 */
@@ -0,0 +1,92 @@
1
+ /*
2
+ * Copyright (c) 2019, Marcus Geelnard <m at bitsnbites dot eu>
3
+ *
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of Redis nor the names of its contributors may be used
15
+ * to endorse or promote products derived from this software without
16
+ * specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ * POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #ifndef __SOCKCOMPAT_H
32
+ #define __SOCKCOMPAT_H
33
+
34
+ #ifndef _WIN32
35
+ /* For POSIX systems we use the standard BSD socket API. */
36
+ #include <unistd.h>
37
+ #include <sys/socket.h>
38
+ #include <sys/select.h>
39
+ #include <sys/un.h>
40
+ #include <netinet/in.h>
41
+ #include <netinet/tcp.h>
42
+ #include <arpa/inet.h>
43
+ #include <netdb.h>
44
+ #include <poll.h>
45
+ #else
46
+ /* For Windows we use winsock. */
47
+ #undef _WIN32_WINNT
48
+ #define _WIN32_WINNT 0x0600 /* To get WSAPoll etc. */
49
+ #include <winsock2.h>
50
+ #include <ws2tcpip.h>
51
+ #include <stddef.h>
52
+ #include <errno.h>
53
+
54
+ #ifdef _MSC_VER
55
+ typedef long long ssize_t;
56
+ #endif
57
+
58
+ /* Emulate the parts of the BSD socket API that we need (override the winsock signatures). */
59
+ int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
60
+ const char *win32_gai_strerror(int errcode);
61
+ void win32_freeaddrinfo(struct addrinfo *res);
62
+ SOCKET win32_socket(int domain, int type, int protocol);
63
+ int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp);
64
+ int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen);
65
+ int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen);
66
+ int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen);
67
+ int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen);
68
+ int win32_close(SOCKET fd);
69
+ ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags);
70
+ ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags);
71
+ typedef ULONG nfds_t;
72
+ int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout);
73
+
74
+ #ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION
75
+ #define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res)
76
+ #undef gai_strerror
77
+ #define gai_strerror(errcode) win32_gai_strerror(errcode)
78
+ #define freeaddrinfo(res) win32_freeaddrinfo(res)
79
+ #define socket(domain, type, protocol) win32_socket(domain, type, protocol)
80
+ #define ioctl(fd, request, argp) win32_ioctl(fd, request, argp)
81
+ #define bind(sockfd, addr, addrlen) win32_bind(sockfd, addr, addrlen)
82
+ #define connect(sockfd, addr, addrlen) win32_connect(sockfd, addr, addrlen)
83
+ #define getsockopt(sockfd, level, optname, optval, optlen) win32_getsockopt(sockfd, level, optname, optval, optlen)
84
+ #define setsockopt(sockfd, level, optname, optval, optlen) win32_setsockopt(sockfd, level, optname, optval, optlen)
85
+ #define close(fd) win32_close(fd)
86
+ #define recv(sockfd, buf, len, flags) win32_recv(sockfd, buf, len, flags)
87
+ #define send(sockfd, buf, len, flags) win32_send(sockfd, buf, len, flags)
88
+ #define poll(fds, nfds, timeout) win32_poll(fds, nfds, timeout)
89
+ #endif /* REDIS_SOCKCOMPAT_IMPLEMENTATION */
90
+ #endif /* _WIN32 */
91
+
92
+ #endif /* __SOCKCOMPAT_H */