hiredis 0.5.2 → 0.6.3

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.
@@ -8,12 +8,15 @@
8
8
  #include <unistd.h>
9
9
  #include <signal.h>
10
10
  #include <errno.h>
11
+ #include <limits.h>
11
12
 
12
13
  #include "hiredis.h"
14
+ #include "net.h"
13
15
 
14
16
  enum connection_type {
15
17
  CONN_TCP,
16
- CONN_UNIX
18
+ CONN_UNIX,
19
+ CONN_FD
17
20
  };
18
21
 
19
22
  struct config {
@@ -22,11 +25,12 @@ struct config {
22
25
  struct {
23
26
  const char *host;
24
27
  int port;
28
+ struct timeval timeout;
25
29
  } tcp;
26
30
 
27
31
  struct {
28
32
  const char *path;
29
- } unix;
33
+ } unix_sock;
30
34
  };
31
35
 
32
36
  /* The following lines make up our testing "framework" :) */
@@ -40,6 +44,13 @@ static long long usec(void) {
40
44
  return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
41
45
  }
42
46
 
47
+ /* The assert() calls below have side effects, so we need assert()
48
+ * even if we are compiling without asserts (-DNDEBUG). */
49
+ #ifdef NDEBUG
50
+ #undef assert
51
+ #define assert(e) (void)(e)
52
+ #endif
53
+
43
54
  static redisContext *select_database(redisContext *c) {
44
55
  redisReply *reply;
45
56
 
@@ -62,7 +73,7 @@ static redisContext *select_database(redisContext *c) {
62
73
  return c;
63
74
  }
64
75
 
65
- static void disconnect(redisContext *c) {
76
+ static int disconnect(redisContext *c, int keep_fd) {
66
77
  redisReply *reply;
67
78
 
68
79
  /* Make sure we're on DB 9. */
@@ -73,8 +84,11 @@ static void disconnect(redisContext *c) {
73
84
  assert(reply != NULL);
74
85
  freeReplyObject(reply);
75
86
 
76
- /* Free the context as well. */
87
+ /* Free the context as well, but keep the fd if requested. */
88
+ if (keep_fd)
89
+ return redisFreeKeepFd(c);
77
90
  redisFree(c);
91
+ return -1;
78
92
  }
79
93
 
80
94
  static redisContext *connect(struct config config) {
@@ -83,13 +97,25 @@ static redisContext *connect(struct config config) {
83
97
  if (config.type == CONN_TCP) {
84
98
  c = redisConnect(config.tcp.host, config.tcp.port);
85
99
  } else if (config.type == CONN_UNIX) {
86
- c = redisConnectUnix(config.unix.path);
100
+ c = redisConnectUnix(config.unix_sock.path);
101
+ } else if (config.type == CONN_FD) {
102
+ /* Create a dummy connection just to get an fd to inherit */
103
+ redisContext *dummy_ctx = redisConnectUnix(config.unix_sock.path);
104
+ if (dummy_ctx) {
105
+ int fd = disconnect(dummy_ctx, 1);
106
+ printf("Connecting to inherited fd %d\n", fd);
107
+ c = redisConnectFd(fd);
108
+ }
87
109
  } else {
88
110
  assert(NULL);
89
111
  }
90
112
 
91
- if (c->err) {
113
+ if (c == NULL) {
114
+ printf("Connection error: can't allocate redis context\n");
115
+ exit(1);
116
+ } else if (c->err) {
92
117
  printf("Connection error: %s\n", c->errstr);
118
+ redisFree(c);
93
119
  exit(1);
94
120
  }
95
121
 
@@ -125,13 +151,13 @@ static void test_format_commands(void) {
125
151
  free(cmd);
126
152
 
127
153
  test("Format command with %%b string interpolation: ");
128
- len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"b\0r",3);
154
+ len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3);
129
155
  test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 &&
130
156
  len == 4+4+(3+2)+4+(3+2)+4+(3+2));
131
157
  free(cmd);
132
158
 
133
159
  test("Format command with %%b and an empty string: ");
134
- len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"",0);
160
+ len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0);
135
161
  test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
136
162
  len == 4+4+(3+2)+4+(3+2)+4+(0+2));
137
163
  free(cmd);
@@ -177,7 +203,7 @@ static void test_format_commands(void) {
177
203
  FLOAT_WIDTH_TEST(double);
178
204
 
179
205
  test("Format command with invalid printf format: ");
180
- len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",3);
206
+ len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3);
181
207
  test_cond(len == -1);
182
208
 
183
209
  const char *argv[3];
@@ -198,6 +224,44 @@ static void test_format_commands(void) {
198
224
  test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 &&
199
225
  len == 4+4+(3+2)+4+(7+2)+4+(3+2));
200
226
  free(cmd);
227
+
228
+ sds sds_cmd;
229
+
230
+ sds_cmd = sdsempty();
231
+ test("Format command into sds by passing argc/argv without lengths: ");
232
+ len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,NULL);
233
+ test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
234
+ len == 4+4+(3+2)+4+(3+2)+4+(3+2));
235
+ sdsfree(sds_cmd);
236
+
237
+ sds_cmd = sdsempty();
238
+ test("Format command into sds by passing argc/argv with lengths: ");
239
+ len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,lens);
240
+ test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 &&
241
+ len == 4+4+(3+2)+4+(7+2)+4+(3+2));
242
+ sdsfree(sds_cmd);
243
+ }
244
+
245
+ static void test_append_formatted_commands(struct config config) {
246
+ redisContext *c;
247
+ redisReply *reply;
248
+ char *cmd;
249
+ int len;
250
+
251
+ c = connect(config);
252
+
253
+ test("Append format command: ");
254
+
255
+ len = redisFormatCommand(&cmd, "SET foo bar");
256
+
257
+ test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK);
258
+
259
+ assert(redisGetReply(c, (void*)&reply) == REDIS_OK);
260
+
261
+ free(cmd);
262
+ freeReplyObject(reply);
263
+
264
+ disconnect(c, 0);
201
265
  }
