hiredis 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d1cce35760d2be25e5029aa935a2613e7cc8ee1
4
- data.tar.gz: c751c54fafa5c215e85731863f90a2de17c3d475
3
+ metadata.gz: cd797dc2c633e7e0702618c9e07953f6524d36c4
4
+ data.tar.gz: dfb5c9321d4e0f726bbbc68f2d58e3b893d967d7
5
5
  SHA512:
6
- metadata.gz: 703badbbec006e2e0f2c243f0cfc8baac8f4d36f654b20d7f20b1ff8c0abcb687ea26f5c062f7c211b865cfdab4b41ac3c4949cf6c0843d927b7491ba1b80f32
7
- data.tar.gz: 3fbbc47a99d8bfba0be19ba98bc10c238034e892956844a349f862806593e59c67fcd5da1143262bab66eb92385789d75ad43c7a447b47edd1c3d0d6aa113d31
6
+ metadata.gz: b338f43933ee66c000ba6180baceee528ccc5f86228af6a7aef780ab22ef9303929ec27185af10f800625301226ca9b4fd4b40da66b249904b173767b20e4d6b
7
+ data.tar.gz: 9fa9da86808f554aec490d41d4205588ac6780d93b1476bf4d626184391c892dab3783fb0d0a1319ee912e1a822e7f2515182cc0aeadcda8eaeecb53a2293f64
@@ -1,3 +1,3 @@
1
1
  module Hiredis
2
- VERSION = "0.5.2"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -3,12 +3,36 @@
3
3
  # Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis at gmail dot com>
4
4
  # This file is released under the BSD license, see the COPYING file
5
5
 
6
- OBJ=net.o hiredis.o sds.o async.o
7
- BINS=hiredis-example hiredis-test
6
+ OBJ=net.o hiredis.o sds.o async.o read.o
7
+ EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
8
+ TESTS=hiredis-test
8
9
  LIBNAME=libhiredis
10
+ PKGCONFNAME=hiredis.pc
9
11
 
10
- HIREDIS_MAJOR=0
11
- HIREDIS_MINOR=10
12
+ HIREDIS_MAJOR=$(shell grep HIREDIS_MAJOR hiredis.h | awk '{print $$3}')
13
+ HIREDIS_MINOR=$(shell grep HIREDIS_MINOR hiredis.h | awk '{print $$3}')
14
+ HIREDIS_PATCH=$(shell grep HIREDIS_PATCH hiredis.h | awk '{print $$3}')
15
+
16
+ # Installation related variables and target
17
+ PREFIX?=/usr/local
18
+ INCLUDE_PATH?=include/hiredis
19
+ LIBRARY_PATH?=lib
20
+ PKGCONF_PATH?=pkgconfig
21
+ INSTALL_INCLUDE_PATH= $(PREFIX)/$(INCLUDE_PATH)
22
+ INSTALL_LIBRARY_PATH= $(PREFIX)/$(LIBRARY_PATH)
23
+ INSTALL_PKGCONF_PATH= $(LIBRARY_PATH)/$(PKGCONF_PATH)
24
+
25
+ # redis-server configuration used for testing
26
+ REDIS_PORT=56379
27
+ REDIS_SERVER=redis-server
28
+ define REDIS_TEST_CONFIG
29
+ daemonize yes
30
+ pidfile /tmp/hiredis-test-redis.pid
31
+ port $(REDIS_PORT)
32
+ bind 127.0.0.1
33
+ unixsocket /tmp/hiredis-test-redis.sock
34
+ endef
35
+ export REDIS_TEST_CONFIG
12
36
 
13
37
  # Fallback to gcc when $CC is not in $PATH.
14
38
  CC:=$(shell sh -c 'type $(CC) >/dev/null 2>/dev/null && echo $(CC) || echo gcc')
@@ -41,15 +65,16 @@ ifeq ($(uname_S),Darwin)
41
65
  DYLIB_MAKE_CMD=$(CC) -shared -Wl,-install_name,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
42
66
  endif
43
67
 
44
- all: $(DYLIBNAME) $(BINS)
68
+ all: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
45
69
 
46
70
  # Deps (use make dep to generate this)
