threadsafe-hiredis 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,210 +0,0 @@
1
- /*
2
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
3
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
4
- *
5
- * All rights reserved.
6
- *
7
- * Redistribution and use in source and binary forms, with or without
8
- * modification, are permitted provided that the following conditions are met:
9
- *
10
- * * Redistributions of source code must retain the above copyright notice,
11
- * this list of conditions and the following disclaimer.
12
- * * Redistributions in binary form must reproduce the above copyright
13
- * notice, this list of conditions and the following disclaimer in the
14
- * documentation and/or other materials provided with the distribution.
15
- * * Neither the name of Redis nor the names of its contributors may be used
16
- * to endorse or promote products derived from this software without
17
- * specific prior written permission.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
- * POSSIBILITY OF SUCH DAMAGE.
30
- */
31
-
32
- #ifndef __HIREDIS_H
33
- #define __HIREDIS_H
34
- #include <stdio.h> /* for size_t */
35
- #include <stdarg.h> /* for va_list */
36
- #include <sys/time.h> /* for struct timeval */
37
-
38
- #define HIREDIS_MAJOR 0
39
- #define HIREDIS_MINOR 11
40
- #define HIREDIS_PATCH 0
41
-
42
- #define REDIS_ERR -1
43
- #define REDIS_OK 0
44
-
45
- /* When an error occurs, the err flag in a context is set to hold the type of
46
- * error that occured. REDIS_ERR_IO means there was an I/O error and you
47
- * should use the "errno" variable to find out what is wrong.
48
- * For other values, the "errstr" field will hold a description. */
49
- #define REDIS_ERR_IO 1 /* Error in read or write */
50
- #define REDIS_ERR_EOF 3 /* End of file */
51
- #define REDIS_ERR_PROTOCOL 4 /* Protocol error */
52
- #define REDIS_ERR_OOM 5 /* Out of memory */
53
- #define REDIS_ERR_OTHER 2 /* Everything else... */
54
-
55
- /* Connection type can be blocking or non-blocking and is set in the
56
- * least significant bit of the flags field in redisContext. */
57
- #define REDIS_BLOCK 0x1
58
-
59
- /* Connection may be disconnected before being free'd. The second bit
60
- * in the flags field is set when the context is connected. */
61
- #define REDIS_CONNECTED 0x2
62
-
63
- /* The async API might try to disconnect cleanly and flush the output
64
- * buffer and read all subsequent replies before disconnecting.
65
- * This flag means no new commands can come in and the connection
66
- * should be terminated once all replies have been read. */
67
- #define REDIS_DISCONNECTING 0x4
68
-
69
- /* Flag specific to the async API which means that the context should be clean
70
- * up as soon as possible. */
71
- #define REDIS_FREEING 0x8
72
-
73
- /* Flag that is set when an async callback is executed. */
74
- #define REDIS_IN_CALLBACK 0x10
75
-
76
- /* Flag that is set when the async context has one or more subscriptions. */
77
- #define REDIS_SUBSCRIBED 0x20
78
-
79
- /* Flag that is set when monitor mode is active */
80
- #define REDIS_MONITORING 0x40
81
-
82
- #define REDIS_REPLY_STRING 1
83
- #define REDIS_REPLY_ARRAY 2
84
- #define REDIS_REPLY_INTEGER 3
85
- #define REDIS_REPLY_NIL 4
86
- #define REDIS_REPLY_STATUS 5
87
- #define REDIS_REPLY_ERROR 6
88
-
89
- #define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */
90
-
91
- #ifdef __cplusplus
92
- extern "C" {
93
- #endif
94
-
95
- /* This is the reply object returned by redisCommand() */
96
- typedef struct redisReply {
97
- int type; /* REDIS_REPLY_* */
98
- long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
99
- int len; /* Length of string */
100
- char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
101
- size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
102
- struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
103
- } redisReply;
104
-
105
- typedef struct redisReadTask {
106
- int type;
107
- int elements; /* number of elements in multibulk container */
108
- int idx; /* index in parent (array) object */
109
- void *obj; /* holds user-generated value for a read task */
110
- struct redisReadTask *parent; /* parent task */
111
- void *privdata; /* user-settable arbitrary field */
112
- } redisReadTask;
113
-
114
- typedef struct redisReplyObjectFunctions {
115
- void *(*createString)(const redisReadTask*, char*, size_t);
116
- void *(*createArray)(const redisReadTask*, int);
117
- void *(*createInteger)(const redisReadTask*, long long);
118
- void *(*createNil)(const redisReadTask*);
119
- void (*freeObject)(void*);
120
- } redisReplyObjectFunctions;
121
-
122
- /* State for the protocol parser */
123
- typedef struct redisReader {
124
- int err; /* Error flags, 0 when there is no error */
125
- char errstr[128]; /* String representation of error when applicable */
126
-
127
- char *buf; /* Read buffer */
128
- size_t pos; /* Buffer cursor */
129
- size_t len; /* Buffer length */
130
- size_t maxbuf; /* Max length of unused buffer */
131
-
132
- redisReadTask rstack[9];
133
- int ridx; /* Index of current read task */
134
- void *reply; /* Temporary reply pointer */
135
-
136
- redisReplyObjectFunctions *fn;
137
- void *privdata;
138
- } redisReader;
139
-
140
- /* Public API for the protocol parser. */
141
- redisReader *redisReaderCreate(void);
142
- void redisReaderFree(redisReader *r);
143
- int redisReaderFeed(redisReader *r, const char *buf, size_t len);
144
- int redisReaderGetReply(redisReader *r, void **reply);
145
-
146
- /* Backwards compatibility, can be removed on big version bump. */
147
- #define redisReplyReaderCreate redisReaderCreate
148
- #define redisReplyReaderFree redisReaderFree
149
- #define redisReplyReaderFeed redisReaderFeed
150
- #define redisReplyReaderGetReply redisReaderGetReply
151
- #define redisReplyReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p))
152
- #define redisReplyReaderGetObject(_r) (((redisReader*)(_r))->reply)
153
- #define redisReplyReaderGetError(_r) (((redisReader*)(_r))->errstr)
154
-
155
- /* Function to free the reply objects hiredis returns by default. */
156
- void freeReplyObject(void *reply);
157
-
158
- /* Functions to format a command according to the protocol. */
159
- int redisvFormatCommand(char **target, const char *format, va_list ap);
160
- int redisFormatCommand(char **target, const char *format, ...);
161
- int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
162
-
163
- /* Context for a connection to Redis */
164
- typedef struct redisContext {
165
- int err; /* Error flags, 0 when there is no error */
166
- char errstr[128]; /* String representation of error when applicable */
167
- int fd;
168
- int flags;
169
- char *obuf; /* Write buffer */
170
- redisReader *reader; /* Protocol reader */
171
- } redisContext;
172
-
173
- redisContext *redisConnect(const char *ip, int port);
174
- redisContext *redisConnectWithTimeout(const char *ip, int port, struct timeval tv);
175
- redisContext *redisConnectNonBlock(const char *ip, int port);
176
- redisContext *redisConnectUnix(const char *path);
177
- redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv);
178
- redisContext *redisConnectUnixNonBlock(const char *path);
179
- int redisSetTimeout(redisContext *c, struct timeval tv);
180
- void redisFree(redisContext *c);
181
- int redisBufferRead(redisContext *c);
182
- int redisBufferWrite(redisContext *c, int *done);
183
-
184
- /* In a blocking context, this function first checks if there are unconsumed
185
- * replies to return and returns one if so. Otherwise, it flushes the output
186
- * buffer to the socket and reads until it has a reply. In a non-blocking
187
- * context, it will return unconsumed replies until there are no more. */
188
- int redisGetReply(redisContext *c, void **reply);
189
- int redisGetReplyFromReader(redisContext *c, void **reply);
190
-
191
- /* Write a command to the output buffer. Use these functions in blocking mode
192
- * to get a pipeline of commands. */
193
- int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
194
- int redisAppendCommand(redisContext *c, const char *format, ...);
195
- int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
196
-
197
- /* Issue a command to Redis. In a blocking context, it is identical to calling
198
- * redisAppendCommand, followed by redisGetReply. The function will return
199
- * NULL if there was an error in performing the request, otherwise it will
200
- * return the reply. In a non-blocking context, it is identical to calling
201
- * only redisAppendCommand and will always return NULL. */
202
- void *redisvCommand(redisContext *c, const char *format, va_list ap);
203
- void *redisCommand(redisContext *c, const char *format, ...);
204
- void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
205
-
206
- #ifdef __cplusplus
207
- }
208
- #endif
209
-
210
- #endif
data/vendor/hiredis/net.c DELETED
@@ -1,291 +0,0 @@
1
- /* Extracted from anet.c to work properly with Hiredis error reporting.
2
- *
3
- * Copyright (c) 2006-2011, Salvatore Sanfilippo <antirez at gmail dot com>
4
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
5
- *
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
- #include "fmacros.h"
34
- #include <sys/types.h>
35
- #include <sys/socket.h>
36
- #include <sys/select.h>
37
- #include <sys/un.h>
38
- #include <netinet/in.h>
39
- #include <netinet/tcp.h>
40
- #include <arpa/inet.h>
41
- #include <unistd.h>
42
- #include <fcntl.h>
43
- #include <string.h>
44
- #include <netdb.h>
45
- #include <errno.h>
46
- #include <stdarg.h>
47
- #include <stdio.h>
48
- #include <poll.h>
49
- #include <limits.h>
50
-
51
- #include "net.h"
52
- #include "sds.h"
53
-
54
- /* Defined in hiredis.c */
55
- void __redisSetError(redisContext *c, int type, const char *str);
56
-
57
- static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) {
58
- char buf[128];
59
- size_t len = 0;
60
-
61
- if (prefix != NULL)
62
- len = snprintf(buf,sizeof(buf),"%s: ",prefix);
63
- strerror_r(errno,buf+len,sizeof(buf)-len);
64
- __redisSetError(c,type,buf);
65
- }
66
-
67
- static int redisSetReuseAddr(redisContext *c, int fd) {
68
- int on = 1;
69
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
70
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
71
- close(fd);
72
- return REDIS_ERR;
73
- }
74
- return REDIS_OK;
75
- }
76
-
77
- static int redisCreateSocket(redisContext *c, int type) {
78
- int s;
79
- if ((s = socket(type, SOCK_STREAM, 0)) == -1) {
80
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
81
- return REDIS_ERR;
82
- }
83
- if (type == AF_INET) {
84
- if (redisSetReuseAddr(c,s) == REDIS_ERR) {
85
- return REDIS_ERR;
86
- }
87
- }
88
- return s;
89
- }
90
-
91
- static int redisSetBlocking(redisContext *c, int fd, int blocking) {
92
- int flags;
93
-
94
- /* Set the socket nonblocking.
95
- * Note that fcntl(2) for F_GETFL and F_SETFL can't be
96
- * interrupted by a signal. */
97
- if ((flags = fcntl(fd, F_GETFL)) == -1) {
98
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
99
- close(fd);
100
- return REDIS_ERR;
101
- }
102
-
103
- if (blocking)
104
- flags &= ~O_NONBLOCK;
105
- else
106
- flags |= O_NONBLOCK;
107
-
108
- if (fcntl(fd, F_SETFL, flags) == -1) {
109
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
110
- close(fd);
111
- return REDIS_ERR;
112
- }
113
- return REDIS_OK;
114
- }
115
-
116
- static int redisSetTcpNoDelay(redisContext *c, int fd) {
117
- int yes = 1;
118
- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
119
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
120
- close(fd);
121
- return REDIS_ERR;
122
- }
123
- return REDIS_OK;
124
- }
125
-
126
- #define __MAX_MSEC (((LONG_MAX) - 999) / 1000)
127
-
128
- static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *timeout) {
129
- struct pollfd wfd[1];
130
- long msec;
131
-
132
- msec = -1;
133
- wfd[0].fd = fd;
134
- wfd[0].events = POLLOUT;
135
-
136
- /* Only use timeout when not NULL. */
137
- if (timeout != NULL) {
138
- if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
139
- close(fd);
140
- return REDIS_ERR;
141
- }
142
-
143
- msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);
144
-
145
- if (msec < 0 || msec > INT_MAX) {
146
- msec = INT_MAX;
147
- }
148
- }
149
-
150
- if (errno == EINPROGRESS) {
151
- int res;
152
-
153
- if ((res = poll(wfd, 1, msec)) == -1) {
154
- __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
155
- close(fd);
156
- return REDIS_ERR;
157
- } else if (res == 0) {
158
- errno = ETIMEDOUT;
159
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
160
- close(fd);
161
- return REDIS_ERR;
162
- }
163
-
164
- if (redisCheckSocketError(c, fd) != REDIS_OK)
165
- return REDIS_ERR;
166
-
167
- return REDIS_OK;
168
- }
169
-
170
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
171
- close(fd);
172
- return REDIS_ERR;
173
- }
174
-
175
- int redisCheckSocketError(redisContext *c, int fd) {
176
- int err = 0;
177
- socklen_t errlen = sizeof(err);
178
-
179
- if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
180
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
181
- close(fd);
182
- return REDIS_ERR;
183
- }
184
-
185
- if (err) {
186
- errno = err;
187
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
188
- close(fd);
189
- return REDIS_ERR;
190
- }
191
-
192
- return REDIS_OK;
193
- }
194
-
195
- int redisContextSetTimeout(redisContext *c, struct timeval tv) {
196
- if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) {
197
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)");
198
- return REDIS_ERR;
199
- }
200
- if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,&tv,sizeof(tv)) == -1) {
201
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)");
202
- return REDIS_ERR;
203
- }
204
- return REDIS_OK;
205
- }
206
-
207
- int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout) {
208
- int s, rv;
209
- char _port[6]; /* strlen("65535"); */
210
- struct addrinfo hints, *servinfo, *p;
211
- int blocking = (c->flags & REDIS_BLOCK);
212
-
213
- snprintf(_port, 6, "%d", port);
214
- memset(&hints,0,sizeof(hints));
215
- hints.ai_family = AF_INET;
216
- hints.ai_socktype = SOCK_STREAM;
217
-
218
- if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
219
- __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv));
220
- return REDIS_ERR;
221
- }
222
- for (p = servinfo; p != NULL; p = p->ai_next) {
223
- if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
224
- continue;
225
-
226
- if (redisSetBlocking(c,s,0) != REDIS_OK)
227
- goto error;
228
- if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
229
- if (errno == EHOSTUNREACH) {
230
- close(s);
231
- continue;
232
- } else if (errno == EINPROGRESS && !blocking) {
233
- /* This is ok. */
234
- } else {
235
- if (redisContextWaitReady(c,s,timeout) != REDIS_OK)
236
- goto error;
237
- }
238
- }
239
- if (blocking && redisSetBlocking(c,s,1) != REDIS_OK)
240
- goto error;
241
- if (redisSetTcpNoDelay(c,s) != REDIS_OK)
242
- goto error;
243
-
244
- c->fd = s;
245
- c->flags |= REDIS_CONNECTED;
246
- rv = REDIS_OK;
247
- goto end;
248
- }
249
- if (p == NULL) {
250
- char buf[128];
251
- snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno));
252
- __redisSetError(c,REDIS_ERR_OTHER,buf);
253
- goto error;
254
- }
255
-
256
- error:
257
- rv = REDIS_ERR;
258
- end:
259
- freeaddrinfo(servinfo);
260
- return rv; // Need to return REDIS_OK if alright
261
- }
262
-
263
- int redisContextConnectUnix(redisContext *c, const char *path, struct timeval *timeout) {
264
- int s;
265
- int blocking = (c->flags & REDIS_BLOCK);
266
- struct sockaddr_un sa;
267
-
268
- if ((s = redisCreateSocket(c,AF_LOCAL)) < 0)
269
- return REDIS_ERR;
270
- if (redisSetBlocking(c,s,0) != REDIS_OK)
271
- return REDIS_ERR;
272
-
273
- sa.sun_family = AF_LOCAL;
274
- strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
275
- if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
276
- if (errno == EINPROGRESS && !blocking) {
277
- /* This is ok. */
278
- } else {
279
- if (redisContextWaitReady(c,s,timeout) != REDIS_OK)
280
- return REDIS_ERR;
281
- }
282
- }
283
-
284
- /* Reset socket to be blocking after connect(2). */
285
- if (blocking && redisSetBlocking(c,s,1) != REDIS_OK)
286
- return REDIS_ERR;
287
-
288
- c->fd = s;
289
- c->flags |= REDIS_CONNECTED;
290
- return REDIS_OK;
291
- }