202
266
 
203
267
  static void test_reply_reader(void) {
@@ -238,6 +302,82 @@ static void test_reply_reader(void) {
238
302
  strncasecmp(reader->errstr,"No support for",14) == 0);
239
303
  redisReaderFree(reader);
240
304
 
305
+ test("Correctly parses LLONG_MAX: ");
306
+ reader = redisReaderCreate();
307
+ redisReaderFeed(reader, ":9223372036854775807\r\n",22);
308
+ ret = redisReaderGetReply(reader,&reply);
309
+ test_cond(ret == REDIS_OK &&
310
+ ((redisReply*)reply)->type == REDIS_REPLY_INTEGER &&
311
+ ((redisReply*)reply)->integer == LLONG_MAX);
312
+ freeReplyObject(reply);
313
+ redisReaderFree(reader);
314
+
315
+ test("Set error when > LLONG_MAX: ");
316
+ reader = redisReaderCreate();
317
+ redisReaderFeed(reader, ":9223372036854775808\r\n",22);
318
+ ret = redisReaderGetReply(reader,&reply);
319
+ test_cond(ret == REDIS_ERR &&
320
+ strcasecmp(reader->errstr,"Bad integer value") == 0);
321
+ freeReplyObject(reply);
322
+ redisReaderFree(reader);
323
+
324
+ test("Correctly parses LLONG_MIN: ");
325
+ reader = redisReaderCreate();
326
+ redisReaderFeed(reader, ":-9223372036854775808\r\n",23);
327
+ ret = redisReaderGetReply(reader,&reply);
328
+ test_cond(ret == REDIS_OK &&
329
+ ((redisReply*)reply)->type == REDIS_REPLY_INTEGER &&
330
+ ((redisReply*)reply)->integer == LLONG_MIN);
331
+ freeReplyObject(reply);
332
+ redisReaderFree(reader);
333
+
334
+ test("Set error when < LLONG_MIN: ");
335
+ reader = redisReaderCreate();
336
+ redisReaderFeed(reader, ":-9223372036854775809\r\n",23);
337
+ ret = redisReaderGetReply(reader,&reply);
338
+ test_cond(ret == REDIS_ERR &&
339
+ strcasecmp(reader->errstr,"Bad integer value") == 0);
340
+ freeReplyObject(reply);
341
+ redisReaderFree(reader);
342
+
343
+ test("Set error when array < -1: ");
344
+ reader = redisReaderCreate();
345
+ redisReaderFeed(reader, "*-2\r\n+asdf\r\n",12);
346
+ ret = redisReaderGetReply(reader,&reply);
347
+ test_cond(ret == REDIS_ERR &&
348
+ strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0);
349
+ freeReplyObject(reply);
350
+ redisReaderFree(reader);
351
+
352
+ test("Set error when bulk < -1: ");
353
+ reader = redisReaderCreate();
354
+ redisReaderFeed(reader, "$-2\r\nasdf\r\n",11);
355
+ ret = redisReaderGetReply(reader,&reply);
356
+ test_cond(ret == REDIS_ERR &&
357
+ strcasecmp(reader->errstr,"Bulk string length out of range") == 0);
358
+ freeReplyObject(reply);
359
+ redisReaderFree(reader);
360
+
361
+ test("Set error when array > INT_MAX: ");
362
+ reader = redisReaderCreate();
363
+ redisReaderFeed(reader, "*9223372036854775807\r\n+asdf\r\n",29);
364
+ ret = redisReaderGetReply(reader,&reply);
365
+ test_cond(ret == REDIS_ERR &&
366
+ strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0);
367
+ freeReplyObject(reply);
368
+ redisReaderFree(reader);
369
+
370
+ #if LLONG_MAX > SIZE_MAX
371
+ test("Set error when bulk > SIZE_MAX: ");
372
+ reader = redisReaderCreate();
373
+ redisReaderFeed(reader, "$9223372036854775807\r\nasdf\r\n",28);
374
+ ret = redisReaderGetReply(reader,&reply);
375
+ test_cond(ret == REDIS_ERR &&
376
+ strcasecmp(reader->errstr,"Bulk string length out of range") == 0);
377
+ freeReplyObject(reply);
378
+ redisReaderFree(reader);
379
+ #endif
380
+
241
381
  test("Works with NULL functions for reply: ");
242
382
  reader = redisReaderCreate();
243
383
  reader->fn = NULL;
@@ -279,14 +419,32 @@ static void test_reply_reader(void) {
279
419
  redisReaderFree(reader);
280
420
  }
281
421
 
422
+ static void test_free_null(void) {
423
+ void *redisCtx = NULL;
424
+ void *reply = NULL;
425
+
426
+ test("Don't fail when redisFree is passed a NULL value: ");
427
+ redisFree(redisCtx);
428
+ test_cond(redisCtx == NULL);
429
+
430
+ test("Don't fail when freeReplyObject is passed a NULL value: ");
431
+ freeReplyObject(reply);
432
+ test_cond(reply == NULL);
433
+ }
434
+
282
435
  static void test_blocking_connection_errors(void) {
283
436
  redisContext *c;
284
437
 
285
438
  test("Returns error when host cannot be resolved: ");
286
- c = redisConnect((char*)"idontexist.local", 6379);
439
+ c = redisConnect((char*)"idontexist.test", 6379);
287
440
  test_cond(c->err == REDIS_ERR_OTHER &&
288
441
  (strcmp(c->errstr,"Name or service not known") == 0 ||
289
- strcmp(c->errstr,"Can't resolve: idontexist.local") == 0));
442
+ strcmp(c->errstr,"Can't resolve: idontexist.test") == 0 ||
443
+ strcmp(c->errstr,"nodename nor servname provided, or not known") == 0 ||
444
+ strcmp(c->errstr,"No address associated with hostname") == 0 ||
445
+ strcmp(c->errstr,"Temporary failure in name resolution") == 0 ||
446
+ strcmp(c->errstr,"hostname nor servname provided, or not known") == 0 ||
447
+ strcmp(c->errstr,"no address associated with name") == 0));
290
448
  redisFree(c);
