hiredis 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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