47
- net.o: net.c fmacros.h net.h hiredis.h
48
- async.o: async.c async.h hiredis.h sds.h dict.c dict.h
49
- example.o: example.c hiredis.h
50
- hiredis.o: hiredis.c fmacros.h hiredis.h net.h sds.h
71
+ async.o: async.c fmacros.h async.h hiredis.h read.h sds.h net.h dict.c dict.h
72
+ dict.o: dict.c fmacros.h dict.h
73
+ hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h net.h
74
+ net.o: net.c fmacros.h net.h hiredis.h read.h sds.h
75
+ read.o: read.c fmacros.h read.h sds.h
51
76
  sds.o: sds.c sds.h
52
- test.o: test.c hiredis.h
77
+ test.o: test.c fmacros.h hiredis.h read.h sds.h
53
78
 
54
79
  $(DYLIBNAME): $(OBJ)
55
80
  $(DYLIB_MAKE_CMD) $(OBJ)
@@ -61,21 +86,40 @@ dynamic: $(DYLIBNAME)
61
86
  static: $(STLIBNAME)
62
87
 
63
88
  # Binaries:
64
- hiredis-example-libevent: example-libevent.c adapters/libevent.h $(STLIBNAME)
65
- $(CC) -o $@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -levent example-libevent.c $(STLIBNAME)
89
+ hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME)
90
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -levent $(STLIBNAME)
91
+
92
+ hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME)
93
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -lev $(STLIBNAME)
66
94
 
67
- hiredis-example-libev: example-libev.c adapters/libev.h $(STLIBNAME)
68
- $(CC) -o $@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -lev example-libev.c $(STLIBNAME)
95
+ hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME)
96
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) $(shell pkg-config --cflags --libs glib-2.0) -I. $< $(STLIBNAME)
69
97
 
70
98
  ifndef AE_DIR
71
99
  hiredis-example-ae:
72
100
  @echo "Please specify AE_DIR (e.g. <redis repository>/src)"
73
101
  @false
74
102
  else
75
- hiredis-example-ae: example-ae.c adapters/ae.h $(STLIBNAME)
76
- $(CC) -o $@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I$(AE_DIR) $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o example-ae.c $(STLIBNAME)
103
+ hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME)
104
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(AE_DIR) $< $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o $(AE_DIR)/../deps/jemalloc/lib/libjemalloc.a -pthread $(STLIBNAME)
105
+ endif
106
+
107
+ ifndef LIBUV_DIR
108
+ hiredis-example-libuv:
109
+ @echo "Please specify LIBUV_DIR (e.g. ../libuv/)"
110
+ @false
111
+ else
112
+ hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME)
113
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread $(STLIBNAME)
77
114
  endif
78
115
 