291
449
 
292
450
  test("Returns error when the port is not open: ");
@@ -295,7 +453,7 @@ static void test_blocking_connection_errors(void) {
295
453
  strcmp(c->errstr,"Connection refused") == 0);
296
454
  redisFree(c);
297
455
 
298
- test("Returns error when the unix socket path doesn't accept connections: ");
456
+ test("Returns error when the unix_sock socket path doesn't accept connections: ");
299
457
  c = redisConnectUnix((char*)"/tmp/idontexist.sock");
300
458
  test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */
301
459
  redisFree(c);
@@ -328,7 +486,7 @@ static void test_blocking_connection(struct config config) {
328
486
  freeReplyObject(reply);
329
487
 
330
488
  test("%%b String interpolation works: ");
331
- reply = redisCommand(c,"SET %b %b","foo",3,"hello\x00world",11);
489
+ reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11);
332
490
  freeReplyObject(reply);
333
491
  reply = redisCommand(c,"GET foo");
334
492
  test_cond(reply->type == REDIS_REPLY_STRING &&
@@ -376,7 +534,53 @@ static void test_blocking_connection(struct config config) {
376
534
  strcasecmp(reply->element[1]->str,"pong") == 0);
377
535
  freeReplyObject(reply);
378
536
 
379
- disconnect(c);
537
+ disconnect(c, 0);
538
+ }
539
+
540
+ static void test_blocking_connection_timeouts(struct config config) {
541
+ redisContext *c;
542
+ redisReply *reply;
543
+ ssize_t s;
544
+ const char *cmd = "DEBUG SLEEP 3\r\n";
545
+ struct timeval tv;
546
+
547
+ c = connect(config);
548
+ test("Successfully completes a command when the timeout is not exceeded: ");
549
+ reply = redisCommand(c,"SET foo fast");
550
+ freeReplyObject(reply);
551
+ tv.tv_sec = 0;
552
+ tv.tv_usec = 10000;
553
+ redisSetTimeout(c, tv);
554
+ reply = redisCommand(c, "GET foo");
555
+ test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0);
556
+ freeReplyObject(reply);
557
+ disconnect(c, 0);
558
+
559
+ c = connect(config);
560
+ test("Does not return a reply when the command times out: ");
561
+ s = write(c->fd, cmd, strlen(cmd));
562
+ tv.tv_sec = 0;
563
+ tv.tv_usec = 10000;
564
+ redisSetTimeout(c, tv);
565
+ reply = redisCommand(c, "GET foo");
566
+ test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0);
567
+ freeReplyObject(reply);
568
+
569
+ test("Reconnect properly reconnects after a timeout: ");
570
+ redisReconnect(c);
571
+ reply = redisCommand(c, "PING");
572
+ test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
573
+ freeReplyObject(reply);
574
+
575
+ test("Reconnect properly uses owned parameters: ");
576
+ config.tcp.host = "foo";
577
+ config.unix_sock.path = "foo";
578
+ redisReconnect(c);
579
+ reply = redisCommand(c, "PING");
580
+ test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
581
+ freeReplyObject(reply);
582
+
583
+ disconnect(c, 0);
380
584
  }