116
+ hiredis-example: examples/example.c $(STLIBNAME)
117
+ $(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< $(STLIBNAME)
118
+
119
+ examples: $(EXAMPLES)
120
+
121
+ hiredis-test: test.o $(STLIBNAME)
122
+
79
123
  hiredis-%: %.o $(STLIBNAME)
80
124
  $(CC) -o $@ $(REAL_LDFLAGS) $< $(STLIBNAME)
81
125
 
@@ -83,14 +127,8 @@ test: hiredis-test
83
127
  ./hiredis-test
84
128
 
85
129
  check: hiredis-test
86
- echo \
87
- "daemonize yes\n" \
88
- "pidfile /tmp/hiredis-test-redis.pid\n" \
89
- "port 56379\n" \
90
- "bind 127.0.0.1\n" \
91
- "unixsocket /tmp/hiredis-test-redis.sock" \
92
- | redis-server -
93
- ./hiredis-test -h 127.0.0.1 -p 56379 -s /tmp/hiredis-test-redis.sock || \
130
+ @echo "$$REDIS_TEST_CONFIG" | $(REDIS_SERVER) -
131
+ $(PRE) ./hiredis-test -h 127.0.0.1 -p $(REDIS_PORT) -s /tmp/hiredis-test-redis.sock || \
94
132
  ( kill `cat /tmp/hiredis-test-redis.pid` && false )
95
133
  kill `cat /tmp/hiredis-test-redis.pid`
96
134
 
@@ -98,24 +136,30 @@ check: hiredis-test
98
136
  $(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $<
99
137
 
100
138
  clean:
101
- rm -rf $(DYLIBNAME) $(STLIBNAME) $(BINS) hiredis-example* *.o *.gcda *.gcno *.gcov
139
+ rm -rf $(DYLIBNAME) $(STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov
102
140
 
103
141
  dep:
104
142
  $(CC) -MM *.c
105
143
 
106
- # Installation related variables and target
107
- PREFIX?=/usr/local
108
- INCLUDE_PATH?=include/hiredis
109
- LIBRARY_PATH?=lib
110
- INSTALL_INCLUDE_PATH= $(PREFIX)/$(INCLUDE_PATH)
111
- INSTALL_LIBRARY_PATH= $(PREFIX)/$(LIBRARY_PATH)
112
-
113
144
  ifeq ($(uname_S),SunOS)
114
145
  INSTALL?= cp -r
115
146
  endif
116
147
 
117
148
  INSTALL?= cp -a
118
149
 
150
+ $(PKGCONFNAME): $(PKGCONF_SRCNAME)
151
+ @echo "Generating $@ for pkgconfig..."
152
+ @echo prefix=$(PREFIX) > $@
153
+ @echo exec_prefix=$${prefix} >> $@
154
+ @echo libdir=$(INSTALL_LIBRARY_PATH) >> $@
155
+ @echo includedir=$(INSTALL_INCLUDE_PATH) >> $@
156
+ @echo >> $@
157
+ @echo Name: hiredis >> $@
158
+ @echo Description: Minimalistic C client library for the Redis database. >> $@
159
+ @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@
160
+ @echo Libs: -L$${libdir} -lhiredis >> $@
161
+ @echo Cflags: -I$${includedir} -D_FILE_OFFSET_BITS=64 >> $@
162
+
119
163
  install: $(DYLIBNAME) $(STLIBNAME)
120
164
  mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH)
121
165
  $(INSTALL) hiredis.h async.h adapters $(INSTALL_INCLUDE_PATH)
@@ -123,6 +167,8 @@ install: $(DYLIBNAME) $(STLIBNAME)
123
167
  cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIB_MAJOR_NAME)
124
168
  cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MAJOR_NAME) $(DYLIBNAME)
125
169
  $(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH)
170
+ mkdir -p $(INSTALL_PKGCONF_PATH)
171
+ $(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH)
126
172
 
127
173
  32bit:
128
174
  @echo ""
@@ -58,11 +58,12 @@
58
58
  } while(0);
59
59
 
60
60
  /* Forward declaration of function in hiredis.c */
61
- void __redisAppendCommand(redisContext *c, char *cmd, size_t len);
61
+ int __redisAppendCommand(redisContext *c, const char *cmd, size_t len);
62
62
 
63
63
  /* Functions managing dictionary of callbacks for pub/sub. */
64
64
  static unsigned int callbackHash(const void *key) {
65
- return dictGenHashFunction((unsigned char*)key,sdslen((char*)key));
65
+ return dictGenHashFunction((const unsigned char *)key,
66
+ sdslen((const sds)key));
66
67
  }
67
68
 
68
69
  static void *callbackValDup(void *privdata, const void *src) {
@@ -76,8 +77,8 @@ static int callbackKeyCompare(void *privdata, const void *key1, const void *key2
76
77
  int l1, l2;
77
78
  ((void) privdata);
78
79
 
79
- l1 = sdslen((sds)key1);
80
- l2 = sdslen((sds)key2);
80
+ l1 = sdslen((const sds)key1);
81
+ l2 = sdslen((const sds)key2);
81
82
  if (l1 != l2) return 0;
82
83
  return memcmp(key1,key2,l1) == 0;
83
84
  }
@@ -102,7 +103,12 @@ static dictType callbackDict = {
102
103
  };
103
104
 
104
105
  static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
105
- redisAsyncContext *ac = realloc(c,sizeof(redisAsyncContext));
106
+ redisAsyncContext *ac;
107
+
108
+ ac = realloc(c,sizeof(redisAsyncContext));
109
+ if (ac == NULL)
110
+ return NULL;
111
+
106
112
  c = &(ac->c);
107
113
 
108
114
  /* The regular connect functions will always set the flag REDIS_CONNECTED.
@@ -136,25 +142,66 @@ static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
136
142
  /* We want the error field to be accessible directly instead of requiring
137
143
  * an indirection to the redisContext struct. */
138
144
  static void __redisAsyncCopyError(redisAsyncContext *ac) {
145
+ if (!ac)
146
+ return;
147
+
139
148
  redisContext *c = &(ac->c);
140
149
  ac->err = c->err;
141
150
  ac->errstr = c->errstr;
142
151
  }
143
152
 
144
153
  redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
145
- redisContext *c = redisConnectNonBlock(ip,port);
154
+ redisContext *c;
155
+ redisAsyncContext *ac;
156
+
157
+ c = redisConnectNonBlock(ip,port);
158
+ if (c == NULL)
159
+ return NULL;
160
+
161
+ ac = redisAsyncInitialize(c);
162
+ if (ac == NULL) {
163
+ redisFree(c);
164
+ return NULL;
165
+ }
166
+
167
+ __redisAsyncCopyError(ac);
168
+ return ac;
169
+ }
170
+
171
+ redisAsyncContext *redisAsyncConnectBind(const char *ip, int port,
172
+ const char *source_addr) {
173
+ redisContext *c = redisConnectBindNonBlock(ip,port,source_addr);
146
174
  redisAsyncContext *ac = redisAsyncInitialize(c);
147
175
  __redisAsyncCopyError(ac);
148
176
  return ac;
149
177
  }