381
585
 
382
586
  static void test_blocking_io_errors(struct config config) {
@@ -402,7 +606,7 @@ static void test_blocking_io_errors(struct config config) {
402
606
 
403
607
  test("Returns I/O error when the connection is lost: ");
404
608
  reply = redisCommand(c,"QUIT");
405
- if (major >= 2 && minor > 0) {
609
+ if (major > 2 || (major == 2 && minor > 0)) {
406
610
  /* > 2.0 returns OK on QUIT and read() should be issued once more
407
611
  * to know the descriptor is at EOF. */
408
612
  test_cond(strcasecmp(reply->str,"OK") == 0 &&
@@ -430,6 +634,30 @@ static void test_blocking_io_errors(struct config config) {
430
634
  redisFree(c);
431
635
  }
432
636
 
637
+ static void test_invalid_timeout_errors(struct config config) {
638
+ redisContext *c;
639
+
640
+ test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: ");
641
+
642
+ config.tcp.timeout.tv_sec = 0;
643
+ config.tcp.timeout.tv_usec = 10000001;
644
+
645
+ c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
646
+
647
+ test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0);
648
+ redisFree(c);
649
+
650
+ test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: ");
651
+
652
+ config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1;
653
+ config.tcp.timeout.tv_usec = 0;
654
+
655
+ c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
656
+
657
+ test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0);
658
+ redisFree(c);
659
+ }
660
+
433
661
  static void test_throughput(struct config config) {
434
662
  redisContext *c = connect(config);
435
663
  redisReply **replies;
@@ -464,6 +692,17 @@ static void test_throughput(struct config config) {
464
692
  free(replies);
465
693
  printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0);
466
694
 
695
+ replies = malloc(sizeof(redisReply*)*num);
696
+ t1 = usec();
697
+ for (i = 0; i < num; i++) {
698
+ replies[i] = redisCommand(c, "INCRBY incrkey %d", 1000000);
699
+ assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER);
700
+ }
701
+ t2 = usec();
702
+ for (i = 0; i < num; i++) freeReplyObject(replies[i]);
703
+ free(replies);
704
+ printf("\t(%dx INCRBY: %.3fs)\n", num, (t2-t1)/1000000.0);
705
+
467
706
  num = 10000;
468
707
  replies = malloc(sizeof(redisReply*)*num);
469
708
  for (i = 0; i < num; i++)
@@ -492,7 +731,20 @@ static void test_throughput(struct config config) {
492
731
  free(replies);
493
732
  printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
494
733
 
495
- disconnect(c);
734
+ replies = malloc(sizeof(redisReply*)*num);
735
+ for (i = 0; i < num; i++)
736
+ redisAppendCommand(c,"INCRBY incrkey %d", 1000000);
737
+ t1 = usec();
738
+ for (i = 0; i < num; i++) {
739
+ assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK);
740
+ assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER);
741
+ }
742
+ t2 = usec();
743
+ for (i = 0; i < num; i++) freeReplyObject(replies[i]);
744
+ free(replies);
745
+ printf("\t(%dx INCRBY (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
746
+
747
+ disconnect(c, 0);
496
748
  }
497
749
 
498
750
  // static long __test_callback_flags = 0;
@@ -600,11 +852,12 @@ int main(int argc, char **argv) {
600
852
  .host = "127.0.0.1",
601
853
  .port = 6379
602
854
  },
603
- .unix = {
855
+ .unix_sock = {
604
856
  .path = "/tmp/redis.sock"
605
857
  }
606
858
  };
607
859
  int throughput = 1;
860
+ int test_inherit_fd = 1;
608
861
 
609
862
  /* Ignore broken pipe signal (for I/O error tests). */
610
863
  signal(SIGPIPE, SIG_IGN);
@@ -620,9 +873,11 @@ int main(int argc, char **argv) {
620
873
  cfg.tcp.port = atoi(argv[0]);
621
874
  } else if (argc >= 2 && !strcmp(argv[0],"-s")) {
622
875
  argv++; argc--;
623
- cfg.unix.path = argv[0];
876
+ cfg.unix_sock.path = argv[0];
624
877
  } else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) {
625
878
  throughput = 0;
879
+ } else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) {
880
+ test_inherit_fd = 0;
626
881
  } else {
627
882
  fprintf(stderr, "Invalid argument: %s\n", argv[0]);
628
883
  exit(1);
@@ -633,19 +888,31 @@ int main(int argc, char **argv) {
633
888
  test_format_commands();
634
889
  test_reply_reader();
635
890
  test_blocking_connection_errors();
891
+ test_free_null();
636
892
 
637
893
  printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port);
638
894
  cfg.type = CONN_TCP;
639
895
  test_blocking_connection(cfg);
896
+ test_blocking_connection_timeouts(cfg);
640
897
  test_blocking_io_errors(cfg);
898
+ test_invalid_timeout_errors(cfg);
899
+ test_append_formatted_commands(cfg);
641
900
  if (throughput) test_throughput(cfg);
642
901
 
643
- printf("\nTesting against Unix socket connection (%s):\n", cfg.unix.path);
902
+ printf("\nTesting against Unix socket connection (%s):\n", cfg.unix_sock.path);
644
903
  cfg.type = CONN_UNIX;
645
904
  test_blocking_connection(cfg);
905
+ test_blocking_connection_timeouts(cfg);
646
906
  test_blocking_io_errors(cfg);
647
907
  if (throughput) test_throughput(cfg);
648
908
 
909
+ if (test_inherit_fd) {
910
+ printf("\nTesting against inherited fd (%s):\n", cfg.unix_sock.path);
911
+ cfg.type = CONN_FD;
912
+ test_blocking_connection(cfg);
913
+ }
914
+
915
+
649
916
  if (fails) {
650
917
  printf("*** %d TESTS FAILED ***\n", fails);
651
918
  return 1;
@@ -0,0 +1,42 @@
1
+ #ifndef _WIN32_HELPER_INCLUDE
2
+ #define _WIN32_HELPER_INCLUDE
3
+ #ifdef _MSC_VER
4
+
5
+ #ifndef inline
6
+ #define inline __inline
7
+ #endif
8
+
9
+ #ifndef va_copy
10
+ #define va_copy(d,s) ((d) = (s))
11
+ #endif
12
+
13
+ #ifndef snprintf
14
+ #define snprintf c99_snprintf
15
+
16
+ __inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
17
+ {
18
+ int count = -1;
19
+
20
+ if (size != 0)
21
+ count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
22
+ if (count == -1)
23
+ count = _vscprintf(format, ap);
24
+
25
+ return count;
26
+ }
27
+
28
+ __inline int c99_snprintf(char* str, size_t size, const char* format, ...)
29
+ {
30
+ int count;
31
+ va_list ap;
32
+
33
+ va_start(ap, format);
34
+ count = c99_vsnprintf(str, size, format, ap);
35
+ va_end(ap);
36
+
37
+ return count;
38
+ }
39
+ #endif
40
+
41
+ #endif
42
+ #endif
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hiredis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pieter Noordhuis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-10 00:00:00.000000000 Z
11
+ date: 2018-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -28,16 +28,30 @@ dependencies:
28
28
  name: rake-compiler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.7.1
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.7.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 5.5.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 5.5.1
41
55
  description: Ruby wrapper for hiredis (protocol serialization/deserialization and
42
56
  blocking I/O)
43
57
  email:
@@ -47,38 +61,42 @@ extensions:
47
61
  - ext/hiredis_ext/extconf.rb
48
62
  extra_rdoc_files: []
49
63
  files:
50
- - ext/hiredis_ext/extconf.rb
64
+ - COPYING
65
+ - Rakefile
51
66
  - ext/hiredis_ext/connection.c
67
+ - ext/hiredis_ext/extconf.rb
52
68
  - ext/hiredis_ext/hiredis_ext.c
53
- - ext/hiredis_ext/reader.c
54
69
  - ext/hiredis_ext/hiredis_ext.h
55
- - vendor/hiredis/async.c
56
- - vendor/hiredis/dict.c
57
- - vendor/hiredis/hiredis.c
58
- - vendor/hiredis/net.c
59
- - vendor/hiredis/sds.c
60
- - vendor/hiredis/test.c
61
- - vendor/hiredis/async.h
62
- - vendor/hiredis/dict.h
63
- - vendor/hiredis/fmacros.h
64
- - vendor/hiredis/hiredis.h
65
- - vendor/hiredis/net.h
66
- - vendor/hiredis/sds.h
67
- - vendor/hiredis/COPYING
68
- - vendor/hiredis/Makefile
70
+ - ext/hiredis_ext/reader.c
71
+ - lib/hiredis.rb
69
72
  - lib/hiredis/connection.rb
70
- - lib/hiredis/errors.rb
71
73
  - lib/hiredis/ext/connection.rb
72
74
  - lib/hiredis/ext/reader.rb
73
75
  - lib/hiredis/reader.rb
74
76
  - lib/hiredis/ruby/connection.rb
75
77
  - lib/hiredis/ruby/reader.rb
76
78
  - lib/hiredis/version.rb
77
- - lib/hiredis.rb
78
- - COPYING
79
- - Rakefile
79
+ - vendor/hiredis/COPYING
80
+ - vendor/hiredis/Makefile
81
+ - vendor/hiredis/async.c
82
+ - vendor/hiredis/async.h
83
+ - vendor/hiredis/dict.c
84
+ - vendor/hiredis/dict.h
85
+ - vendor/hiredis/fmacros.h
86
+ - vendor/hiredis/hiredis.c
87
+ - vendor/hiredis/hiredis.h
88
+ - vendor/hiredis/net.c
89
+ - vendor/hiredis/net.h
90
+ - vendor/hiredis/read.c
91
+ - vendor/hiredis/read.h
92
+ - vendor/hiredis/sds.c
93
+ - vendor/hiredis/sds.h
94
+ - vendor/hiredis/sdsalloc.h
95
+ - vendor/hiredis/test.c
96
+ - vendor/hiredis/win32.h
80
97
  homepage: http://github.com/redis/hiredis-rb
81
- licenses: []
98
+ licenses:
99
+ - BSD-3-Clause
82
100
  metadata: {}
83
101
  post_install_message:
84
102
  rdoc_options: []
@@ -86,17 +104,17 @@ require_paths:
86
104
  - lib
87
105
  required_ruby_version: !ruby/object:Gem::Requirement
88
106
  requirements:
89
- - - '>='
107
+ - - ">="
90
108
  - !ruby/object:Gem::Version
91
109
  version: '0'
92
110
  required_rubygems_version: !ruby/object:Gem::Requirement
93
111
  requirements:
94
- - - '>='
112
+ - - ">="
95
113
  - !ruby/object:Gem::Version
96
114
  version: '0'
97
115
  requirements: []
98
116
  rubyforge_project:
99
- rubygems_version: 2.0.3
117
+ rubygems_version: 2.7.6
100
118
  signing_key:
101
119
  specification_version: 4
102
120
  summary: Ruby wrapper for hiredis (protocol serialization/deserialization and blocking
@@ -1,5 +0,0 @@
1
- module Hiredis
2
- class Error < StandardError; end
3
- class ProtocolError < Error; end
4
- class ReplyError < Error; end
5
- end