150
178
 
151
- redisAsyncContext *redisAsyncConnectUnix(const char *path) {
152
- redisContext *c = redisConnectUnixNonBlock(path);
179
+ redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
180
+ const char *source_addr) {
181
+ redisContext *c = redisConnectBindNonBlockWithReuse(ip,port,source_addr);
153
182
  redisAsyncContext *ac = redisAsyncInitialize(c);
154
183
  __redisAsyncCopyError(ac);
155
184
  return ac;
156
185
  }
157
186
 
187
+ redisAsyncContext *redisAsyncConnectUnix(const char *path) {
188
+ redisContext *c;
189
+ redisAsyncContext *ac;
190
+
191
+ c = redisConnectUnixNonBlock(path);
192
+ if (c == NULL)
193
+ return NULL;
194
+
195
+ ac = redisAsyncInitialize(c);
196
+ if (ac == NULL) {
197
+ redisFree(c);
198
+ return NULL;
199
+ }
200
+
201
+ __redisAsyncCopyError(ac);
202
+ return ac;
203
+ }
204
+
158
205
  int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) {
159
206
  if (ac->onConnect == NULL) {
160
207
  ac->onConnect = fn;
@@ -182,6 +229,9 @@ static int __redisPushCallback(redisCallbackList *list, redisCallback *source) {
182
229
 
183
230
  /* Copy callback from stack to heap */
184
231
  cb = malloc(sizeof(*cb));
232
+ if (cb == NULL)
233
+ return REDIS_ERR_OOM;
234
+
185
235
  if (source != NULL) {
186
236
  memcpy(cb,source,sizeof(*cb));
187
237
  cb->next = NULL;
@@ -360,7 +410,7 @@ static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply,
360
410
 
361
411
  void redisProcessCallbacks(redisAsyncContext *ac) {
362
412
  redisContext *c = &(ac->c);
363
- redisCallback cb;
413
+ redisCallback cb = {NULL, NULL, NULL};
364
414
  void *reply = NULL;
365
415
  int status;
366
416
 
@@ -372,7 +422,7 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
372
422
  __redisAsyncDisconnect(ac);
373
423
  return;
374
424
  }
375
-
425
+
376
426
  /* If monitor mode, repush callback */
377
427
  if(c->flags & REDIS_MONITORING) {
378
428
  __redisPushCallback(&ac->replies,&cb);
@@ -442,7 +492,7 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
442
492
  static int __redisAsyncHandleConnect(redisAsyncContext *ac) {
443
493
  redisContext *c = &(ac->c);
444
494
 
445
- if (redisCheckSocketError(c,c->fd) == REDIS_ERR) {
495
+ if (redisCheckSocketError(c) == REDIS_ERR) {
446
496
  /* Try again later when connect(2) is still in progress. */
447
497
  if (errno == EINPROGRESS)
448
498
  return REDIS_OK;
@@ -511,8 +561,8 @@ void redisAsyncHandleWrite(redisAsyncContext *ac) {
511
561
 
512
562
  /* Sets a pointer to the first argument and its length starting at p. Returns
513
563
  * the number of bytes to skip to get to the following argument. */
514
- static char *nextArgument(char *start, char **str, size_t *len) {
515
- char *p = start;
564
+ static const char *nextArgument(const char *start, const char **str, size_t *len) {
565
+ const char *p = start;
516
566
  if (p[0] != '$') {
517
567
  p = strchr(p,'$');
518
568
  if (p == NULL) return NULL;
@@ -528,14 +578,15 @@ static char *nextArgument(char *start, char **str, size_t *len) {
528
578
  /* Helper function for the redisAsyncCommand* family of functions. Writes a
529
579
  * formatted command to the output buffer and registers the provided callback
530
580
  * function with the context. */
531
- static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, char *cmd, size_t len) {
581
+ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) {
532
582
  redisContext *c = &(ac->c);
533
583
  redisCallback cb;
534
584
  int pvariant, hasnext;
535
- char *cstr, *astr;
585
+ const char *cstr, *astr;
536
586
  size_t clen, alen;
537
- char *p;
587
+ const char *p;
538
588
  sds sname;
589
+ int ret;
539
590
 
540
591
  /* Don't accept new commands when the connection is about to be closed. */
541
592
  if (c->flags & (REDIS_DISCONNECTING | REDIS_FREEING)) return REDIS_ERR;
@@ -559,9 +610,11 @@ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void
559
610
  while ((p = nextArgument(p,&astr,&alen)) != NULL) {
560
611
  sname = sdsnewlen(astr,alen);
561
612
  if (pvariant)
562
- dictReplace(ac->sub.patterns,sname,&cb);
613
+ ret = dictReplace(ac->sub.patterns,sname,&cb);
563
614
  else
564
- dictReplace(ac->sub.channels,sname,&cb);
615
+ ret = dictReplace(ac->sub.channels,sname,&cb);
616
+
617
+ if (ret == 0) sdsfree(sname);
565
618
  }
566
619
  } else if (strncasecmp(cstr,"unsubscribe\r\n",13) == 0) {
567
620
  /* It is only useful to call (P)UNSUBSCRIBE when the context is
@@ -597,6 +650,11 @@ int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdat
597
650
  int len;
598
651
  int status;
599
652
  len = redisvFormatCommand(&cmd,format,ap);
653
+
654
+ /* We don't want to pass -1 or -2 to future functions as a length. */
655
+ if (len < 0)
656
+ return REDIS_ERR;
657
+
600
658
  status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
601
659
  free(cmd);
602
660
  return status;
@@ -612,11 +670,16 @@ int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata
612
670
  }
613
671
 
614
672
  int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) {
615
- char *cmd;
673
+ sds cmd;
616
674
  int len;
617
675
  int status;
618
- len = redisFormatCommandArgv(&cmd,argc,argv,argvlen);
676
+ len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
619
677
  status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
620
- free(cmd);
678
+ sdsfree(cmd);
679
+ return status;
680
+ }
681
+
682
+ int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) {
683
+ int status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
621
684
  return status;
622
685
  }
@@ -102,6 +102,9 @@ typedef struct redisAsyncContext {
102
102
 
103
103
  /* Functions that proxy to hiredis */
104
104
  redisAsyncContext *redisAsyncConnect(const char *ip, int port);
105
+ redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr);
106
+ redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
107
+ const char *source_addr);
105
108
  redisAsyncContext *redisAsyncConnectUnix(const char *path);
106
109
  int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
107
110
  int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
@@ -117,6 +120,7 @@ void redisAsyncHandleWrite(redisAsyncContext *ac);
117
120
  int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap);
118
121
  int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...);
119
122
  int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
123
+ int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len);
120
124
 
121
125
  #ifdef __cplusplus
122
126
  }
@@ -1,16 +1,21 @@
1
1
  #ifndef __HIREDIS_FMACRO_H
2
2
  #define __HIREDIS_FMACRO_H
3
3
 
4
- #if !defined(_BSD_SOURCE)
4
+ #if defined(__linux__)
5
5
  #define _BSD_SOURCE
6
+ #define _DEFAULT_SOURCE
6
7
  #endif
7
8
 
8
9
  #if defined(__sun__)
9
10
  #define _POSIX_C_SOURCE 200112L
10
- #elif defined(__linux__)
11
+ #elif defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
11
12
  #define _XOPEN_SOURCE 600
12
13
  #else
13
14
  #define _XOPEN_SOURCE
14
15
  #endif
15
16
 
17
+ #if __APPLE__ && __MACH__
18
+ #define _OSX
19
+ #endif
20
+
16
21
  #endif