summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deps/hiredis/.gitignore8
-rw-r--r--deps/hiredis/.travis.yml97
-rw-r--r--deps/hiredis/CHANGELOG.md199
-rw-r--r--deps/hiredis/CMakeLists.txt90
-rw-r--r--deps/hiredis/COPYING29
-rw-r--r--deps/hiredis/Makefile273
-rw-r--r--deps/hiredis/README.md412
-rw-r--r--deps/hiredis/adapters/ae.h127
-rw-r--r--deps/hiredis/adapters/glib.h153
-rw-r--r--deps/hiredis/adapters/ivykis.h81
-rw-r--r--deps/hiredis/adapters/libev.h147
-rw-r--r--deps/hiredis/adapters/libevent.h172
-rw-r--r--deps/hiredis/adapters/libuv.h119
-rw-r--r--deps/hiredis/adapters/macosx.h114
-rw-r--r--deps/hiredis/adapters/qt.h135
-rw-r--r--deps/hiredis/appveyor.yml24
-rw-r--r--deps/hiredis/async.c766
-rw-r--r--deps/hiredis/async.h142
-rw-r--r--deps/hiredis/async_private.h72
-rw-r--r--deps/hiredis/dict.c338
-rw-r--r--deps/hiredis/dict.h126
-rw-r--r--deps/hiredis/examples/CMakeLists.txt46
-rw-r--r--deps/hiredis/examples/example-ae.c62
-rw-r--r--deps/hiredis/examples/example-glib.c73
-rw-r--r--deps/hiredis/examples/example-ivykis.c58
-rw-r--r--deps/hiredis/examples/example-libev.c52
-rw-r--r--deps/hiredis/examples/example-libevent-ssl.c73
-rw-r--r--deps/hiredis/examples/example-libevent.c64
-rw-r--r--deps/hiredis/examples/example-libuv.c53
-rw-r--r--deps/hiredis/examples/example-macosx.c66
-rw-r--r--deps/hiredis/examples/example-qt.cpp46
-rw-r--r--deps/hiredis/examples/example-qt.h32
-rw-r--r--deps/hiredis/examples/example-ssl.c97
-rw-r--r--deps/hiredis/examples/example.c91
-rw-r--r--deps/hiredis/fmacros.h12
-rw-r--r--deps/hiredis/hiredis.c1086
-rw-r--r--deps/hiredis/hiredis.h299
-rw-r--r--deps/hiredis/hiredis.pc.in11
-rw-r--r--deps/hiredis/hiredis_ssl.h53
-rw-r--r--deps/hiredis/hiredis_ssl.pc.in12
-rw-r--r--deps/hiredis/net.c571
-rw-r--r--deps/hiredis/net.h54
-rw-r--r--deps/hiredis/read.c681
-rw-r--r--deps/hiredis/read.h122
-rw-r--r--deps/hiredis/sds.c1291
-rw-r--r--deps/hiredis/sds.h276
-rw-r--r--deps/hiredis/sdsalloc.h42
-rw-r--r--deps/hiredis/sockcompat.c248
-rw-r--r--deps/hiredis/sockcompat.h91
-rw-r--r--deps/hiredis/ssl.c448
-rw-r--r--deps/hiredis/test.c1012
-rwxr-xr-xdeps/hiredis/test.sh70
-rw-r--r--deps/hiredis/win32.h56
53 files changed, 0 insertions, 10872 deletions
diff --git a/deps/hiredis/.gitignore b/deps/hiredis/.gitignore
deleted file mode 100644
index 8e50b5434..000000000
--- a/deps/hiredis/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-/hiredis-test
-/examples/hiredis-example*
-/*.o
-/*.so
-/*.dylib
-/*.a
-/*.pc
-*.dSYM
diff --git a/deps/hiredis/.travis.yml b/deps/hiredis/.travis.yml
deleted file mode 100644
index dd8e0e73d..000000000
--- a/deps/hiredis/.travis.yml
+++ /dev/null
@@ -1,97 +0,0 @@
-language: c
-sudo: false
-compiler:
- - gcc
- - clang
-
-os:
- - linux
- - osx
-
-branches:
- only:
- - staging
- - trying
- - master
-
-before_script:
- - if [ "$TRAVIS_OS_NAME" == "osx" ] ; then brew update; brew install redis; fi
-
-addons:
- apt:
- packages:
- - libc6-dbg
- - libc6-dev
- - libc6:i386
- - libc6-dev-i386
- - libc6-dbg:i386
- - gcc-multilib
- - g++-multilib
- - valgrind
-
-env:
- - BITS="32"
- - BITS="64"
-
-script:
- - EXTRA_CMAKE_OPTS="-DENABLE_EXAMPLES:BOOL=ON -DHIREDIS_SSL:BOOL=ON";
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
- if [ "$BITS" == "32" ]; then
- CFLAGS="-m32 -Werror";
- CXXFLAGS="-m32 -Werror";
- LDFLAGS="-m32";
- EXTRA_CMAKE_OPTS=;
- else
- CFLAGS="-Werror";
- CXXFLAGS="-Werror";
- fi;
- else
- TEST_PREFIX="valgrind --track-origins=yes --leak-check=full";
- if [ "$BITS" == "32" ]; then
- CFLAGS="-m32 -Werror";
- CXXFLAGS="-m32 -Werror";
- LDFLAGS="-m32";
- EXTRA_CMAKE_OPTS=;
- else
- CFLAGS="-Werror";
- CXXFLAGS="-Werror";
- fi;
- fi;
- export CFLAGS CXXFLAGS LDFLAGS TEST_PREFIX EXTRA_CMAKE_OPTS
- - mkdir build/ && cd build/
- - cmake .. ${EXTRA_CMAKE_OPTS}
- - make VERBOSE=1
- - ctest -V
-
-matrix:
- include:
- # Windows MinGW cross compile on Linux
- - os: linux
- dist: xenial
- compiler: mingw
- addons:
- apt:
- packages:
- - ninja-build
- - gcc-mingw-w64-x86-64
- - g++-mingw-w64-x86-64
- script:
- - mkdir build && cd build
- - CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_WITH_INSTALL_RPATH=on
- - ninja -v
-
- # Windows MSVC 2017
- - os: windows
- compiler: msvc
- env:
- - MATRIX_EVAL="CC=cl.exe && CXX=cl.exe"
- before_install:
- - eval "${MATRIX_EVAL}"
- install:
- - choco install ninja
- script:
- - mkdir build && cd build
- - cmd.exe /C '"C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64 &&
- cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release &&
- ninja -v'
- - ctest -V
diff --git a/deps/hiredis/CHANGELOG.md b/deps/hiredis/CHANGELOG.md
deleted file mode 100644
index d1d37e515..000000000
--- a/deps/hiredis/CHANGELOG.md
+++ /dev/null
@@ -1,199 +0,0 @@
-### 1.0.0 (unreleased)
-
-**BREAKING CHANGES**:
-
-* Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now
- protocol errors. This is consistent with the RESP specification. On 32-bit
- platforms, the upper bound is lowered to `SIZE_MAX`.
-
-* Change `redisReply.len` to `size_t`, as it denotes the the size of a string
-
- User code should compare this to `size_t` values as well. If it was used to
- compare to other values, casting might be necessary or can be removed, if
- casting was applied before.
-
-### 0.x.x (unreleased)
-**BREAKING CHANGES**:
-
-* Change `redisReply.len` to `size_t`, as it denotes the the size of a string
-
-User code should compare this to `size_t` values as well.
-If it was used to compare to other values, casting might be necessary or can be removed, if casting was applied before.
-
-* `redisReplyObjectFunctions.createArray` now takes `size_t` for its length parameter.
-
-### 0.14.0 (2018-09-25)
-
-* Make string2ll static to fix conflict with Redis (Tom Lee [c3188b])
-* Use -dynamiclib instead of -shared for OSX (Ryan Schmidt [a65537])
-* Use string2ll from Redis w/added tests (Michael Grunder [7bef04, 60f622])
-* Makefile - OSX compilation fixes (Ryan Schmidt [881fcb, 0e9af8])
-* Remove redundant NULL checks (Justin Brewer [54acc8, 58e6b8])
-* Fix bulk and multi-bulk length truncation (Justin Brewer [109197])
-* Fix SIGSEGV in OpenBSD by checking for NULL before calling freeaddrinfo (Justin Brewer [546d94])
-* Several POSIX compatibility fixes (Justin Brewer [bbeab8, 49bbaa, d1c1b6])
-* Makefile - Compatibility fixes (Dimitri Vorobiev [3238cf, 12a9d1])
-* Makefile - Fix make install on FreeBSD (Zach Shipko [a2ef2b])
-* Makefile - don't assume $(INSTALL) is cp (Igor Gnatenko [725a96])
-* Separate side-effect causing function from assert and small cleanup (amallia [b46413, 3c3234])
-* Don't send negative values to `__redisAsyncCommand` (Frederik Deweerdt [706129])
-* Fix leak if setsockopt fails (Frederik Deweerdt [e21c9c])
-* Fix libevent leak (zfz [515228])
-* Clean up GCC warning (Ichito Nagata [2ec774])
-* Keep track of errno in `__redisSetErrorFromErrno()` as snprintf may use it (Jin Qing [25cd88])
-* Solaris compilation fix (Donald Whyte [41b07d])
-* Reorder linker arguments when building examples (Tustfarm-heart [06eedd])
-* Keep track of subscriptions in case of rapid subscribe/unsubscribe (Hyungjin Kim [073dc8, be76c5, d46999])
-* libuv use after free fix (Paul Scott [cbb956])
-* Properly close socket fd on reconnect attempt (WSL [64d1ec])
-* Skip valgrind in OSX tests (Jan-Erik Rediger [9deb78])
-* Various updates for Travis testing OSX (Ted Nyman [fa3774, 16a459, bc0ea5])
-* Update libevent (Chris Xin [386802])
-* Change sds.h for building in C++ projects (Ali Volkan ATLI [f5b32e])
-* Use proper format specifier in redisFormatSdsCommandArgv (Paulino Huerta, Jan-Erik Rediger [360a06, 8655a6])
-* Better handling of NULL reply in example code (Jan-Erik Rediger [1b8ed3])
-* Prevent overflow when formatting an error (Jan-Erik Rediger [0335cb])
-* Compatibility fix for strerror_r (Tom Lee [bb1747])
-* Properly detect integer parse/overflow errors (Justin Brewer [93421f])
-* Adds CI for Windows and cygwin fixes (owent, [6c53d6, 6c3e40])
-* Catch a buffer overflow when formatting the error message
-* Import latest upstream sds. This breaks applications that are linked against the old hiredis v0.13
-* Fix warnings, when compiled with -Wshadow
-* Make hiredis compile in Cygwin on Windows, now CI-tested
-* Bulk and multi-bulk lengths less than -1 or greater than `LLONG_MAX` are now
- protocol errors. This is consistent with the RESP specification. On 32-bit
- platforms, the upper bound is lowered to `SIZE_MAX`.
-
-* Remove backwards compatibility macro's
-
-This removes the following old function aliases, use the new name now:
-
-| Old | New |
-| --------------------------- | ---------------------- |
-| redisReplyReaderCreate | redisReaderCreate |
-| redisReplyReaderCreate | redisReaderCreate |
-| redisReplyReaderFree | redisReaderFree |
-| redisReplyReaderFeed | redisReaderFeed |
-| redisReplyReaderGetReply | redisReaderGetReply |
-| redisReplyReaderSetPrivdata | redisReaderSetPrivdata |
-| redisReplyReaderGetObject | redisReaderGetObject |
-| redisReplyReaderGetError | redisReaderGetError |
-
-* The `DEBUG` variable in the Makefile was renamed to `DEBUG_FLAGS`
-
-Previously it broke some builds for people that had `DEBUG` set to some arbitrary value,
-due to debugging other software.
-By renaming we avoid unintentional name clashes.
-
-Simply rename `DEBUG` to `DEBUG_FLAGS` in your environment to make it working again.
-
-### 0.13.3 (2015-09-16)
-
-* Revert "Clear `REDIS_CONNECTED` flag when connection is closed".
-* Make tests pass on FreeBSD (Thanks, Giacomo Olgeni)
-
-
-If the `REDIS_CONNECTED` flag is cleared,
-the async onDisconnect callback function will never be called.
-This causes problems as the disconnect is never reported back to the user.
-
-### 0.13.2 (2015-08-25)
-
-* Prevent crash on pending replies in async code (Thanks, @switch-st)
-* Clear `REDIS_CONNECTED` flag when connection is closed (Thanks, Jerry Jacobs)
-* Add MacOS X addapter (Thanks, @dizzus)
-* Add Qt adapter (Thanks, Pietro Cerutti)
-* Add Ivykis adapter (Thanks, Gergely Nagy)
-
-All adapters are provided as is and are only tested where possible.
-
-### 0.13.1 (2015-05-03)
-
-This is a bug fix release.
-The new `reconnect` method introduced new struct members, which clashed with pre-defined names in pre-C99 code.
-Another commit forced C99 compilation just to make it work, but of course this is not desirable for outside projects.
-Other non-C99 code can now use hiredis as usual again.
-Sorry for the inconvenience.
-
-* Fix memory leak in async reply handling (Salvatore Sanfilippo)
-* Rename struct member to avoid name clash with pre-c99 code (Alex Balashov, ncopa)
-
-### 0.13.0 (2015-04-16)
-
-This release adds a minimal Windows compatibility layer.
-The parser, standalone since v0.12.0, can now be compiled on Windows
-(and thus used in other client libraries as well)
-
-* Windows compatibility layer for parser code (tzickel)
-* Properly escape data printed to PKGCONF file (Dan Skorupski)
-* Fix tests when assert() undefined (Keith Bennett, Matt Stancliff)
-* Implement a reconnect method for the client context, this changes the structure of `redisContext` (Aaron Bedra)
-
-### 0.12.1 (2015-01-26)
-
-* Fix `make install`: DESTDIR support, install all required files, install PKGCONF in proper location
-* Fix `make test` as 32 bit build on 64 bit platform
-
-### 0.12.0 (2015-01-22)
-
-* Add optional KeepAlive support
-
-* Try again on EINTR errors
-
-* Add libuv adapter
-
-* Add IPv6 support
-
-* Remove possibility of multiple close on same fd
-
-* Add ability to bind source address on connect
-
-* Add redisConnectFd() and redisFreeKeepFd()
-
-* Fix getaddrinfo() memory leak
-
-* Free string if it is unused (fixes memory leak)
-
-* Improve redisAppendCommandArgv performance 2.5x
-
-* Add support for SO_REUSEADDR
-
-* Fix redisvFormatCommand format parsing
-
-* Add GLib 2.0 adapter
-
-* Refactor reading code into read.c
-
-* Fix errno error buffers to not clobber errors
-
-* Generate pkgconf during build
-
-* Silence _BSD_SOURCE warnings
-
-* Improve digit counting for multibulk creation
-
-
-### 0.11.0
-
-* Increase the maximum multi-bulk reply depth to 7.
-
-* Increase the read buffer size from 2k to 16k.
-
-* Use poll(2) instead of select(2) to support large fds (>= 1024).
-
-### 0.10.1
-
-* Makefile overhaul. Important to check out if you override one or more
- variables using environment variables or via arguments to the "make" tool.
-
-* Issue #45: Fix potential memory leak for a multi bulk reply with 0 elements
- being created by the default reply object functions.
-
-* Issue #43: Don't crash in an asynchronous context when Redis returns an error
- reply after the connection has been made (this happens when the maximum
- number of connections is reached).
-
-### 0.10.0
-
-* See commit log.
-
diff --git a/deps/hiredis/CMakeLists.txt b/deps/hiredis/CMakeLists.txt
deleted file mode 100644
index 9e78894f3..000000000
--- a/deps/hiredis/CMakeLists.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 3.4.0)
-INCLUDE(GNUInstallDirs)
-PROJECT(hiredis)
-
-OPTION(ENABLE_SSL "Build hiredis_ssl for SSL support" OFF)
-
-MACRO(getVersionBit name)
- SET(VERSION_REGEX "^#define ${name} (.+)$")
- FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/hiredis.h"
- VERSION_BIT REGEX ${VERSION_REGEX})
- STRING(REGEX REPLACE ${VERSION_REGEX} "\\1" ${name} "${VERSION_BIT}")
-ENDMACRO(getVersionBit)
-
-getVersionBit(HIREDIS_MAJOR)
-getVersionBit(HIREDIS_MINOR)
-getVersionBit(HIREDIS_PATCH)
-getVersionBit(HIREDIS_SONAME)
-SET(VERSION "${HIREDIS_MAJOR}.${HIREDIS_MINOR}.${HIREDIS_PATCH}")
-MESSAGE("Detected version: ${VERSION}")
-
-PROJECT(hiredis VERSION "${VERSION}")
-
-SET(ENABLE_EXAMPLES OFF CACHE BOOL "Enable building hiredis examples")
-
-ADD_LIBRARY(hiredis SHARED
- async.c
- dict.c
- hiredis.c
- net.c
- read.c
- sds.c
- sockcompat.c)
-
-SET_TARGET_PROPERTIES(hiredis
- PROPERTIES
- VERSION "${HIREDIS_SONAME}")
-IF(WIN32 OR MINGW)
- TARGET_LINK_LIBRARIES(hiredis PRIVATE ws2_32)
-ENDIF()
-TARGET_INCLUDE_DIRECTORIES(hiredis PUBLIC .)
-
-CONFIGURE_FILE(hiredis.pc.in hiredis.pc @ONLY)
-
-INSTALL(TARGETS hiredis
- DESTINATION "${CMAKE_INSTALL_LIBDIR}")
-
-INSTALL(FILES hiredis.h read.h sds.h async.h
- DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis)
-
-INSTALL(DIRECTORY adapters
- DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis)
-
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis.pc
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
-
-IF(ENABLE_SSL)
- IF (NOT OPENSSL_ROOT_DIR)
- IF (APPLE)
- SET(OPENSSL_ROOT_DIR "/usr/local/opt/openssl")
- ENDIF()
- ENDIF()
- FIND_PACKAGE(OpenSSL REQUIRED)
- ADD_LIBRARY(hiredis_ssl SHARED
- ssl.c)
- TARGET_INCLUDE_DIRECTORIES(hiredis_ssl PRIVATE "${OPENSSL_INCLUDE_DIR}")
- TARGET_LINK_LIBRARIES(hiredis_ssl PRIVATE ${OPENSSL_LIBRARIES})
- CONFIGURE_FILE(hiredis_ssl.pc.in hiredis_ssl.pc @ONLY)
-
- INSTALL(TARGETS hiredis_ssl
- DESTINATION "${CMAKE_INSTALL_LIBDIR}")
-
- INSTALL(FILES hiredis_ssl.h
- DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis)
-
- INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl.pc
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
-ENDIF()
-
-IF(NOT (WIN32 OR MINGW))
- ENABLE_TESTING()
- ADD_EXECUTABLE(hiredis-test test.c)
- TARGET_LINK_LIBRARIES(hiredis-test hiredis)
- ADD_TEST(NAME hiredis-test
- COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test.sh)
-ENDIF()
-
-# Add examples
-IF(ENABLE_EXAMPLES)
- ADD_SUBDIRECTORY(examples)
-ENDIF(ENABLE_EXAMPLES)
diff --git a/deps/hiredis/COPYING b/deps/hiredis/COPYING
deleted file mode 100644
index a5fc97395..000000000
--- a/deps/hiredis/COPYING
+++ /dev/null
@@ -1,29 +0,0 @@
-Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
-Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-* Neither the name of Redis nor the names of its contributors may be used
- to endorse or promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/deps/hiredis/Makefile b/deps/hiredis/Makefile
deleted file mode 100644
index 25ac15464..000000000
--- a/deps/hiredis/Makefile
+++ /dev/null
@@ -1,273 +0,0 @@
-# Hiredis Makefile
-# Copyright (C) 2010-2011 Salvatore Sanfilippo <antirez at gmail dot com>
-# Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis at gmail dot com>
-# This file is released under the BSD license, see the COPYING file
-
-OBJ=net.o hiredis.o sds.o async.o read.o sockcompat.o
-SSL_OBJ=ssl.o
-EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
-ifeq ($(USE_SSL),1)
-EXAMPLES+=hiredis-example-ssl hiredis-example-libevent-ssl
-endif
-TESTS=hiredis-test
-LIBNAME=libhiredis
-SSL_LIBNAME=libhiredis_ssl
-PKGCONFNAME=hiredis.pc
-SSL_PKGCONFNAME=hiredis_ssl.pc
-
-HIREDIS_MAJOR=$(shell grep HIREDIS_MAJOR hiredis.h | awk '{print $$3}')
-HIREDIS_MINOR=$(shell grep HIREDIS_MINOR hiredis.h | awk '{print $$3}')
-HIREDIS_PATCH=$(shell grep HIREDIS_PATCH hiredis.h | awk '{print $$3}')
-HIREDIS_SONAME=$(shell grep HIREDIS_SONAME hiredis.h | awk '{print $$3}')
-
-# Installation related variables and target
-PREFIX?=/usr/local
-INCLUDE_PATH?=include/hiredis
-LIBRARY_PATH?=lib
-PKGCONF_PATH?=pkgconfig
-INSTALL_INCLUDE_PATH= $(DESTDIR)$(PREFIX)/$(INCLUDE_PATH)
-INSTALL_LIBRARY_PATH= $(DESTDIR)$(PREFIX)/$(LIBRARY_PATH)
-INSTALL_PKGCONF_PATH= $(INSTALL_LIBRARY_PATH)/$(PKGCONF_PATH)
-
-# redis-server configuration used for testing
-REDIS_PORT=56379
-REDIS_SERVER=redis-server
-define REDIS_TEST_CONFIG
- daemonize yes
- pidfile /tmp/hiredis-test-redis.pid
- port $(REDIS_PORT)
- bind 127.0.0.1
- unixsocket /tmp/hiredis-test-redis.sock
-endef
-export REDIS_TEST_CONFIG
-
-# Fallback to gcc when $CC is not in $PATH.
-CC:=$(shell sh -c 'type $${CC%% *} >/dev/null 2>/dev/null && echo $(CC) || echo gcc')
-CXX:=$(shell sh -c 'type $${CXX%% *} >/dev/null 2>/dev/null && echo $(CXX) || echo g++')
-OPTIMIZATION?=-O3
-WARNINGS=-Wall -W -Wstrict-prototypes -Wwrite-strings -Wno-missing-field-initializers
-DEBUG_FLAGS?= -g -ggdb
-REAL_CFLAGS=$(OPTIMIZATION) -fPIC $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEBUG_FLAGS)
-REAL_LDFLAGS=$(LDFLAGS)
-
-DYLIBSUFFIX=so
-STLIBSUFFIX=a
-DYLIB_MINOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME)
-DYLIB_MAJOR_NAME=$(LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR)
-DYLIBNAME=$(LIBNAME).$(DYLIBSUFFIX)
-SSL_DYLIBNAME=$(SSL_LIBNAME).$(DYLIBSUFFIX)
-DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME)
-STLIBNAME=$(LIBNAME).$(STLIBSUFFIX)
-SSL_STLIBNAME=$(SSL_LIBNAME).$(STLIBSUFFIX)
-STLIB_MAKE_CMD=$(AR) rcs
-
-# Platform-specific overrides
-uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
-
-USE_SSL?=0
-
-# This is required for test.c only
-ifeq ($(USE_SSL),1)
- CFLAGS+=-DHIREDIS_TEST_SSL
-endif
-
-ifeq ($(uname_S),Linux)
- SSL_LDFLAGS=-lssl -lcrypto
-else
- OPENSSL_PREFIX?=/usr/local/opt/openssl
- CFLAGS+=-I$(OPENSSL_PREFIX)/include
- SSL_LDFLAGS+=-L$(OPENSSL_PREFIX)/lib -lssl -lcrypto
-endif
-
-ifeq ($(uname_S),SunOS)
- REAL_LDFLAGS+= -ldl -lnsl -lsocket
- DYLIB_MAKE_CMD=$(CC) -G -o $(DYLIBNAME) -h $(DYLIB_MINOR_NAME) $(LDFLAGS)
-endif
-ifeq ($(uname_S),Darwin)
- DYLIBSUFFIX=dylib
- DYLIB_MINOR_NAME=$(LIBNAME).$(HIREDIS_SONAME).$(DYLIBSUFFIX)
- DYLIB_MAKE_CMD=$(CC) -dynamiclib -Wl,-install_name,$(PREFIX)/$(LIBRARY_PATH)/$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
-endif
-
-all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME)
-ifeq ($(USE_SSL),1)
-all: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME)
-endif
-
-# Deps (use make dep to generate this)
-async.o: async.c fmacros.h async.h hiredis.h read.h sds.h net.h dict.c dict.h
-dict.o: dict.c fmacros.h dict.h
-hiredis.o: hiredis.c fmacros.h hiredis.h read.h sds.h net.h win32.h
-net.o: net.c fmacros.h net.h hiredis.h read.h sds.h sockcompat.h win32.h
-read.o: read.c fmacros.h read.h sds.h
-sds.o: sds.c sds.h
-sockcompat.o: sockcompat.c sockcompat.h
-ssl.o: ssl.c hiredis.h
-test.o: test.c fmacros.h hiredis.h read.h sds.h
-
-$(DYLIBNAME): $(OBJ)
- $(DYLIB_MAKE_CMD) -o $(DYLIBNAME) $(OBJ) $(REAL_LDFLAGS)
-
-$(STLIBNAME): $(OBJ)
- $(STLIB_MAKE_CMD) $(STLIBNAME) $(OBJ)
-
-$(SSL_DYLIBNAME): $(SSL_OBJ)
- $(DYLIB_MAKE_CMD) -o $(SSL_DYLIBNAME) $(SSL_OBJ) $(REAL_LDFLAGS) $(SSL_LDFLAGS)
-
-$(SSL_STLIBNAME): $(SSL_OBJ)
- $(STLIB_MAKE_CMD) $(SSL_STLIBNAME) $(SSL_OBJ)
-
-dynamic: $(DYLIBNAME)
-static: $(STLIBNAME)
-ifeq ($(USE_SSL),1)
-dynamic: $(SSL_DYLIBNAME)
-static: $(SSL_STLIBNAME)
-endif
-
-# Binaries:
-hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(REAL_LDFLAGS)
-
-hiredis-example-libevent-ssl: examples/example-libevent-ssl.c adapters/libevent.h $(STLIBNAME) $(SSL_STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -levent $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS)
-
-hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -lev $(STLIBNAME) $(REAL_LDFLAGS)
-
-hiredis-example-glib: examples/example-glib.c adapters/glib.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(shell pkg-config --cflags --libs glib-2.0) $(STLIBNAME) $(REAL_LDFLAGS)
-
-hiredis-example-ivykis: examples/example-ivykis.c adapters/ivykis.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -livykis $(STLIBNAME) $(REAL_LDFLAGS)
-
-hiredis-example-macosx: examples/example-macosx.c adapters/macosx.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< -framework CoreFoundation $(STLIBNAME) $(REAL_LDFLAGS)
-
-hiredis-example-ssl: examples/example-ssl.c $(STLIBNAME) $(SSL_STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(SSL_STLIBNAME) $(REAL_LDFLAGS) $(SSL_LDFLAGS)
-
-ifndef AE_DIR
-hiredis-example-ae:
- @echo "Please specify AE_DIR (e.g. <redis repository>/src)"
- @false
-else
-hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME)
- $(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)
-endif
-
-ifndef LIBUV_DIR
-hiredis-example-libuv:
- @echo "Please specify LIBUV_DIR (e.g. ../libuv/)"
- @false
-else
-hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread -lrt $(STLIBNAME) $(REAL_LDFLAGS)
-endif
-
-ifeq ($(and $(QT_MOC),$(QT_INCLUDE_DIR),$(QT_LIBRARY_DIR)),)
-hiredis-example-qt:
- @echo "Please specify QT_MOC, QT_INCLUDE_DIR AND QT_LIBRARY_DIR"
- @false
-else
-hiredis-example-qt: examples/example-qt.cpp adapters/qt.h $(STLIBNAME)
- $(QT_MOC) adapters/qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \
- $(CXX) -x c++ -o qt-adapter-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore
- $(QT_MOC) examples/example-qt.h -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore | \
- $(CXX) -x c++ -o qt-example-moc.o -c - $(REAL_CFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore
- $(CXX) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(QT_INCLUDE_DIR) -I$(QT_INCLUDE_DIR)/QtCore -L$(QT_LIBRARY_DIR) qt-adapter-moc.o qt-example-moc.o $< -pthread $(STLIBNAME) -lQtCore
-endif
-
-hiredis-example: examples/example.c $(STLIBNAME)
- $(CC) -o examples/$@ $(REAL_CFLAGS) -I. $< $(STLIBNAME) $(REAL_LDFLAGS)
-
-examples: $(EXAMPLES)
-
-TEST_LIBS = $(STLIBNAME)
-ifeq ($(USE_SSL),1)
- TEST_LIBS += $(SSL_STLIBNAME) -lssl -lcrypto -lpthread
-endif
-hiredis-test: test.o $(TEST_LIBS)
-
-hiredis-%: %.o $(STLIBNAME)
- $(CC) $(REAL_CFLAGS) -o $@ $< $(TEST_LIBS) $(REAL_LDFLAGS)
-
-test: hiredis-test
- ./hiredis-test
-
-check: hiredis-test
- TEST_SSL=$(USE_SSL) ./test.sh
-
-.c.o:
- $(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $<
-
-clean:
- rm -rf $(DYLIBNAME) $(STLIBNAME) $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(TESTS) $(PKGCONFNAME) examples/hiredis-example* *.o *.gcda *.gcno *.gcov
-
-dep:
- $(CC) $(CPPFLAGS) $(CFLAGS) -MM *.c
-
-INSTALL?= cp -pPR
-
-$(PKGCONFNAME): hiredis.h
- @echo "Generating $@ for pkgconfig..."
- @echo prefix=$(PREFIX) > $@
- @echo exec_prefix=\$${prefix} >> $@
- @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@
- @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@
- @echo >> $@
- @echo Name: hiredis >> $@
- @echo Description: Minimalistic C client library for Redis. >> $@
- @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@
- @echo Libs: -L\$${libdir} -lhiredis >> $@
- @echo Cflags: -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@
-
-$(SSL_PKGCONFNAME): hiredis.h
- @echo "Generating $@ for pkgconfig..."
- @echo prefix=$(PREFIX) > $@
- @echo exec_prefix=\$${prefix} >> $@
- @echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@
- @echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@
- @echo >> $@
- @echo Name: hiredis_ssl >> $@
- @echo Description: SSL Support for hiredis. >> $@
- @echo Version: $(HIREDIS_MAJOR).$(HIREDIS_MINOR).$(HIREDIS_PATCH) >> $@
- @echo Requires: hiredis >> $@
- @echo Libs: -L\$${libdir} -lhiredis_ssl >> $@
- @echo Libs.private: -lssl -lcrypto >> $@
-
-install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
- mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL_LIBRARY_PATH)
- $(INSTALL) hiredis.h async.h read.h sds.h $(INSTALL_INCLUDE_PATH)
- $(INSTALL) adapters/*.h $(INSTALL_INCLUDE_PATH)/adapters
- $(INSTALL) $(DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(DYLIB_MINOR_NAME)
- cd $(INSTALL_LIBRARY_PATH) && ln -sf $(DYLIB_MINOR_NAME) $(DYLIBNAME)
- $(INSTALL) $(STLIBNAME) $(INSTALL_LIBRARY_PATH)
- mkdir -p $(INSTALL_PKGCONF_PATH)
- $(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH)
-
-32bit:
- @echo ""
- @echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386"
- @echo ""
- $(MAKE) CFLAGS="-m32" LDFLAGS="-m32"
-
-32bit-vars:
- $(eval CFLAGS=-m32)
- $(eval LDFLAGS=-m32)
-
-gprof:
- $(MAKE) CFLAGS="-pg" LDFLAGS="-pg"
-
-gcov:
- $(MAKE) CFLAGS="-fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs"
-
-coverage: gcov
- make check
- mkdir -p tmp/lcov
- lcov -d . -c -o tmp/lcov/hiredis.info
- genhtml --legend -o tmp/lcov/report tmp/lcov/hiredis.info
-
-noopt:
- $(MAKE) OPTIMIZATION=""
-
-.PHONY: all test check clean dep install 32bit 32bit-vars gprof gcov noopt
diff --git a/deps/hiredis/README.md b/deps/hiredis/README.md
deleted file mode 100644
index c0b432f07..000000000
--- a/deps/hiredis/README.md
+++ /dev/null
@@ -1,412 +0,0 @@
-[![Build Status](https://travis-ci.org/redis/hiredis.png)](https://travis-ci.org/redis/hiredis)
-
-**This Readme reflects the latest changed in the master branch. See [v0.13.3](https://github.com/redis/hiredis/tree/v0.13.3) for the Readme and documentation for the latest release.**
-
-# HIREDIS
-
-Hiredis is a minimalistic C client library for the [Redis](http://redis.io/) database.
-
-It is minimalistic because it just adds minimal support for the protocol, but
-at the same time it uses a high level printf-alike API in order to make it
-much higher level than otherwise suggested by its minimal code base and the
-lack of explicit bindings for every Redis command.
-
-Apart from supporting sending commands and receiving replies, it comes with
-a reply parser that is decoupled from the I/O layer. It
-is a stream parser designed for easy reusability, which can for instance be used
-in higher level language bindings for efficient reply parsing.
-
-Hiredis only supports the binary-safe Redis protocol, so you can use it with any
-Redis version >= 1.2.0.
-
-The library comes with multiple APIs. There is the
-*synchronous API*, the *asynchronous API* and the *reply parsing API*.
-
-## Upgrading to `1.0.0`
-
-Version 1.0.0 marks a stable release of hiredis.
-It includes some minor breaking changes, mostly to make the exposed API more uniform and self-explanatory.
-It also bundles the updated `sds` library, to sync up with upstream and Redis.
-For most applications a recompile against the new hiredis should be enough.
-For code changes see the [Changelog](CHANGELOG.md).
-
-## Upgrading from `<0.9.0`
-
-Version 0.9.0 is a major overhaul of hiredis in every aspect. However, upgrading existing
-code using hiredis should not be a big pain. The key thing to keep in mind when
-upgrading is that hiredis >= 0.9.0 uses a `redisContext*` to keep state, in contrast to
-the stateless 0.0.1 that only has a file descriptor to work with.
-
-## Synchronous API
-
-To consume the synchronous API, there are only a few function calls that need to be introduced:
-
-```c
-redisContext *redisConnect(const char *ip, int port);
-void *redisCommand(redisContext *c, const char *format, ...);
-void freeReplyObject(void *reply);
-```
-
-### Connecting
-
-The function `redisConnect` is used to create a so-called `redisContext`. The
-context is where Hiredis holds state for a connection. The `redisContext`
-struct has an integer `err` field that is non-zero when the connection is in
-an error state. The field `errstr` will contain a string with a description of
-the error. More information on errors can be found in the **Errors** section.
-After trying to connect to Redis using `redisConnect` you should
-check the `err` field to see if establishing the connection was successful:
-```c
-redisContext *c = redisConnect("127.0.0.1", 6379);
-if (c == NULL || c->err) {
- if (c) {
- printf("Error: %s\n", c->errstr);
- // handle error
- } else {
- printf("Can't allocate redis context\n");
- }
-}
-```
-
-*Note: A `redisContext` is not thread-safe.*
-
-### Sending commands
-
-There are several ways to issue commands to Redis. The first that will be introduced is
-`redisCommand`. This function takes a format similar to printf. In the simplest form,
-it is used like this:
-```c
-reply = redisCommand(context, "SET foo bar");
-```
-
-The specifier `%s` interpolates a string in the command, and uses `strlen` to
-determine the length of the string:
-```c
-reply = redisCommand(context, "SET foo %s", value);
-```
-When you need to pass binary safe strings in a command, the `%b` specifier can be
-used. Together with a pointer to the string, it requires a `size_t` length argument
-of the string:
-```c
-reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen);
-```
-Internally, Hiredis splits the command in different arguments and will
-convert it to the protocol used to communicate with Redis.
-One or more spaces separates arguments, so you can use the specifiers
-anywhere in an argument:
-```c
-reply = redisCommand(context, "SET key:%s %s", myid, value);
-```
-
-### Using replies
-
-The return value of `redisCommand` holds a reply when the command was
-successfully executed. When an error occurs, the return value is `NULL` and
-the `err` field in the context will be set (see section on **Errors**).
-Once an error is returned the context cannot be reused and you should set up
-a new connection.
-
-The standard replies that `redisCommand` are of the type `redisReply`. The
-`type` field in the `redisReply` should be used to test what kind of reply
-was received:
-
-* **`REDIS_REPLY_STATUS`**:
- * The command replied with a status reply. The status string can be accessed using `reply->str`.
- The length of this string can be accessed using `reply->len`.
-
-* **`REDIS_REPLY_ERROR`**:
- * The command replied with an error. The error string can be accessed identical to `REDIS_REPLY_STATUS`.
-
-* **`REDIS_REPLY_INTEGER`**:
- * The command replied with an integer. The integer value can be accessed using the
- `reply->integer` field of type `long long`.
-
-* **`REDIS_REPLY_NIL`**:
- * The command replied with a **nil** object. There is no data to access.
-
-* **`REDIS_REPLY_STRING`**:
- * A bulk (string) reply. The value of the reply can be accessed using `reply->str`.
- The length of this string can be accessed using `reply->len`.
-
-* **`REDIS_REPLY_ARRAY`**:
- * A multi bulk reply. The number of elements in the multi bulk reply is stored in
- `reply->elements`. Every element in the multi bulk reply is a `redisReply` object as well
- and can be accessed via `reply->element[..index..]`.
- Redis may reply with nested arrays but this is fully supported.
-
-Replies should be freed using the `freeReplyObject()` function.
-Note that this function will take care of freeing sub-reply objects
-contained in arrays and nested arrays, so there is no need for the user to
-free the sub replies (it is actually harmful and will corrupt the memory).
-
-**Important:** the current version of hiredis (0.10.0) frees replies when the
-asynchronous API is used. This means you should not call `freeReplyObject` when
-you use this API. The reply is cleaned up by hiredis _after_ the callback
-returns. This behavior will probably change in future releases, so make sure to
-keep an eye on the changelog when upgrading (see issue #39).
-
-### Cleaning up
-
-To disconnect and free the context the following function can be used:
-```c
-void redisFree(redisContext *c);
-```
-This function immediately closes the socket and then frees the allocations done in
-creating the context.
-
-### Sending commands (cont'd)
-
-Together with `redisCommand`, the function `redisCommandArgv` can be used to issue commands.
-It has the following prototype:
-```c
-void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
-```
-It takes the number of arguments `argc`, an array of strings `argv` and the lengths of the
-arguments `argvlen`. For convenience, `argvlen` may be set to `NULL` and the function will
-use `strlen(3)` on every argument to determine its length. Obviously, when any of the arguments
-need to be binary safe, the entire array of lengths `argvlen` should be provided.
-
-The return value has the same semantic as `redisCommand`.
-
-### Pipelining
-
-To explain how Hiredis supports pipelining in a blocking connection, there needs to be
-understanding of the internal execution flow.
-
-When any of the functions in the `redisCommand` family is called, Hiredis first formats the
-command according to the Redis protocol. The formatted command is then put in the output buffer
-of the context. This output buffer is dynamic, so it can hold any number of commands.
-After the command is put in the output buffer, `redisGetReply` is called. This function has the
-following two execution paths:
-
-1. The input buffer is non-empty:
- * Try to parse a single reply from the input buffer and return it
- * If no reply could be parsed, continue at *2*
-2. The input buffer is empty:
- * Write the **entire** output buffer to the socket
- * Read from the socket until a single reply could be parsed
-
-The function `redisGetReply` is exported as part of the Hiredis API and can be used when a reply
-is expected on the socket. To pipeline commands, the only things that needs to be done is
-filling up the output buffer. For this cause, two commands can be used that are identical
-to the `redisCommand` family, apart from not returning a reply:
-```c
-void redisAppendCommand(redisContext *c, const char *format, ...);
-void redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
-```
-After calling either function one or more times, `redisGetReply` can be used to receive the
-subsequent replies. The return value for this function is either `REDIS_OK` or `REDIS_ERR`, where
-the latter means an error occurred while reading a reply. Just as with the other commands,
-the `err` field in the context can be used to find out what the cause of this error is.
-
-The following examples shows a simple pipeline (resulting in only a single call to `write(2)` and
-a single call to `read(2)`):
-```c
-redisReply *reply;
-redisAppendCommand(context,"SET foo bar");
-redisAppendCommand(context,"GET foo");
-redisGetReply(context,&reply); // reply for SET
-freeReplyObject(reply);
-redisGetReply(context,&reply); // reply for GET
-freeReplyObject(reply);
-```
-This API can also be used to implement a blocking subscriber:
-```c
-reply = redisCommand(context,"SUBSCRIBE foo");
-freeReplyObject(reply);
-while(redisGetReply(context,&reply) == REDIS_OK) {
- // consume message
- freeReplyObject(reply);
-}
-```
-### Errors
-
-When a function call is not successful, depending on the function either `NULL` or `REDIS_ERR` is
-returned. The `err` field inside the context will be non-zero and set to one of the
-following constants:
-
-* **`REDIS_ERR_IO`**:
- There was an I/O error while creating the connection, trying to write
- to the socket or read from the socket. If you included `errno.h` in your
- application, you can use the global `errno` variable to find out what is
- wrong.
-
-* **`REDIS_ERR_EOF`**:
- The server closed the connection which resulted in an empty read.
-
-* **`REDIS_ERR_PROTOCOL`**:
- There was an error while parsing the protocol.
-
-* **`REDIS_ERR_OTHER`**:
- Any other error. Currently, it is only used when a specified hostname to connect
- to cannot be resolved.
-
-In every case, the `errstr` field in the context will be set to hold a string representation
-of the error.
-
-## Asynchronous API
-
-Hiredis comes with an asynchronous API that works easily with any event library.
-Examples are bundled that show using Hiredis with [libev](http://software.schmorp.de/pkg/libev.html)
-and [libevent](http://monkey.org/~provos/libevent/).
-
-### Connecting
-
-The function `redisAsyncConnect` can be used to establish a non-blocking connection to
-Redis. It returns a pointer to the newly created `redisAsyncContext` struct. The `err` field
-should be checked after creation to see if there were errors creating the connection.
-Because the connection that will be created is non-blocking, the kernel is not able to
-instantly return if the specified host and port is able to accept a connection.
-
-*Note: A `redisAsyncContext` is not thread-safe.*
-
-```c
-redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
-if (c->err) {
- printf("Error: %s\n", c->errstr);
- // handle error
-}
-```
-
-The asynchronous context can hold a disconnect callback function that is called when the
-connection is disconnected (either because of an error or per user request). This function should
-have the following prototype:
-```c
-void(const redisAsyncContext *c, int status);
-```
-On a disconnect, the `status` argument is set to `REDIS_OK` when disconnection was initiated by the
-user, or `REDIS_ERR` when the disconnection was caused by an error. When it is `REDIS_ERR`, the `err`
-field in the context can be accessed to find out the cause of the error.
-
-The context object is always freed after the disconnect callback fired. When a reconnect is needed,
-the disconnect callback is a good point to do so.
-
-Setting the disconnect callback can only be done once per context. For subsequent calls it will
-return `REDIS_ERR`. The function to set the disconnect callback has the following prototype:
-```c
-int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
-```
-`ac->data` may be used to pass user data to this callback, the same can be done for redisConnectCallback.
-### Sending commands and their callbacks
-
-In an asynchronous context, commands are automatically pipelined due to the nature of an event loop.
-Therefore, unlike the synchronous API, there is only a single way to send commands.
-Because commands are sent to Redis asynchronously, issuing a command requires a callback function
-that is called when the reply is received. Reply callbacks should have the following prototype:
-```c
-void(redisAsyncContext *c, void *reply, void *privdata);
-```
-The `privdata` argument can be used to curry arbitrary data to the callback from the point where
-the command is initially queued for execution.
-
-The functions that can be used to issue commands in an asynchronous context are:
-```c
-int redisAsyncCommand(
- redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,
- const char *format, ...);
-int redisAsyncCommandArgv(
- redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,
- int argc, const char **argv, const size_t *argvlen);
-```
-Both functions work like their blocking counterparts. The return value is `REDIS_OK` when the command
-was successfully added to the output buffer and `REDIS_ERR` otherwise. Example: when the connection
-is being disconnected per user-request, no new commands may be added to the output buffer and `REDIS_ERR` is
-returned on calls to the `redisAsyncCommand` family.
-
-If the reply for a command with a `NULL` callback is read, it is immediately freed. When the callback
-for a command is non-`NULL`, the memory is freed immediately following the callback: the reply is only
-valid for the duration of the callback.
-
-All pending callbacks are called with a `NULL` reply when the context encountered an error.
-
-### Disconnecting
-
-An asynchronous connection can be terminated using:
-```c
-void redisAsyncDisconnect(redisAsyncContext *ac);
-```
-When this function is called, the connection is **not** immediately terminated. Instead, new
-commands are no longer accepted and the connection is only terminated when all pending commands
-have been written to the socket, their respective replies have been read and their respective
-callbacks have been executed. After this, the disconnection callback is executed with the
-`REDIS_OK` status and the context object is freed.
-
-### Hooking it up to event library *X*
-
-There are a few hooks that need to be set on the context object after it is created.
-See the `adapters/` directory for bindings to *libev* and *libevent*.
-
-## Reply parsing API
-
-Hiredis comes with a reply parsing API that makes it easy for writing higher
-level language bindings.
-
-The reply parsing API consists of the following functions:
-```c
-redisReader *redisReaderCreate(void);
-void redisReaderFree(redisReader *reader);
-int redisReaderFeed(redisReader *reader, const char *buf, size_t len);
-int redisReaderGetReply(redisReader *reader, void **reply);
-```
-The same set of functions are used internally by hiredis when creating a
-normal Redis context, the above API just exposes it to the user for a direct
-usage.
-
-### Usage
-
-The function `redisReaderCreate` creates a `redisReader` structure that holds a
-buffer with unparsed data and state for the protocol parser.
-
-Incoming data -- most likely from a socket -- can be placed in the internal
-buffer of the `redisReader` using `redisReaderFeed`. This function will make a
-copy of the buffer pointed to by `buf` for `len` bytes. This data is parsed
-when `redisReaderGetReply` is called. This function returns an integer status
-and a reply object (as described above) via `void **reply`. The returned status
-can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went
-wrong (either a protocol error, or an out of memory error).
-
-The parser limits the level of nesting for multi bulk payloads to 7. If the
-multi bulk nesting level is higher than this, the parser returns an error.
-
-### Customizing replies
-
-The function `redisReaderGetReply` creates `redisReply` and makes the function
-argument `reply` point to the created `redisReply` variable. For instance, if
-the response of type `REDIS_REPLY_STATUS` then the `str` field of `redisReply`
-will hold the status as a vanilla C string. However, the functions that are
-responsible for creating instances of the `redisReply` can be customized by
-setting the `fn` field on the `redisReader` struct. This should be done
-immediately after creating the `redisReader`.
-
-For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c)
-uses customized reply object functions to create Ruby objects.
-
-### Reader max buffer
-
-Both when using the Reader API directly or when using it indirectly via a
-normal Redis context, the redisReader structure uses a buffer in order to
-accumulate data from the server.
-Usually this buffer is destroyed when it is empty and is larger than 16
-KiB in order to avoid wasting memory in unused buffers
-
-However when working with very big payloads destroying the buffer may slow
-down performances considerably, so it is possible to modify the max size of
-an idle buffer changing the value of the `maxbuf` field of the reader structure
-to the desired value. The special value of 0 means that there is no maximum
-value for an idle buffer, so the buffer will never get freed.
-
-For instance if you have a normal Redis context you can set the maximum idle
-buffer to zero (unlimited) just with:
-```c
-context->reader->maxbuf = 0;
-```
-This should be done only in order to maximize performances when working with
-large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again
-as soon as possible in order to prevent allocation of useless memory.
-
-## AUTHORS
-
-Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and
-Pieter Noordhuis (pcnoordhuis at gmail) and is released under the BSD license.
-Hiredis is currently maintained by Matt Stancliff (matt at genges dot com) and
-Jan-Erik Rediger (janerik at fnordig dot com)
diff --git a/deps/hiredis/adapters/ae.h b/deps/hiredis/adapters/ae.h
deleted file mode 100644
index 5c551c2ed..000000000
--- a/deps/hiredis/adapters/ae.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HIREDIS_AE_H__
-#define __HIREDIS_AE_H__
-#include <sys/types.h>
-#include <ae.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct redisAeEvents {
- redisAsyncContext *context;
- aeEventLoop *loop;
- int fd;
- int reading, writing;
-} redisAeEvents;
-
-static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
- ((void)el); ((void)fd); ((void)mask);
-
- redisAeEvents *e = (redisAeEvents*)privdata;
- redisAsyncHandleRead(e->context);
-}
-
-static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) {
- ((void)el); ((void)fd); ((void)mask);
-
- redisAeEvents *e = (redisAeEvents*)privdata;
- redisAsyncHandleWrite(e->context);
-}
-
-static void redisAeAddRead(void *privdata) {
- redisAeEvents *e = (redisAeEvents*)privdata;
- aeEventLoop *loop = e->loop;
- if (!e->reading) {
- e->reading = 1;
- aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e);
- }
-}
-
-static void redisAeDelRead(void *privdata) {
- redisAeEvents *e = (redisAeEvents*)privdata;
- aeEventLoop *loop = e->loop;
- if (e->reading) {
- e->reading = 0;
- aeDeleteFileEvent(loop,e->fd,AE_READABLE);
- }
-}
-
-static void redisAeAddWrite(void *privdata) {
- redisAeEvents *e = (redisAeEvents*)privdata;
- aeEventLoop *loop = e->loop;
- if (!e->writing) {
- e->writing = 1;
- aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e);
- }
-}
-
-static void redisAeDelWrite(void *privdata) {
- redisAeEvents *e = (redisAeEvents*)privdata;
- aeEventLoop *loop = e->loop;
- if (e->writing) {
- e->writing = 0;
- aeDeleteFileEvent(loop,e->fd,AE_WRITABLE);
- }
-}
-
-static void redisAeCleanup(void *privdata) {
- redisAeEvents *e = (redisAeEvents*)privdata;
- redisAeDelRead(privdata);
- redisAeDelWrite(privdata);
- free(e);
-}
-
-static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- redisAeEvents *e;
-
- /* Nothing should be attached when something is already attached */
- if (ac->ev.data != NULL)
- return REDIS_ERR;
-
- /* Create container for context and r/w events */
- e = (redisAeEvents*)malloc(sizeof(*e));
- e->context = ac;
- e->loop = loop;
- e->fd = c->fd;
- e->reading = e->writing = 0;
-
- /* Register functions to start/stop listening for events */
- ac->ev.addRead = redisAeAddRead;
- ac->ev.delRead = redisAeDelRead;
- ac->ev.addWrite = redisAeAddWrite;
- ac->ev.delWrite = redisAeDelWrite;
- ac->ev.cleanup = redisAeCleanup;
- ac->ev.data = e;
-
- return REDIS_OK;
-}
-#endif
diff --git a/deps/hiredis/adapters/glib.h b/deps/hiredis/adapters/glib.h
deleted file mode 100644
index e0a6411d3..000000000
--- a/deps/hiredis/adapters/glib.h
+++ /dev/null
@@ -1,153 +0,0 @@
-#ifndef __HIREDIS_GLIB_H__
-#define __HIREDIS_GLIB_H__
-
-#include <glib.h>
-
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct
-{
- GSource source;
- redisAsyncContext *ac;
- GPollFD poll_fd;
-} RedisSource;
-
-static void
-redis_source_add_read (gpointer data)
-{
- RedisSource *source = (RedisSource *)data;
- g_return_if_fail(source);
- source->poll_fd.events |= G_IO_IN;
- g_main_context_wakeup(g_source_get_context((GSource *)data));
-}
-
-static void
-redis_source_del_read (gpointer data)
-{
- RedisSource *source = (RedisSource *)data;
- g_return_if_fail(source);
- source->poll_fd.events &= ~G_IO_IN;
- g_main_context_wakeup(g_source_get_context((GSource *)data));
-}
-
-static void
-redis_source_add_write (gpointer data)
-{
- RedisSource *source = (RedisSource *)data;
- g_return_if_fail(source);
- source->poll_fd.events |= G_IO_OUT;
- g_main_context_wakeup(g_source_get_context((GSource *)data));
-}
-
-static void
-redis_source_del_write (gpointer data)
-{
- RedisSource *source = (RedisSource *)data;
- g_return_if_fail(source);
- source->poll_fd.events &= ~G_IO_OUT;
- g_main_context_wakeup(g_source_get_context((GSource *)data));
-}
-
-static void
-redis_source_cleanup (gpointer data)
-{
- RedisSource *source = (RedisSource *)data;
-
- g_return_if_fail(source);
-
- redis_source_del_read(source);
- redis_source_del_write(source);
- /*
- * It is not our responsibility to remove ourself from the
- * current main loop. However, we will remove the GPollFD.
- */
- if (source->poll_fd.fd >= 0) {
- g_source_remove_poll((GSource *)data, &source->poll_fd);
- source->poll_fd.fd = -1;
- }
-}
-
-static gboolean
-redis_source_prepare (GSource *source,
- gint *timeout_)
-{
- RedisSource *redis = (RedisSource *)source;
- *timeout_ = -1;
- return !!(redis->poll_fd.events & redis->poll_fd.revents);
-}
-
-static gboolean
-redis_source_check (GSource *source)
-{
- RedisSource *redis = (RedisSource *)source;
- return !!(redis->poll_fd.events & redis->poll_fd.revents);
-}
-
-static gboolean
-redis_source_dispatch (GSource *source,
- GSourceFunc callback,
- gpointer user_data)
-{
- RedisSource *redis = (RedisSource *)source;
-
- if ((redis->poll_fd.revents & G_IO_OUT)) {
- redisAsyncHandleWrite(redis->ac);
- redis->poll_fd.revents &= ~G_IO_OUT;
- }
-
- if ((redis->poll_fd.revents & G_IO_IN)) {
- redisAsyncHandleRead(redis->ac);
- redis->poll_fd.revents &= ~G_IO_IN;
- }
-
- if (callback) {
- return callback(user_data);
- }
-
- return TRUE;
-}
-
-static void
-redis_source_finalize (GSource *source)
-{
- RedisSource *redis = (RedisSource *)source;
-
- if (redis->poll_fd.fd >= 0) {
- g_source_remove_poll(source, &redis->poll_fd);
- redis->poll_fd.fd = -1;
- }
-}
-
-static GSource *
-redis_source_new (redisAsyncContext *ac)
-{
- static GSourceFuncs source_funcs = {
- .prepare = redis_source_prepare,
- .check = redis_source_check,
- .dispatch = redis_source_dispatch,
- .finalize = redis_source_finalize,
- };
- redisContext *c = &ac->c;
- RedisSource *source;
-
- g_return_val_if_fail(ac != NULL, NULL);
-
- source = (RedisSource *)g_source_new(&source_funcs, sizeof *source);
- source->ac = ac;
- source->poll_fd.fd = c->fd;
- source->poll_fd.events = 0;
- source->poll_fd.revents = 0;
- g_source_add_poll((GSource *)source, &source->poll_fd);
-
- ac->ev.addRead = redis_source_add_read;
- ac->ev.delRead = redis_source_del_read;
- ac->ev.addWrite = redis_source_add_write;
- ac->ev.delWrite = redis_source_del_write;
- ac->ev.cleanup = redis_source_cleanup;
- ac->ev.data = source;
-
- return (GSource *)source;
-}
-
-#endif /* __HIREDIS_GLIB_H__ */
diff --git a/deps/hiredis/adapters/ivykis.h b/deps/hiredis/adapters/ivykis.h
deleted file mode 100644
index 6a12a868a..000000000
--- a/deps/hiredis/adapters/ivykis.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef __HIREDIS_IVYKIS_H__
-#define __HIREDIS_IVYKIS_H__
-#include <iv.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct redisIvykisEvents {
- redisAsyncContext *context;
- struct iv_fd fd;
-} redisIvykisEvents;
-
-static void redisIvykisReadEvent(void *arg) {
- redisAsyncContext *context = (redisAsyncContext *)arg;
- redisAsyncHandleRead(context);
-}
-
-static void redisIvykisWriteEvent(void *arg) {
- redisAsyncContext *context = (redisAsyncContext *)arg;
- redisAsyncHandleWrite(context);
-}
-
-static void redisIvykisAddRead(void *privdata) {
- redisIvykisEvents *e = (redisIvykisEvents*)privdata;
- iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent);
-}
-
-static void redisIvykisDelRead(void *privdata) {
- redisIvykisEvents *e = (redisIvykisEvents*)privdata;
- iv_fd_set_handler_in(&e->fd, NULL);
-}
-
-static void redisIvykisAddWrite(void *privdata) {
- redisIvykisEvents *e = (redisIvykisEvents*)privdata;
- iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent);
-}
-
-static void redisIvykisDelWrite(void *privdata) {
- redisIvykisEvents *e = (redisIvykisEvents*)privdata;
- iv_fd_set_handler_out(&e->fd, NULL);
-}
-
-static void redisIvykisCleanup(void *privdata) {
- redisIvykisEvents *e = (redisIvykisEvents*)privdata;
-
- iv_fd_unregister(&e->fd);
- free(e);
-}
-
-static int redisIvykisAttach(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- redisIvykisEvents *e;
-
- /* Nothing should be attached when something is already attached */
- if (ac->ev.data != NULL)
- return REDIS_ERR;
-
- /* Create container for context and r/w events */
- e = (redisIvykisEvents*)malloc(sizeof(*e));
- e->context = ac;
-
- /* Register functions to start/stop listening for events */
- ac->ev.addRead = redisIvykisAddRead;
- ac->ev.delRead = redisIvykisDelRead;
- ac->ev.addWrite = redisIvykisAddWrite;
- ac->ev.delWrite = redisIvykisDelWrite;
- ac->ev.cleanup = redisIvykisCleanup;
- ac->ev.data = e;
-
- /* Initialize and install read/write events */
- IV_FD_INIT(&e->fd);
- e->fd.fd = c->fd;
- e->fd.handler_in = redisIvykisReadEvent;
- e->fd.handler_out = redisIvykisWriteEvent;
- e->fd.handler_err = NULL;
- e->fd.cookie = e->context;
-
- iv_fd_register(&e->fd);
-
- return REDIS_OK;
-}
-#endif
diff --git a/deps/hiredis/adapters/libev.h b/deps/hiredis/adapters/libev.h
deleted file mode 100644
index 2bf8d521f..000000000
--- a/deps/hiredis/adapters/libev.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HIREDIS_LIBEV_H__
-#define __HIREDIS_LIBEV_H__
-#include <stdlib.h>
-#include <sys/types.h>
-#include <ev.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct redisLibevEvents {
- redisAsyncContext *context;
- struct ev_loop *loop;
- int reading, writing;
- ev_io rev, wev;
-} redisLibevEvents;
-
-static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) {
-#if EV_MULTIPLICITY
- ((void)loop);
-#endif
- ((void)revents);
-
- redisLibevEvents *e = (redisLibevEvents*)watcher->data;
- redisAsyncHandleRead(e->context);
-}
-
-static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) {
-#if EV_MULTIPLICITY
- ((void)loop);
-#endif
- ((void)revents);
-
- redisLibevEvents *e = (redisLibevEvents*)watcher->data;
- redisAsyncHandleWrite(e->context);
-}
-
-static void redisLibevAddRead(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- struct ev_loop *loop = e->loop;
- ((void)loop);
- if (!e->reading) {
- e->reading = 1;
- ev_io_start(EV_A_ &e->rev);
- }
-}
-
-static void redisLibevDelRead(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- struct ev_loop *loop = e->loop;
- ((void)loop);
- if (e->reading) {
- e->reading = 0;
- ev_io_stop(EV_A_ &e->rev);
- }
-}
-
-static void redisLibevAddWrite(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- struct ev_loop *loop = e->loop;
- ((void)loop);
- if (!e->writing) {
- e->writing = 1;
- ev_io_start(EV_A_ &e->wev);
- }
-}
-
-static void redisLibevDelWrite(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- struct ev_loop *loop = e->loop;
- ((void)loop);
- if (e->writing) {
- e->writing = 0;
- ev_io_stop(EV_A_ &e->wev);
- }
-}
-
-static void redisLibevCleanup(void *privdata) {
- redisLibevEvents *e = (redisLibevEvents*)privdata;
- redisLibevDelRead(privdata);
- redisLibevDelWrite(privdata);
- free(e);
-}
-
-static int redisLibevAttach(EV_P_ redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- redisLibevEvents *e;
-
- /* Nothing should be attached when something is already attached */
- if (ac->ev.data != NULL)
- return REDIS_ERR;
-
- /* Create container for context and r/w events */
- e = (redisLibevEvents*)malloc(sizeof(*e));
- e->context = ac;
-#if EV_MULTIPLICITY
- e->loop = loop;
-#else
- e->loop = NULL;
-#endif
- e->reading = e->writing = 0;
- e->rev.data = e;
- e->wev.data = e;
-
- /* Register functions to start/stop listening for events */
- ac->ev.addRead = redisLibevAddRead;
- ac->ev.delRead = redisLibevDelRead;
- ac->ev.addWrite = redisLibevAddWrite;
- ac->ev.delWrite = redisLibevDelWrite;
- ac->ev.cleanup = redisLibevCleanup;
- ac->ev.data = e;
-
- /* Initialize read/write events */
- ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ);
- ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE);
- return REDIS_OK;
-}
-
-#endif
diff --git a/deps/hiredis/adapters/libevent.h b/deps/hiredis/adapters/libevent.h
deleted file mode 100644
index a4952776c..000000000
--- a/deps/hiredis/adapters/libevent.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HIREDIS_LIBEVENT_H__
-#define __HIREDIS_LIBEVENT_H__
-#include <event2/event.h>
-#include "../hiredis.h"
-#include "../async.h"
-
-#define REDIS_LIBEVENT_DELETED 0x01
-#define REDIS_LIBEVENT_ENTERED 0x02
-
-typedef struct redisLibeventEvents {
- redisAsyncContext *context;
- struct event *ev;
- struct event_base *base;
- struct timeval tv;
- short flags;
- short state;
-} redisLibeventEvents;
-
-static void redisLibeventDestroy(redisLibeventEvents *e) {
- free(e);
-}
-
-static void redisLibeventHandler(int fd, short event, void *arg) {
- ((void)fd);
- redisLibeventEvents *e = (redisLibeventEvents*)arg;
- e->state |= REDIS_LIBEVENT_ENTERED;
-
- #define CHECK_DELETED() if (e->state & REDIS_LIBEVENT_DELETED) {\
- redisLibeventDestroy(e);\
- return; \
- }
-
- if ((event & EV_TIMEOUT) && (e->state & REDIS_LIBEVENT_DELETED) == 0) {
- redisAsyncHandleTimeout(e->context);
- CHECK_DELETED();
- }
-
- if ((event & EV_READ) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) {
- redisAsyncHandleRead(e->context);
- CHECK_DELETED();
- }
-
- if ((event & EV_WRITE) && e->context && (e->state & REDIS_LIBEVENT_DELETED) == 0) {
- redisAsyncHandleWrite(e->context);
- CHECK_DELETED();
- }
-
- e->state &= ~REDIS_LIBEVENT_ENTERED;
- #undef CHECK_DELETED
-}
-
-static void redisLibeventUpdate(void *privdata, short flag, int isRemove) {
- redisLibeventEvents *e = (redisLibeventEvents *)privdata;
- const struct timeval *tv = e->tv.tv_sec || e->tv.tv_usec ? &e->tv : NULL;
-
- if (isRemove) {
- if ((e->flags & flag) == 0) {
- return;
- } else {
- e->flags &= ~flag;
- }
- } else {
- if (e->flags & flag) {
- return;
- } else {
- e->flags |= flag;
- }
- }
-
- event_del(e->ev);
- event_assign(e->ev, e->base, e->context->c.fd, e->flags | EV_PERSIST,
- redisLibeventHandler, privdata);
- event_add(e->ev, tv);
-}
-
-static void redisLibeventAddRead(void *privdata) {
- redisLibeventUpdate(privdata, EV_READ, 0);
-}
-
-static void redisLibeventDelRead(void *privdata) {
- redisLibeventUpdate(privdata, EV_READ, 1);
-}
-
-static void redisLibeventAddWrite(void *privdata) {
- redisLibeventUpdate(privdata, EV_WRITE, 0);
-}
-
-static void redisLibeventDelWrite(void *privdata) {
- redisLibeventUpdate(privdata, EV_WRITE, 1);
-}
-
-static void redisLibeventCleanup(void *privdata) {
- redisLibeventEvents *e = (redisLibeventEvents*)privdata;
- if (!e) {
- return;
- }
- event_del(e->ev);
- event_free(e->ev);
- e->ev = NULL;
-
- if (e->state & REDIS_LIBEVENT_ENTERED) {
- e->state |= REDIS_LIBEVENT_DELETED;
- } else {
- redisLibeventDestroy(e);
- }
-}
-
-static void redisLibeventSetTimeout(void *privdata, struct timeval tv) {
- redisLibeventEvents *e = (redisLibeventEvents *)privdata;
- short flags = e->flags;
- e->flags = 0;
- e->tv = tv;
- redisLibeventUpdate(e, flags, 0);
-}
-
-static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) {
- redisContext *c = &(ac->c);
- redisLibeventEvents *e;
-
- /* Nothing should be attached when something is already attached */
- if (ac->ev.data != NULL)
- return REDIS_ERR;
-
- /* Create container for context and r/w events */
- e = (redisLibeventEvents*)calloc(1, sizeof(*e));
- e->context = ac;
-
- /* Register functions to start/stop listening for events */
- ac->ev.addRead = redisLibeventAddRead;
- ac->ev.delRead = redisLibeventDelRead;
- ac->ev.addWrite = redisLibeventAddWrite;
- ac->ev.delWrite = redisLibeventDelWrite;
- ac->ev.cleanup = redisLibeventCleanup;
- ac->ev.scheduleTimer = redisLibeventSetTimeout;
- ac->ev.data = e;
-
- /* Initialize and install read/write events */
- e->ev = event_new(base, c->fd, EV_READ | EV_WRITE, redisLibeventHandler, e);
- e->base = base;
- return REDIS_OK;
-}
-#endif
diff --git a/deps/hiredis/adapters/libuv.h b/deps/hiredis/adapters/libuv.h
deleted file mode 100644
index 39ef7cf5e..000000000
--- a/deps/hiredis/adapters/libuv.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef __HIREDIS_LIBUV_H__
-#define __HIREDIS_LIBUV_H__
-#include <stdlib.h>
-#include <uv.h>
-#include "../hiredis.h"
-#include "../async.h"
-#include <string.h>
-
-typedef struct redisLibuvEvents {
- redisAsyncContext* context;
- uv_poll_t handle;
- int events;
-} redisLibuvEvents;
-
-
-static void redisLibuvPoll(uv_poll_t* handle, int status, int events) {
- redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
- int ev = (status ? p->events : events);
-
- if (p->context != NULL && (ev & UV_READABLE)) {
- redisAsyncHandleRead(p->context);
- }
- if (p->context != NULL && (ev & UV_WRITABLE)) {
- redisAsyncHandleWrite(p->context);
- }
-}
-
-
-static void redisLibuvAddRead(void *privdata) {
- redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
- p->events |= UV_READABLE;
-
- uv_poll_start(&p->handle, p->events, redisLibuvPoll);
-}
-
-
-static void redisLibuvDelRead(void *privdata) {
- redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
- p->events &= ~UV_READABLE;
-
- if (p->events) {
- uv_poll_start(&p->handle, p->events, redisLibuvPoll);
- } else {
- uv_poll_stop(&p->handle);
- }
-}
-
-
-static void redisLibuvAddWrite(void *privdata) {
- redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
- p->events |= UV_WRITABLE;
-
- uv_poll_start(&p->handle, p->events, redisLibuvPoll);
-}
-
-
-static void redisLibuvDelWrite(void *privdata) {
- redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
- p->events &= ~UV_WRITABLE;
-
- if (p->events) {
- uv_poll_start(&p->handle, p->events, redisLibuvPoll);
- } else {
- uv_poll_stop(&p->handle);
- }
-}
-
-
-static void on_close(uv_handle_t* handle) {
- redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
-
- free(p);
-}
-
-
-static void redisLibuvCleanup(void *privdata) {
- redisLibuvEvents* p = (redisLibuvEvents*)privdata;
-
- p->context = NULL; // indicate that context might no longer exist
- uv_close((uv_handle_t*)&p->handle, on_close);
-}
-
-
-static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
- redisContext *c = &(ac->c);
-
- if (ac->ev.data != NULL) {
- return REDIS_ERR;
- }
-
- ac->ev.addRead = redisLibuvAddRead;
- ac->ev.delRead = redisLibuvDelRead;
- ac->ev.addWrite = redisLibuvAddWrite;
- ac->ev.delWrite = redisLibuvDelWrite;
- ac->ev.cleanup = redisLibuvCleanup;
-
- redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p));
-
- if (!p) {
- return REDIS_ERR;
- }
-
- memset(p, 0, sizeof(*p));
-
- if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
- return REDIS_ERR;
- }
-
- ac->ev.data = p;
- p->handle.data = p;
- p->context = ac;
-
- return REDIS_OK;
-}
-#endif
diff --git a/deps/hiredis/adapters/macosx.h b/deps/hiredis/adapters/macosx.h
deleted file mode 100644
index 72121f606..000000000
--- a/deps/hiredis/adapters/macosx.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//
-// Created by Дмитрий Бахвалов on 13.07.15.
-// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved.
-//
-
-#ifndef __HIREDIS_MACOSX_H__
-#define __HIREDIS_MACOSX_H__
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include "../hiredis.h"
-#include "../async.h"
-
-typedef struct {
- redisAsyncContext *context;
- CFSocketRef socketRef;
- CFRunLoopSourceRef sourceRef;
-} RedisRunLoop;
-
-static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) {
- if( redisRunLoop != NULL ) {
- if( redisRunLoop->sourceRef != NULL ) {
- CFRunLoopSourceInvalidate(redisRunLoop->sourceRef);
- CFRelease(redisRunLoop->sourceRef);
- }
- if( redisRunLoop->socketRef != NULL ) {
- CFSocketInvalidate(redisRunLoop->socketRef);
- CFRelease(redisRunLoop->socketRef);
- }
- free(redisRunLoop);
- }
- return REDIS_ERR;
-}
-
-static void redisMacOSAddRead(void *privdata) {
- RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
- CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
-}
-
-static void redisMacOSDelRead(void *privdata) {
- RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
- CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack);
-}
-
-static void redisMacOSAddWrite(void *privdata) {
- RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
- CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
-}
-
-static void redisMacOSDelWrite(void *privdata) {
- RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
- CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack);
-}
-
-static void redisMacOSCleanup(void *privdata) {
- RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata;
- freeRedisRunLoop(redisRunLoop);
-}
-
-static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) {
- redisAsyncContext* context = (redisAsyncContext*) info;
-
- switch (callbackType) {
- case kCFSocketReadCallBack:
- redisAsyncHandleRead(context);
- break;
-
- case kCFSocketWriteCallBack:
- redisAsyncHandleWrite(context);
- break;
-
- default:
- break;
- }
-}
-
-static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) {
- redisContext *redisCtx = &(redisAsyncCtx->c);
-
- /* Nothing should be attached when something is already attached */
- if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR;
-
- RedisRunLoop* redisRunLoop = (RedisRunLoop*) calloc(1, sizeof(RedisRunLoop));
- if( !redisRunLoop ) return REDIS_ERR;
-
- /* Setup redis stuff */
- redisRunLoop->context = redisAsyncCtx;
-
- redisAsyncCtx->ev.addRead = redisMacOSAddRead;
- redisAsyncCtx->ev.delRead = redisMacOSDelRead;
- redisAsyncCtx->ev.addWrite = redisMacOSAddWrite;
- redisAsyncCtx->ev.delWrite = redisMacOSDelWrite;
- redisAsyncCtx->ev.cleanup = redisMacOSCleanup;
- redisAsyncCtx->ev.data = redisRunLoop;
-
- /* Initialize and install read/write events */
- CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL };
-
- redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd,
- kCFSocketReadCallBack | kCFSocketWriteCallBack,
- redisMacOSAsyncCallback,
- &socketCtx);
- if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop);
-
- redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0);
- if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop);
-
- CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode);
-
- return REDIS_OK;
-}
-
-#endif
-
diff --git a/deps/hiredis/adapters/qt.h b/deps/hiredis/adapters/qt.h
deleted file mode 100644
index 5cc02e6ce..000000000
--- a/deps/hiredis/adapters/qt.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*-
- * Copyright (C) 2014 Pietro Cerutti <gahr@gahr.ch>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef __HIREDIS_QT_H__
-#define __HIREDIS_QT_H__
-#include <QSocketNotifier>
-#include "../async.h"
-
-static void RedisQtAddRead(void *);
-static void RedisQtDelRead(void *);
-static void RedisQtAddWrite(void *);
-static void RedisQtDelWrite(void *);
-static void RedisQtCleanup(void *);
-
-class RedisQtAdapter : public QObject {
-
- Q_OBJECT
-
- friend
- void RedisQtAddRead(void * adapter) {
- RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
- a->addRead();
- }
-
- friend
- void RedisQtDelRead(void * adapter) {
- RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
- a->delRead();
- }
-
- friend
- void RedisQtAddWrite(void * adapter) {
- RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
- a->addWrite();
- }
-
- friend
- void RedisQtDelWrite(void * adapter) {
- RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
- a->delWrite();
- }
-
- friend
- void RedisQtCleanup(void * adapter) {
- RedisQtAdapter * a = static_cast<RedisQtAdapter *>(adapter);
- a->cleanup();
- }
-
- public:
- RedisQtAdapter(QObject * parent = 0)
- : QObject(parent), m_ctx(0), m_read(0), m_write(0) { }
-
- ~RedisQtAdapter() {
- if (m_ctx != 0) {
- m_ctx->ev.data = NULL;
- }
- }
-
- int setContext(redisAsyncContext * ac) {
- if (ac->ev.data != NULL) {
- return REDIS_ERR;
- }
- m_ctx = ac;
- m_ctx->ev.data = this;
- m_ctx->ev.addRead = RedisQtAddRead;
- m_ctx->ev.delRead = RedisQtDelRead;
- m_ctx->ev.addWrite = RedisQtAddWrite;
- m_ctx->ev.delWrite = RedisQtDelWrite;
- m_ctx->ev.cleanup = RedisQtCleanup;
- return REDIS_OK;
- }
-
- private:
- void addRead() {
- if (m_read) return;
- m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0);
- connect(m_read, SIGNAL(activated(int)), this, SLOT(read()));
- }
-
- void delRead() {
- if (!m_read) return;
- delete m_read;
- m_read = 0;
- }
-
- void addWrite() {
- if (m_write) return;
- m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0);
- connect(m_write, SIGNAL(activated(int)), this, SLOT(write()));
- }
-
- void delWrite() {
- if (!m_write) return;
- delete m_write;
- m_write = 0;
- }
-
- void cleanup() {
- delRead();
- delWrite();
- }
-
- private slots:
- void read() { redisAsyncHandleRead(m_ctx); }
- void write() { redisAsyncHandleWrite(m_ctx); }
-
- private:
- redisAsyncContext * m_ctx;
- QSocketNotifier * m_read;
- QSocketNotifier * m_write;
-};
-
-#endif /* !__HIREDIS_QT_H__ */
diff --git a/deps/hiredis/appveyor.yml b/deps/hiredis/appveyor.yml
deleted file mode 100644
index 5b43fdbeb..000000000
--- a/deps/hiredis/appveyor.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-# Appveyor configuration file for CI build of hiredis on Windows (under Cygwin)
-environment:
- matrix:
- - CYG_BASH: C:\cygwin64\bin\bash
- CC: gcc
- - CYG_BASH: C:\cygwin\bin\bash
- CC: gcc
- CFLAGS: -m32
- CXXFLAGS: -m32
- LDFLAGS: -m32
-
-clone_depth: 1
-
-# Attempt to ensure we don't try to convert line endings to Win32 CRLF as this will cause build to fail
-init:
- - git config --global core.autocrlf input
-
-# Install needed build dependencies
-install:
- - '%CYG_BASH% -lc "cygcheck -dc cygwin"'
-
-build_script:
- - 'echo building...'
- - '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; mkdir build && cd build && cmake .. -G \"Unix Makefiles\" && make VERBOSE=1"'
diff --git a/deps/hiredis/async.c b/deps/hiredis/async.c
deleted file mode 100644
index 4f422d566..000000000
--- a/deps/hiredis/async.c
+++ /dev/null
@@ -1,766 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "fmacros.h"
-#include <stdlib.h>
-#include <string.h>
-#ifndef _MSC_VER
-#include <strings.h>
-#endif
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include "async.h"
-#include "net.h"
-#include "dict.c"
-#include "sds.h"
-#include "win32.h"
-
-#include "async_private.h"
-
-/* Forward declaration of function in hiredis.c */
-int __redisAppendCommand(redisContext *c, const char *cmd, size_t len);
-
-/* Functions managing dictionary of callbacks for pub/sub. */
-static unsigned int callbackHash(const void *key) {
- return dictGenHashFunction((const unsigned char *)key,
- sdslen((const sds)key));
-}
-
-static void *callbackValDup(void *privdata, const void *src) {
- ((void) privdata);
- redisCallback *dup = malloc(sizeof(*dup));
- memcpy(dup,src,sizeof(*dup));
- return dup;
-}
-
-static int callbackKeyCompare(void *privdata, const void *key1, const void *key2) {
- int l1, l2;
- ((void) privdata);
-
- l1 = sdslen((const sds)key1);
- l2 = sdslen((const sds)key2);
- if (l1 != l2) return 0;
- return memcmp(key1,key2,l1) == 0;
-}
-
-static void callbackKeyDestructor(void *privdata, void *key) {
- ((void) privdata);
- sdsfree((sds)key);
-}
-
-static void callbackValDestructor(void *privdata, void *val) {
- ((void) privdata);
- free(val);
-}
-
-static dictType callbackDict = {
- callbackHash,
- NULL,
- callbackValDup,
- callbackKeyCompare,
- callbackKeyDestructor,
- callbackValDestructor
-};
-
-static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
- redisAsyncContext *ac;
-
- ac = realloc(c,sizeof(redisAsyncContext));
- if (ac == NULL)
- return NULL;
-
- c = &(ac->c);
-
- /* The regular connect functions will always set the flag REDIS_CONNECTED.
- * For the async API, we want to wait until the first write event is
- * received up before setting this flag, so reset it here. */
- c->flags &= ~REDIS_CONNECTED;
-
- ac->err = 0;
- ac->errstr = NULL;
- ac->data = NULL;
-
- ac->ev.data = NULL;
- ac->ev.addRead = NULL;
- ac->ev.delRead = NULL;
- ac->ev.addWrite = NULL;
- ac->ev.delWrite = NULL;
- ac->ev.cleanup = NULL;
- ac->ev.scheduleTimer = NULL;
-
- ac->onConnect = NULL;
- ac->onDisconnect = NULL;
-
- ac->replies.head = NULL;
- ac->replies.tail = NULL;
- ac->sub.invalid.head = NULL;
- ac->sub.invalid.tail = NULL;
- ac->sub.channels = dictCreate(&callbackDict,NULL);
- ac->sub.patterns = dictCreate(&callbackDict,NULL);
- return ac;
-}
-
-/* We want the error field to be accessible directly instead of requiring
- * an indirection to the redisContext struct. */
-static void __redisAsyncCopyError(redisAsyncContext *ac) {
- if (!ac)
- return;
-
- redisContext *c = &(ac->c);
- ac->err = c->err;
- ac->errstr = c->errstr;
-}
-
-redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options) {
- redisOptions myOptions = *options;
- redisContext *c;
- redisAsyncContext *ac;
-
- myOptions.options |= REDIS_OPT_NONBLOCK;
- c = redisConnectWithOptions(&myOptions);
- if (c == NULL) {
- return NULL;
- }
- ac = redisAsyncInitialize(c);
- if (ac == NULL) {
- redisFree(c);
- return NULL;
- }
- __redisAsyncCopyError(ac);
- return ac;
-}
-
-redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, ip, port);
- return redisAsyncConnectWithOptions(&options);
-}
-
-redisAsyncContext *redisAsyncConnectBind(const char *ip, int port,
- const char *source_addr) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, ip, port);
- options.endpoint.tcp.source_addr = source_addr;
- return redisAsyncConnectWithOptions(&options);
-}
-
-redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
- const char *source_addr) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, ip, port);
- options.options |= REDIS_OPT_REUSEADDR;
- options.endpoint.tcp.source_addr = source_addr;
- return redisAsyncConnectWithOptions(&options);
-}
-
-redisAsyncContext *redisAsyncConnectUnix(const char *path) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_UNIX(&options, path);
- return redisAsyncConnectWithOptions(&options);
-}
-
-int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn) {
- if (ac->onConnect == NULL) {
- ac->onConnect = fn;
-
- /* The common way to detect an established connection is to wait for
- * the first write event to be fired. This assumes the related event
- * library functions are already set. */
- _EL_ADD_WRITE(ac);
- return REDIS_OK;
- }
- return REDIS_ERR;
-}
-
-int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn) {
- if (ac->onDisconnect == NULL) {
- ac->onDisconnect = fn;
- return REDIS_OK;
- }
- return REDIS_ERR;
-}
-
-/* Helper functions to push/shift callbacks */
-static int __redisPushCallback(redisCallbackList *list, redisCallback *source) {
- redisCallback *cb;
-
- /* Copy callback from stack to heap */
- cb = malloc(sizeof(*cb));
- if (cb == NULL)
- return REDIS_ERR_OOM;
-
- if (source != NULL) {
- memcpy(cb,source,sizeof(*cb));
- cb->next = NULL;
- }
-
- /* Store callback in list */
- if (list->head == NULL)
- list->head = cb;
- if (list->tail != NULL)
- list->tail->next = cb;
- list->tail = cb;
- return REDIS_OK;
-}
-
-static int __redisShiftCallback(redisCallbackList *list, redisCallback *target) {
- redisCallback *cb = list->head;
- if (cb != NULL) {
- list->head = cb->next;
- if (cb == list->tail)
- list->tail = NULL;
-
- /* Copy callback from heap to stack */
- if (target != NULL)
- memcpy(target,cb,sizeof(*cb));
- free(cb);
- return REDIS_OK;
- }
- return REDIS_ERR;
-}
-
-static void __redisRunCallback(redisAsyncContext *ac, redisCallback *cb, redisReply *reply) {
- redisContext *c = &(ac->c);
- if (cb->fn != NULL) {
- c->flags |= REDIS_IN_CALLBACK;
- cb->fn(ac,reply,cb->privdata);
- c->flags &= ~REDIS_IN_CALLBACK;
- }
-}
-
-/* Helper function to free the context. */
-static void __redisAsyncFree(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- redisCallback cb;
- dictIterator *it;
- dictEntry *de;
-
- /* Execute pending callbacks with NULL reply. */
- while (__redisShiftCallback(&ac->replies,&cb) == REDIS_OK)
- __redisRunCallback(ac,&cb,NULL);
-
- /* Execute callbacks for invalid commands */
- while (__redisShiftCallback(&ac->sub.invalid,&cb) == REDIS_OK)
- __redisRunCallback(ac,&cb,NULL);
-
- /* Run subscription callbacks callbacks with NULL reply */
- it = dictGetIterator(ac->sub.channels);
- while ((de = dictNext(it)) != NULL)
- __redisRunCallback(ac,dictGetEntryVal(de),NULL);
- dictReleaseIterator(it);
- dictRelease(ac->sub.channels);
-
- it = dictGetIterator(ac->sub.patterns);
- while ((de = dictNext(it)) != NULL)
- __redisRunCallback(ac,dictGetEntryVal(de),NULL);
- dictReleaseIterator(it);
- dictRelease(ac->sub.patterns);
-
- /* Signal event lib to clean up */
- _EL_CLEANUP(ac);
-
- /* Execute disconnect callback. When redisAsyncFree() initiated destroying
- * this context, the status will always be REDIS_OK. */
- if (ac->onDisconnect && (c->flags & REDIS_CONNECTED)) {
- if (c->flags & REDIS_FREEING) {
- ac->onDisconnect(ac,REDIS_OK);
- } else {
- ac->onDisconnect(ac,(ac->err == 0) ? REDIS_OK : REDIS_ERR);
- }
- }
-
- /* Cleanup self */
- redisFree(c);
-}
-
-/* Free the async context. When this function is called from a callback,
- * control needs to be returned to redisProcessCallbacks() before actual
- * free'ing. To do so, a flag is set on the context which is picked up by
- * redisProcessCallbacks(). Otherwise, the context is immediately free'd. */
-void redisAsyncFree(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- c->flags |= REDIS_FREEING;
- if (!(c->flags & REDIS_IN_CALLBACK))
- __redisAsyncFree(ac);
-}
-
-/* Helper function to make the disconnect happen and clean up. */
-void __redisAsyncDisconnect(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
-
- /* Make sure error is accessible if there is any */
- __redisAsyncCopyError(ac);
-
- if (ac->err == 0) {
- /* For clean disconnects, there should be no pending callbacks. */
- int ret = __redisShiftCallback(&ac->replies,NULL);
- assert(ret == REDIS_ERR);
- } else {
- /* Disconnection is caused by an error, make sure that pending
- * callbacks cannot call new commands. */
- c->flags |= REDIS_DISCONNECTING;
- }
-
- /* cleanup event library on disconnect.
- * this is safe to call multiple times */
- _EL_CLEANUP(ac);
-
- /* For non-clean disconnects, __redisAsyncFree() will execute pending
- * callbacks with a NULL-reply. */
- if (!(c->flags & REDIS_NO_AUTO_FREE)) {
- __redisAsyncFree(ac);
- }
-}
-
-/* Tries to do a clean disconnect from Redis, meaning it stops new commands
- * from being issued, but tries to flush the output buffer and execute
- * callbacks for all remaining replies. When this function is called from a
- * callback, there might be more replies and we can safely defer disconnecting
- * to redisProcessCallbacks(). Otherwise, we can only disconnect immediately
- * when there are no pending callbacks. */
-void redisAsyncDisconnect(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- c->flags |= REDIS_DISCONNECTING;
-
- /** unset the auto-free flag here, because disconnect undoes this */
- c->flags &= ~REDIS_NO_AUTO_FREE;
- if (!(c->flags & REDIS_IN_CALLBACK) && ac->replies.head == NULL)
- __redisAsyncDisconnect(ac);
-}
-
-static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply, redisCallback *dstcb) {
- redisContext *c = &(ac->c);
- dict *callbacks;
- redisCallback *cb;
- dictEntry *de;
- int pvariant;
- char *stype;
- sds sname;
-
- /* Custom reply functions are not supported for pub/sub. This will fail
- * very hard when they are used... */
- if (reply->type == REDIS_REPLY_ARRAY) {
- assert(reply->elements >= 2);
- assert(reply->element[0]->type == REDIS_REPLY_STRING);
- stype = reply->element[0]->str;
- pvariant = (tolower(stype[0]) == 'p') ? 1 : 0;
-
- if (pvariant)
- callbacks = ac->sub.patterns;
- else
- callbacks = ac->sub.channels;
-
- /* Locate the right callback */
- assert(reply->element[1]->type == REDIS_REPLY_STRING);
- sname = sdsnewlen(reply->element[1]->str,reply->element[1]->len);
- de = dictFind(callbacks,sname);
- if (de != NULL) {
- cb = dictGetEntryVal(de);
-
- /* If this is an subscribe reply decrease pending counter. */
- if (strcasecmp(stype+pvariant,"subscribe") == 0) {
- cb->pending_subs -= 1;
- }
-
- memcpy(dstcb,cb,sizeof(*dstcb));
-
- /* If this is an unsubscribe message, remove it. */
- if (strcasecmp(stype+pvariant,"unsubscribe") == 0) {
- if (cb->pending_subs == 0)
- dictDelete(callbacks,sname);
-
- /* If this was the last unsubscribe message, revert to
- * non-subscribe mode. */
- assert(reply->element[2]->type == REDIS_REPLY_INTEGER);
-
- /* Unset subscribed flag only when no pipelined pending subscribe. */
- if (reply->element[2]->integer == 0
- && dictSize(ac->sub.channels) == 0
- && dictSize(ac->sub.patterns) == 0)
- c->flags &= ~REDIS_SUBSCRIBED;
- }
- }
- sdsfree(sname);
- } else {
- /* Shift callback for invalid commands. */
- __redisShiftCallback(&ac->sub.invalid,dstcb);
- }
- return REDIS_OK;
-}
-
-void redisProcessCallbacks(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- redisCallback cb = {NULL, NULL, 0, NULL};
- void *reply = NULL;
- int status;
-
- while((status = redisGetReply(c,&reply)) == REDIS_OK) {
- if (reply == NULL) {
- /* When the connection is being disconnected and there are
- * no more replies, this is the cue to really disconnect. */
- if (c->flags & REDIS_DISCONNECTING && sdslen(c->obuf) == 0
- && ac->replies.head == NULL) {
- __redisAsyncDisconnect(ac);
- return;
- }
-
- /* If monitor mode, repush callback */
- if(c->flags & REDIS_MONITORING) {
- __redisPushCallback(&ac->replies,&cb);
- }
-
- /* When the connection is not being disconnected, simply stop
- * trying to get replies and wait for the next loop tick. */
- break;
- }
-
- /* Even if the context is subscribed, pending regular callbacks will
- * get a reply before pub/sub messages arrive. */
- if (__redisShiftCallback(&ac->replies,&cb) != REDIS_OK) {
- /*
- * A spontaneous reply in a not-subscribed context can be the error
- * reply that is sent when a new connection exceeds the maximum
- * number of allowed connections on the server side.
- *
- * This is seen as an error instead of a regular reply because the
- * server closes the connection after sending it.
- *
- * To prevent the error from being overwritten by an EOF error the
- * connection is closed here. See issue #43.
- *
- * Another possibility is that the server is loading its dataset.
- * In this case we also want to close the connection, and have the
- * user wait until the server is ready to take our request.
- */
- if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) {
- c->err = REDIS_ERR_OTHER;
- snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str);
- c->reader->fn->freeObject(reply);
- __redisAsyncDisconnect(ac);
- return;
- }
- /* No more regular callbacks and no errors, the context *must* be subscribed or monitoring. */
- assert((c->flags & REDIS_SUBSCRIBED || c->flags & REDIS_MONITORING));
- if(c->flags & REDIS_SUBSCRIBED)
- __redisGetSubscribeCallback(ac,reply,&cb);
- }
-
- if (cb.fn != NULL) {
- __redisRunCallback(ac,&cb,reply);
- c->reader->fn->freeObject(reply);
-
- /* Proceed with free'ing when redisAsyncFree() was called. */
- if (c->flags & REDIS_FREEING) {
- __redisAsyncFree(ac);
- return;
- }
- } else {
- /* No callback for this reply. This can either be a NULL callback,
- * or there were no callbacks to begin with. Either way, don't
- * abort with an error, but simply ignore it because the client
- * doesn't know what the server will spit out over the wire. */
- c->reader->fn->freeObject(reply);
- }
- }
-
- /* Disconnect when there was an error reading the reply */
- if (status != REDIS_OK)
- __redisAsyncDisconnect(ac);
-}
-
-/* Internal helper function to detect socket status the first time a read or
- * write event fires. When connecting was not successful, the connect callback
- * is called with a REDIS_ERR status and the context is free'd. */
-static int __redisAsyncHandleConnect(redisAsyncContext *ac) {
- int completed = 0;
- redisContext *c = &(ac->c);
- if (redisCheckConnectDone(c, &completed) == REDIS_ERR) {
- /* Error! */
- redisCheckSocketError(c);
- if (ac->onConnect) ac->onConnect(ac, REDIS_ERR);
- __redisAsyncDisconnect(ac);
- return REDIS_ERR;
- } else if (completed == 1) {
- /* connected! */
- if (ac->onConnect) ac->onConnect(ac, REDIS_OK);
- c->flags |= REDIS_CONNECTED;
- return REDIS_OK;
- } else {
- return REDIS_OK;
- }
-}
-
-void redisAsyncRead(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
-
- if (redisBufferRead(c) == REDIS_ERR) {
- __redisAsyncDisconnect(ac);
- } else {
- /* Always re-schedule reads */
- _EL_ADD_READ(ac);
- redisProcessCallbacks(ac);
- }
-}
-
-/* This function should be called when the socket is readable.
- * It processes all replies that can be read and executes their callbacks.
- */
-void redisAsyncHandleRead(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
-
- if (!(c->flags & REDIS_CONNECTED)) {
- /* Abort connect was not successful. */
- if (__redisAsyncHandleConnect(ac) != REDIS_OK)
- return;
- /* Try again later when the context is still not connected. */
- if (!(c->flags & REDIS_CONNECTED))
- return;
- }
-
- c->funcs->async_read(ac);
-}
-
-void redisAsyncWrite(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- int done = 0;
-
- if (redisBufferWrite(c,&done) == REDIS_ERR) {
- __redisAsyncDisconnect(ac);
- } else {
- /* Continue writing when not done, stop writing otherwise */
- if (!done)
- _EL_ADD_WRITE(ac);
- else
- _EL_DEL_WRITE(ac);
-
- /* Always schedule reads after writes */
- _EL_ADD_READ(ac);
- }
-}
-
-void redisAsyncHandleWrite(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
-
- if (!(c->flags & REDIS_CONNECTED)) {
- /* Abort connect was not successful. */
- if (__redisAsyncHandleConnect(ac) != REDIS_OK)
- return;
- /* Try again later when the context is still not connected. */
- if (!(c->flags & REDIS_CONNECTED))
- return;
- }
-
- c->funcs->async_write(ac);
-}
-
-void __redisSetError(redisContext *c, int type, const char *str);
-
-void redisAsyncHandleTimeout(redisAsyncContext *ac) {
- redisContext *c = &(ac->c);
- redisCallback cb;
-
- if ((c->flags & REDIS_CONNECTED) && ac->replies.head == NULL) {
- /* Nothing to do - just an idle timeout */
- return;
- }
-
- if (!c->err) {
- __redisSetError(c, REDIS_ERR_TIMEOUT, "Timeout");
- }
-
- if (!(c->flags & REDIS_CONNECTED) && ac->onConnect) {
- ac->onConnect(ac, REDIS_ERR);
- }
-
- while (__redisShiftCallback(&ac->replies, &cb) == REDIS_OK) {
- __redisRunCallback(ac, &cb, NULL);
- }
-
- /**
- * TODO: Don't automatically sever the connection,
- * rather, allow to ignore <x> responses before the queue is clear
- */
- __redisAsyncDisconnect(ac);
-}
-
-/* Sets a pointer to the first argument and its length starting at p. Returns
- * the number of bytes to skip to get to the following argument. */
-static const char *nextArgument(const char *start, const char **str, size_t *len) {
- const char *p = start;
- if (p[0] != '$') {
- p = strchr(p,'$');
- if (p == NULL) return NULL;
- }
-
- *len = (int)strtol(p+1,NULL,10);
- p = strchr(p,'\r');
- assert(p);
- *str = p+2;
- return p+2+(*len)+2;
-}
-
-/* Helper function for the redisAsyncCommand* family of functions. Writes a
- * formatted command to the output buffer and registers the provided callback
- * function with the context. */
-static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) {
- redisContext *c = &(ac->c);
- redisCallback cb;
- struct dict *cbdict;
- dictEntry *de;
- redisCallback *existcb;
- int pvariant, hasnext;
- const char *cstr, *astr;
- size_t clen, alen;
- const char *p;
- sds sname;
- int ret;
-
- /* Don't accept new commands when the connection is about to be closed. */
- if (c->flags & (REDIS_DISCONNECTING | REDIS_FREEING)) return REDIS_ERR;
-
- /* Setup callback */
- cb.fn = fn;
- cb.privdata = privdata;
- cb.pending_subs = 1;
-
- /* Find out which command will be appended. */
- p = nextArgument(cmd,&cstr,&clen);
- assert(p != NULL);
- hasnext = (p[0] == '$');
- pvariant = (tolower(cstr[0]) == 'p') ? 1 : 0;
- cstr += pvariant;
- clen -= pvariant;
-
- if (hasnext && strncasecmp(cstr,"subscribe\r\n",11) == 0) {
- c->flags |= REDIS_SUBSCRIBED;
-
- /* Add every channel/pattern to the list of subscription callbacks. */
- while ((p = nextArgument(p,&astr,&alen)) != NULL) {
- sname = sdsnewlen(astr,alen);
- if (pvariant)
- cbdict = ac->sub.patterns;
- else
- cbdict = ac->sub.channels;
-
- de = dictFind(cbdict,sname);
-
- if (de != NULL) {
- existcb = dictGetEntryVal(de);
- cb.pending_subs = existcb->pending_subs + 1;
- }
-
- ret = dictReplace(cbdict,sname,&cb);
-
- if (ret == 0) sdsfree(sname);
- }
- } else if (strncasecmp(cstr,"unsubscribe\r\n",13) == 0) {
- /* It is only useful to call (P)UNSUBSCRIBE when the context is
- * subscribed to one or more channels or patterns. */
- if (!(c->flags & REDIS_SUBSCRIBED)) return REDIS_ERR;
-
- /* (P)UNSUBSCRIBE does not have its own response: every channel or
- * pattern that is unsubscribed will receive a message. This means we
- * should not append a callback function for this command. */
- } else if(strncasecmp(cstr,"monitor\r\n",9) == 0) {
- /* Set monitor flag and push callback */
- c->flags |= REDIS_MONITORING;
- __redisPushCallback(&ac->replies,&cb);
- } else {
- if (c->flags & REDIS_SUBSCRIBED)
- /* This will likely result in an error reply, but it needs to be
- * received and passed to the callback. */
- __redisPushCallback(&ac->sub.invalid,&cb);
- else
- __redisPushCallback(&ac->replies,&cb);
- }
-
- __redisAppendCommand(c,cmd,len);
-
- /* Always schedule a write when the write buffer is non-empty */
- _EL_ADD_WRITE(ac);
-
- return REDIS_OK;
-}
-
-int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap) {
- char *cmd;
- int len;
- int status;
- len = redisvFormatCommand(&cmd,format,ap);
-
- /* We don't want to pass -1 or -2 to future functions as a length. */
- if (len < 0)
- return REDIS_ERR;
-
- status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
- free(cmd);
- return status;
-}
-
-int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...) {
- va_list ap;
- int status;
- va_start(ap,format);
- status = redisvAsyncCommand(ac,fn,privdata,format,ap);
- va_end(ap);
- return status;
-}
-
-int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) {
- sds cmd;
- int len;
- int status;
- len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
- if (len < 0)
- return REDIS_ERR;
- status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
- sdsfree(cmd);
- return status;
-}
-
-int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len) {
- int status = __redisAsyncCommand(ac,fn,privdata,cmd,len);
- return status;
-}
-
-void redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv) {
- if (!ac->c.timeout) {
- ac->c.timeout = calloc(1, sizeof(tv));
- }
-
- if (tv.tv_sec == ac->c.timeout->tv_sec &&
- tv.tv_usec == ac->c.timeout->tv_usec) {
- return;
- }
-
- *ac->c.timeout = tv;
-}
diff --git a/deps/hiredis/async.h b/deps/hiredis/async.h
deleted file mode 100644
index 4f6b3b783..000000000
--- a/deps/hiredis/async.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HIREDIS_ASYNC_H
-#define __HIREDIS_ASYNC_H
-#include "hiredis.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct redisAsyncContext; /* need forward declaration of redisAsyncContext */
-struct dict; /* dictionary header is included in async.c */
-
-/* Reply callback prototype and container */
-typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*);
-typedef struct redisCallback {
- struct redisCallback *next; /* simple singly linked list */
- redisCallbackFn *fn;
- int pending_subs;
- void *privdata;
-} redisCallback;
-
-/* List of callbacks for either regular replies or pub/sub */
-typedef struct redisCallbackList {
- redisCallback *head, *tail;
-} redisCallbackList;
-
-/* Connection callback prototypes */
-typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status);
-typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status);
-typedef void(redisTimerCallback)(void *timer, void *privdata);
-
-/* Context for an async connection to Redis */
-typedef struct redisAsyncContext {
- /* Hold the regular context, so it can be realloc'ed. */
- redisContext c;
-
- /* Setup error flags so they can be used directly. */
- int err;
- char *errstr;
-
- /* Not used by hiredis */
- void *data;
-
- /* Event library data and hooks */
- struct {
- void *data;
-
- /* Hooks that are called when the library expects to start
- * reading/writing. These functions should be idempotent. */
- void (*addRead)(void *privdata);
- void (*delRead)(void *privdata);
- void (*addWrite)(void *privdata);
- void (*delWrite)(void *privdata);
- void (*cleanup)(void *privdata);
- void (*scheduleTimer)(void *privdata, struct timeval tv);
- } ev;
-
- /* Called when either the connection is terminated due to an error or per
- * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */
- redisDisconnectCallback *onDisconnect;
-
- /* Called when the first write event was received. */
- redisConnectCallback *onConnect;
-
- /* Regular command callbacks */
- redisCallbackList replies;
-
- /* Address used for connect() */
- struct sockaddr *saddr;
- size_t addrlen;
-
- /* Subscription callbacks */
- struct {
- redisCallbackList invalid;
- struct dict *channels;
- struct dict *patterns;
- } sub;
-} redisAsyncContext;
-
-/* Functions that proxy to hiredis */
-redisAsyncContext *redisAsyncConnectWithOptions(const redisOptions *options);
-redisAsyncContext *redisAsyncConnect(const char *ip, int port);
-redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr);
-redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port,
- const char *source_addr);
-redisAsyncContext *redisAsyncConnectUnix(const char *path);
-int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
-int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
-
-void redisAsyncSetTimeout(redisAsyncContext *ac, struct timeval tv);
-void redisAsyncDisconnect(redisAsyncContext *ac);
-void redisAsyncFree(redisAsyncContext *ac);
-
-/* Handle read/write events */
-void redisAsyncHandleRead(redisAsyncContext *ac);
-void redisAsyncHandleWrite(redisAsyncContext *ac);
-void redisAsyncHandleTimeout(redisAsyncContext *ac);
-void redisAsyncRead(redisAsyncContext *ac);
-void redisAsyncWrite(redisAsyncContext *ac);
-
-/* Command functions for an async context. Write the command to the
- * output buffer and register the provided callback. */
-int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap);
-int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...);
-int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen);
-int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/deps/hiredis/async_private.h b/deps/hiredis/async_private.h
deleted file mode 100644
index d0133ae18..000000000
--- a/deps/hiredis/async_private.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HIREDIS_ASYNC_PRIVATE_H
-#define __HIREDIS_ASYNC_PRIVATE_H
-
-#define _EL_ADD_READ(ctx) \
- do { \
- refreshTimeout(ctx); \
- if ((ctx)->ev.addRead) (ctx)->ev.addRead((ctx)->ev.data); \
- } while (0)
-#define _EL_DEL_READ(ctx) do { \
- if ((ctx)->ev.delRead) (ctx)->ev.delRead((ctx)->ev.data); \
- } while(0)
-#define _EL_ADD_WRITE(ctx) \
- do { \
- refreshTimeout(ctx); \
- if ((ctx)->ev.addWrite) (ctx)->ev.addWrite((ctx)->ev.data); \
- } while (0)
-#define _EL_DEL_WRITE(ctx) do { \
- if ((ctx)->ev.delWrite) (ctx)->ev.delWrite((ctx)->ev.data); \
- } while(0)
-#define _EL_CLEANUP(ctx) do { \
- if ((ctx)->ev.cleanup) (ctx)->ev.cleanup((ctx)->ev.data); \
- ctx->ev.cleanup = NULL; \
- } while(0);
-
-static inline void refreshTimeout(redisAsyncContext *ctx) {
- if (ctx->c.timeout && ctx->ev.scheduleTimer &&
- (ctx->c.timeout->tv_sec || ctx->c.timeout->tv_usec)) {
- ctx->ev.scheduleTimer(ctx->ev.data, *ctx->c.timeout);
- // } else {
- // printf("Not scheduling timer.. (tmo=%p)\n", ctx->c.timeout);
- // if (ctx->c.timeout){
- // printf("tv_sec: %u. tv_usec: %u\n", ctx->c.timeout->tv_sec,
- // ctx->c.timeout->tv_usec);
- // }
- }
-}
-
-void __redisAsyncDisconnect(redisAsyncContext *ac);
-void redisProcessCallbacks(redisAsyncContext *ac);
-
-#endif /* __HIREDIS_ASYNC_PRIVATE_H */
diff --git a/deps/hiredis/dict.c b/deps/hiredis/dict.c
deleted file mode 100644
index e17a62546..000000000
--- a/deps/hiredis/dict.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/* Hash table implementation.
- *
- * This file implements in memory hash tables with insert/del/replace/find/
- * get-random-element operations. Hash tables will auto resize if needed
- * tables of power of two in size are used, collisions are handled by
- * chaining. See the source code for more information... :)
- *
- * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "fmacros.h"
-#include <stdlib.h>
-#include <assert.h>
-#include <limits.h>
-#include "dict.h"
-
-/* -------------------------- private prototypes ---------------------------- */
-
-static int _dictExpandIfNeeded(dict *ht);
-static unsigned long _dictNextPower(unsigned long size);
-static int _dictKeyIndex(dict *ht, const void *key);
-static int _dictInit(dict *ht, dictType *type, void *privDataPtr);
-
-/* -------------------------- hash functions -------------------------------- */
-
-/* Generic hash function (a popular one from Bernstein).
- * I tested a few and this was the best. */
-static unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
- unsigned int hash = 5381;
-
- while (len--)
- hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */
- return hash;
-}
-
-/* ----------------------------- API implementation ------------------------- */
-
-/* Reset an hashtable already initialized with ht_init().
- * NOTE: This function should only called by ht_destroy(). */
-static void _dictReset(dict *ht) {
- ht->table = NULL;
- ht->size = 0;
- ht->sizemask = 0;
- ht->used = 0;
-}
-
-/* Create a new hash table */
-static dict *dictCreate(dictType *type, void *privDataPtr) {
- dict *ht = malloc(sizeof(*ht));
- _dictInit(ht,type,privDataPtr);
- return ht;
-}
-
-/* Initialize the hash table */
-static int _dictInit(dict *ht, dictType *type, void *privDataPtr) {
- _dictReset(ht);
- ht->type = type;
- ht->privdata = privDataPtr;
- return DICT_OK;
-}
-
-/* Expand or create the hashtable */
-static int dictExpand(dict *ht, unsigned long size) {
- dict n; /* the new hashtable */
- unsigned long realsize = _dictNextPower(size), i;
-
- /* the size is invalid if it is smaller than the number of
- * elements already inside the hashtable */
- if (ht->used > size)
- return DICT_ERR;
-
- _dictInit(&n, ht->type, ht->privdata);
- n.size = realsize;
- n.sizemask = realsize-1;
- n.table = calloc(realsize,sizeof(dictEntry*));
-
- /* Copy all the elements from the old to the new table:
- * note that if the old hash table is empty ht->size is zero,
- * so dictExpand just creates an hash table. */
- n.used = ht->used;
- for (i = 0; i < ht->size && ht->used > 0; i++) {
- dictEntry *he, *nextHe;
-
- if (ht->table[i] == NULL) continue;
-
- /* For each hash entry on this slot... */
- he = ht->table[i];
- while(he) {
- unsigned int h;
-
- nextHe = he->next;
- /* Get the new element index */
- h = dictHashKey(ht, he->key) & n.sizemask;
- he->next = n.table[h];
- n.table[h] = he;
- ht->used--;
- /* Pass to the next element */
- he = nextHe;
- }
- }
- assert(ht->used == 0);
- free(ht->table);
-
- /* Remap the new hashtable in the old */
- *ht = n;
- return DICT_OK;
-}
-
-/* Add an element to the target hash table */
-static int dictAdd(dict *ht, void *key, void *val) {
- int index;
- dictEntry *entry;
-
- /* Get the index of the new element, or -1 if
- * the element already exists. */
- if ((index = _dictKeyIndex(ht, key)) == -1)
- return DICT_ERR;
-
- /* Allocates the memory and stores key */
- entry = malloc(sizeof(*entry));
- entry->next = ht->table[index];
- ht->table[index] = entry;
-
- /* Set the hash entry fields. */
- dictSetHashKey(ht, entry, key);
- dictSetHashVal(ht, entry, val);
- ht->used++;
- return DICT_OK;
-}
-
-/* Add an element, discarding the old if the key already exists.
- * Return 1 if the key was added from scratch, 0 if there was already an
- * element with such key and dictReplace() just performed a value update
- * operation. */
-static int dictReplace(dict *ht, void *key, void *val) {
- dictEntry *entry, auxentry;
-
- /* Try to add the element. If the key
- * does not exists dictAdd will succeed. */
- if (dictAdd(ht, key, val) == DICT_OK)
- return 1;
- /* It already exists, get the entry */
- entry = dictFind(ht, key);
- /* Free the old value and set the new one */
- /* Set the new value and free the old one. Note that it is important
- * to do that in this order, as the value may just be exactly the same
- * as the previous one. In this context, think to reference counting,
- * you want to increment (set), and then decrement (free), and not the
- * reverse. */
- auxentry = *entry;
- dictSetHashVal(ht, entry, val);
- dictFreeEntryVal(ht, &auxentry);
- return 0;
-}
-
-/* Search and remove an element */
-static int dictDelete(dict *ht, const void *key) {
- unsigned int h;
- dictEntry *de, *prevde;
-
- if (ht->size == 0)
- return DICT_ERR;
- h = dictHashKey(ht, key) & ht->sizemask;
- de = ht->table[h];
-
- prevde = NULL;
- while(de) {
- if (dictCompareHashKeys(ht,key,de->key)) {
- /* Unlink the element from the list */
- if (prevde)
- prevde->next = de->next;
- else
- ht->table[h] = de->next;
-
- dictFreeEntryKey(ht,de);
- dictFreeEntryVal(ht,de);
- free(de);
- ht->used--;
- return DICT_OK;
- }
- prevde = de;
- de = de->next;
- }
- return DICT_ERR; /* not found */
-}
-
-/* Destroy an entire hash table */
-static int _dictClear(dict *ht) {
- unsigned long i;
-
- /* Free all the elements */
- for (i = 0; i < ht->size && ht->used > 0; i++) {
- dictEntry *he, *nextHe;
-
- if ((he = ht->table[i]) == NULL) continue;
- while(he) {
- nextHe = he->next;
- dictFreeEntryKey(ht, he);
- dictFreeEntryVal(ht, he);
- free(he);
- ht->used--;
- he = nextHe;
- }
- }
- /* Free the table and the allocated cache structure */
- free(ht->table);
- /* Re-initialize the table */
- _dictReset(ht);
- return DICT_OK; /* never fails */
-}
-
-/* Clear & Release the hash table */
-static void dictRelease(dict *ht) {
- _dictClear(ht);
- free(ht);
-}
-
-static dictEntry *dictFind(dict *ht, const void *key) {
- dictEntry *he;
- unsigned int h;
-
- if (ht->size == 0) return NULL;
- h = dictHashKey(ht, key) & ht->sizemask;
- he = ht->table[h];
- while(he) {
- if (dictCompareHashKeys(ht, key, he->key))
- return he;
- he = he->next;
- }
- return NULL;
-}
-
-static dictIterator *dictGetIterator(dict *ht) {
- dictIterator *iter = malloc(sizeof(*iter));
-
- iter->ht = ht;
- iter->index = -1;
- iter->entry = NULL;
- iter->nextEntry = NULL;
- return iter;
-}
-
-static dictEntry *dictNext(dictIterator *iter) {
- while (1) {
- if (iter->entry == NULL) {
- iter->index++;
- if (iter->index >=
- (signed)iter->ht->size) break;
- iter->entry = iter->ht->table[iter->index];
- } else {
- iter->entry = iter->nextEntry;
- }
- if (iter->entry) {
- /* We need to save the 'next' here, the iterator user
- * may delete the entry we are returning. */
- iter->nextEntry = iter->entry->next;
- return iter->entry;
- }
- }
- return NULL;
-}
-
-static void dictReleaseIterator(dictIterator *iter) {
- free(iter);
-}
-
-/* ------------------------- private functions ------------------------------ */
-
-/* Expand the hash table if needed */
-static int _dictExpandIfNeeded(dict *ht) {
- /* If the hash table is empty expand it to the initial size,
- * if the table is "full" dobule its size. */
- if (ht->size == 0)
- return dictExpand(ht, DICT_HT_INITIAL_SIZE);
- if (ht->used == ht->size)
- return dictExpand(ht, ht->size*2);
- return DICT_OK;
-}
-
-/* Our hash table capability is a power of two */
-static unsigned long _dictNextPower(unsigned long size) {
- unsigned long i = DICT_HT_INITIAL_SIZE;
-
- if (size >= LONG_MAX) return LONG_MAX;
- while(1) {
- if (i >= size)
- return i;
- i *= 2;
- }
-}
-
-/* Returns the index of a free slot that can be populated with
- * an hash entry for the given 'key'.
- * If the key already exists, -1 is returned. */
-static int _dictKeyIndex(dict *ht, const void *key) {
- unsigned int h;
- dictEntry *he;
-
- /* Expand the hashtable if needed */
- if (_dictExpandIfNeeded(ht) == DICT_ERR)
- return -1;
- /* Compute the key hash value */
- h = dictHashKey(ht, key) & ht->sizemask;
- /* Search if this slot does not already contain the given key */
- he = ht->table[h];
- while(he) {
- if (dictCompareHashKeys(ht, key, he->key))
- return -1;
- he = he->next;
- }
- return h;
-}
-
diff --git a/deps/hiredis/dict.h b/deps/hiredis/dict.h
deleted file mode 100644
index 95fcd280e..000000000
--- a/deps/hiredis/dict.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Hash table implementation.
- *
- * This file implements in memory hash tables with insert/del/replace/find/
- * get-random-element operations. Hash tables will auto resize if needed
- * tables of power of two in size are used, collisions are handled by
- * chaining. See the source code for more information... :)
- *
- * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __DICT_H
-#define __DICT_H
-
-#define DICT_OK 0
-#define DICT_ERR 1
-
-/* Unused arguments generate annoying warnings... */
-#define DICT_NOTUSED(V) ((void) V)
-
-typedef struct dictEntry {
- void *key;
- void *val;
- struct dictEntry *next;
-} dictEntry;
-
-typedef struct dictType {
- unsigned int (*hashFunction)(const void *key);
- void *(*keyDup)(void *privdata, const void *key);
- void *(*valDup)(void *privdata, const void *obj);
- int (*keyCompare)(void *privdata, const void *key1, const void *key2);
- void (*keyDestructor)(void *privdata, void *key);
- void (*valDestructor)(void *privdata, void *obj);
-} dictType;
-
-typedef struct dict {
- dictEntry **table;
- dictType *type;
- unsigned long size;
- unsigned long sizemask;
- unsigned long used;
- void *privdata;
-} dict;
-
-typedef struct dictIterator {
- dict *ht;
- int index;
- dictEntry *entry, *nextEntry;
-} dictIterator;
-
-/* This is the initial size of every hash table */
-#define DICT_HT_INITIAL_SIZE 4
-
-/* ------------------------------- Macros ------------------------------------*/
-#define dictFreeEntryVal(ht, entry) \
- if ((ht)->type->valDestructor) \
- (ht)->type->valDestructor((ht)->privdata, (entry)->val)
-
-#define dictSetHashVal(ht, entry, _val_) do { \
- if ((ht)->type->valDup) \
- entry->val = (ht)->type->valDup((ht)->privdata, _val_); \
- else \
- entry->val = (_val_); \
-} while(0)
-
-#define dictFreeEntryKey(ht, entry) \
- if ((ht)->type->keyDestructor) \
- (ht)->type->keyDestructor((ht)->privdata, (entry)->key)
-
-#define dictSetHashKey(ht, entry, _key_) do { \
- if ((ht)->type->keyDup) \
- entry->key = (ht)->type->keyDup((ht)->privdata, _key_); \
- else \
- entry->key = (_key_); \
-} while(0)
-
-#define dictCompareHashKeys(ht, key1, key2) \
- (((ht)->type->keyCompare) ? \
- (ht)->type->keyCompare((ht)->privdata, key1, key2) : \
- (key1) == (key2))
-
-#define dictHashKey(ht, key) (ht)->type->hashFunction(key)
-
-#define dictGetEntryKey(he) ((he)->key)
-#define dictGetEntryVal(he) ((he)->val)
-#define dictSlots(ht) ((ht)->size)
-#define dictSize(ht) ((ht)->used)
-
-/* API */
-static unsigned int dictGenHashFunction(const unsigned char *buf, int len);
-static dict *dictCreate(dictType *type, void *privDataPtr);
-static int dictExpand(dict *ht, unsigned long size);
-static int dictAdd(dict *ht, void *key, void *val);
-static int dictReplace(dict *ht, void *key, void *val);
-static int dictDelete(dict *ht, const void *key);
-static void dictRelease(dict *ht);
-static dictEntry * dictFind(dict *ht, const void *key);
-static dictIterator *dictGetIterator(dict *ht);
-static dictEntry *dictNext(dictIterator *iter);
-static void dictReleaseIterator(dictIterator *iter);
-
-#endif /* __DICT_H */
diff --git a/deps/hiredis/examples/CMakeLists.txt b/deps/hiredis/examples/CMakeLists.txt
deleted file mode 100644
index dd3a313ac..000000000
--- a/deps/hiredis/examples/CMakeLists.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-INCLUDE(FindPkgConfig)
-# Check for GLib
-
-PKG_CHECK_MODULES(GLIB2 glib-2.0)
-if (GLIB2_FOUND)
- INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS})
- LINK_DIRECTORIES(${GLIB2_LIBRARY_DIRS})
- ADD_EXECUTABLE(example-glib example-glib.c)
- TARGET_LINK_LIBRARIES(example-glib hiredis ${GLIB2_LIBRARIES})
-ENDIF(GLIB2_FOUND)
-
-FIND_PATH(LIBEV ev.h
- HINTS /usr/local /usr/opt/local
- ENV LIBEV_INCLUDE_DIR)
-
-if (LIBEV)
- # Just compile and link with libev
- ADD_EXECUTABLE(example-libev example-libev.c)
- TARGET_LINK_LIBRARIES(example-libev hiredis ev)
-ENDIF()
-
-FIND_PATH(LIBEVENT event.h)
-if (LIBEVENT)
- ADD_EXECUTABLE(example-libevent example-libevent)
- TARGET_LINK_LIBRARIES(example-libevent hiredis event)
-ENDIF()
-
-FIND_PATH(LIBUV uv.h)
-IF (LIBUV)
- ADD_EXECUTABLE(example-libuv example-libuv.c)
- TARGET_LINK_LIBRARIES(example-libuv hiredis uv)
-ENDIF()
-
-IF (APPLE)
- FIND_LIBRARY(CF CoreFoundation)
- ADD_EXECUTABLE(example-macosx example-macosx.c)
- TARGET_LINK_LIBRARIES(example-macosx hiredis ${CF})
-ENDIF()
-
-IF (ENABLE_SSL)
- ADD_EXECUTABLE(example-ssl example-ssl.c)
- TARGET_LINK_LIBRARIES(example-ssl hiredis hiredis_ssl)
-ENDIF()
-
-ADD_EXECUTABLE(example example.c)
-TARGET_LINK_LIBRARIES(example hiredis)
diff --git a/deps/hiredis/examples/example-ae.c b/deps/hiredis/examples/example-ae.c
deleted file mode 100644
index 8efa7306a..000000000
--- a/deps/hiredis/examples/example-ae.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/ae.h>
-
-/* Put event loop in the global scope, so it can be explicitly stopped */
-static aeEventLoop *loop;
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- aeStop(loop);
- return;
- }
-
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- aeStop(loop);
- return;
- }
-
- printf("Disconnected...\n");
- aeStop(loop);
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
-
- redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
- if (c->err) {
- /* Let *c leak for now... */
- printf("Error: %s\n", c->errstr);
- return 1;
- }
-
- loop = aeCreateEventLoop(64);
- redisAeAttach(loop, c);
- redisAsyncSetConnectCallback(c,connectCallback);
- redisAsyncSetDisconnectCallback(c,disconnectCallback);
- redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
- redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
- aeMain(loop);
- return 0;
-}
-
diff --git a/deps/hiredis/examples/example-glib.c b/deps/hiredis/examples/example-glib.c
deleted file mode 100644
index d6e10f8e8..000000000
--- a/deps/hiredis/examples/example-glib.c
+++ /dev/null
@@ -1,73 +0,0 @@
-#include <stdlib.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/glib.h>
-
-static GMainLoop *mainloop;
-
-static void
-connect_cb (const redisAsyncContext *ac G_GNUC_UNUSED,
- int status)
-{
- if (status != REDIS_OK) {
- g_printerr("Failed to connect: %s\n", ac->errstr);
- g_main_loop_quit(mainloop);
- } else {
- g_printerr("Connected...\n");
- }
-}
-
-static void
-disconnect_cb (const redisAsyncContext *ac G_GNUC_UNUSED,
- int status)
-{
- if (status != REDIS_OK) {
- g_error("Failed to disconnect: %s", ac->errstr);
- } else {
- g_printerr("Disconnected...\n");
- g_main_loop_quit(mainloop);
- }
-}
-
-static void
-command_cb(redisAsyncContext *ac,
- gpointer r,
- gpointer user_data G_GNUC_UNUSED)
-{
- redisReply *reply = r;
-
- if (reply) {
- g_print("REPLY: %s\n", reply->str);
- }
-
- redisAsyncDisconnect(ac);
-}
-
-gint
-main (gint argc G_GNUC_UNUSED,
- gchar *argv[] G_GNUC_UNUSED)
-{
- redisAsyncContext *ac;
- GMainContext *context = NULL;
- GSource *source;
-
- ac = redisAsyncConnect("127.0.0.1", 6379);
- if (ac->err) {
- g_printerr("%s\n", ac->errstr);
- exit(EXIT_FAILURE);
- }
-
- source = redis_source_new(ac);
- mainloop = g_main_loop_new(context, FALSE);
- g_source_attach(source, context);
-
- redisAsyncSetConnectCallback(ac, connect_cb);
- redisAsyncSetDisconnectCallback(ac, disconnect_cb);
- redisAsyncCommand(ac, command_cb, NULL, "SET key 1234");
- redisAsyncCommand(ac, command_cb, NULL, "GET key");
-
- g_main_loop_run(mainloop);
-
- return EXIT_SUCCESS;
-}
diff --git a/deps/hiredis/examples/example-ivykis.c b/deps/hiredis/examples/example-ivykis.c
deleted file mode 100644
index 67affcef3..000000000
--- a/deps/hiredis/examples/example-ivykis.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/ivykis.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
-
- iv_init();
-
- redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
- if (c->err) {
- /* Let *c leak for now... */
- printf("Error: %s\n", c->errstr);
- return 1;
- }
-
- redisIvykisAttach(c);
- redisAsyncSetConnectCallback(c,connectCallback);
- redisAsyncSetDisconnectCallback(c,disconnectCallback);
- redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
- redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
-
- iv_main();
-
- iv_deinit();
-
- return 0;
-}
diff --git a/deps/hiredis/examples/example-libev.c b/deps/hiredis/examples/example-libev.c
deleted file mode 100644
index cc8b166ec..000000000
--- a/deps/hiredis/examples/example-libev.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/libev.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
-
- redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
- if (c->err) {
- /* Let *c leak for now... */
- printf("Error: %s\n", c->errstr);
- return 1;
- }
-
- redisLibevAttach(EV_DEFAULT_ c);
- redisAsyncSetConnectCallback(c,connectCallback);
- redisAsyncSetDisconnectCallback(c,disconnectCallback);
- redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
- redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
- ev_loop(EV_DEFAULT_ 0);
- return 0;
-}
diff --git a/deps/hiredis/examples/example-libevent-ssl.c b/deps/hiredis/examples/example-libevent-ssl.c
deleted file mode 100644
index 1021113b9..000000000
--- a/deps/hiredis/examples/example-libevent-ssl.c
+++ /dev/null
@@ -1,73 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <hiredis_ssl.h>
-#include <async.h>
-#include <adapters/libevent.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
- struct event_base *base = event_base_new();
- if (argc < 5) {
- fprintf(stderr,
- "Usage: %s <key> <host> <port> <cert> <certKey> [ca]\n", argv[0]);
- exit(1);
- }
-
- const char *value = argv[1];
- size_t nvalue = strlen(value);
-
- const char *hostname = argv[2];
- int port = atoi(argv[3]);
-
- const char *cert = argv[4];
- const char *certKey = argv[5];
- const char *caCert = argc > 5 ? argv[6] : NULL;
-
- redisAsyncContext *c = redisAsyncConnect(hostname, port);
- if (c->err) {
- /* Let *c leak for now... */
- printf("Error: %s\n", c->errstr);
- return 1;
- }
- if (redisSecureConnection(&c->c, caCert, cert, certKey, "sni") != REDIS_OK) {
- printf("SSL Error!\n");
- exit(1);
- }
-
- redisLibeventAttach(c,base);
- redisAsyncSetConnectCallback(c,connectCallback);
- redisAsyncSetDisconnectCallback(c,disconnectCallback);
- redisAsyncCommand(c, NULL, NULL, "SET key %b", value, nvalue);
- redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
- event_base_dispatch(base);
- return 0;
-}
diff --git a/deps/hiredis/examples/example-libevent.c b/deps/hiredis/examples/example-libevent.c
deleted file mode 100644
index 1fe71ae4e..000000000
--- a/deps/hiredis/examples/example-libevent.c
+++ /dev/null
@@ -1,64 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/libevent.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) {
- if (c->errstr) {
- printf("errstr: %s\n", c->errstr);
- }
- return;
- }
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
- struct event_base *base = event_base_new();
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, "127.0.0.1", 6379);
- struct timeval tv = {0};
- tv.tv_sec = 1;
- options.timeout = &tv;
-
-
- redisAsyncContext *c = redisAsyncConnectWithOptions(&options);
- if (c->err) {
- /* Let *c leak for now... */
- printf("Error: %s\n", c->errstr);
- return 1;
- }
-
- redisLibeventAttach(c,base);
- redisAsyncSetConnectCallback(c,connectCallback);
- redisAsyncSetDisconnectCallback(c,disconnectCallback);
- redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
- redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
- event_base_dispatch(base);
- return 0;
-}
diff --git a/deps/hiredis/examples/example-libuv.c b/deps/hiredis/examples/example-libuv.c
deleted file mode 100644
index a5462d410..000000000
--- a/deps/hiredis/examples/example-libuv.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/libuv.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
- uv_loop_t* loop = uv_default_loop();
-
- redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
- if (c->err) {
- /* Let *c leak for now... */
- printf("Error: %s\n", c->errstr);
- return 1;
- }
-
- redisLibuvAttach(c,loop);
- redisAsyncSetConnectCallback(c,connectCallback);
- redisAsyncSetDisconnectCallback(c,disconnectCallback);
- redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
- redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
- uv_run(loop, UV_RUN_DEFAULT);
- return 0;
-}
diff --git a/deps/hiredis/examples/example-macosx.c b/deps/hiredis/examples/example-macosx.c
deleted file mode 100644
index bc84ed5ba..000000000
--- a/deps/hiredis/examples/example-macosx.c
+++ /dev/null
@@ -1,66 +0,0 @@
-//
-// Created by Дмитрий Бахвалов on 13.07.15.
-// Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved.
-//
-
-#include <stdio.h>
-
-#include <hiredis.h>
-#include <async.h>
-#include <adapters/macosx.h>
-
-void getCallback(redisAsyncContext *c, void *r, void *privdata) {
- redisReply *reply = r;
- if (reply == NULL) return;
- printf("argv[%s]: %s\n", (char*)privdata, reply->str);
-
- /* Disconnect after receiving the reply to GET */
- redisAsyncDisconnect(c);
-}
-
-void connectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- printf("Connected...\n");
-}
-
-void disconnectCallback(const redisAsyncContext *c, int status) {
- if (status != REDIS_OK) {
- printf("Error: %s\n", c->errstr);
- return;
- }
- CFRunLoopStop(CFRunLoopGetCurrent());
- printf("Disconnected...\n");
-}
-
-int main (int argc, char **argv) {
- signal(SIGPIPE, SIG_IGN);
-
- CFRunLoopRef loop = CFRunLoopGetCurrent();
- if( !loop ) {
- printf("Error: Cannot get current run loop\n");
- return 1;
- }
-
- redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
- if (c->err) {
- /* Let *c leak for now... */
- printf("Error: %s\n", c->errstr);
- return 1;
- }
-
- redisMacOSAttach(c, loop);
-
- redisAsyncSetConnectCallback(c,connectCallback);
- redisAsyncSetDisconnectCallback(c,disconnectCallback);
-
- redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
- redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
-
- CFRunLoopRun();
-
- return 0;
-}
-
diff --git a/deps/hiredis/examples/example-qt.cpp b/deps/hiredis/examples/example-qt.cpp
deleted file mode 100644
index f524c3f3d..000000000
--- a/deps/hiredis/examples/example-qt.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <iostream>
-using namespace std;
-
-#include <QCoreApplication>
-#include <QTimer>
-
-#include "example-qt.h"
-
-void getCallback(redisAsyncContext *, void * r, void * privdata) {
-
- redisReply * reply = static_cast<redisReply *>(r);
- ExampleQt * ex = static_cast<ExampleQt *>(privdata);
- if (reply == nullptr || ex == nullptr) return;
-
- cout << "key: " << reply->str << endl;
-
- ex->finish();
-}
-
-void ExampleQt::run() {
-
- m_ctx = redisAsyncConnect("localhost", 6379);
-
- if (m_ctx->err) {
- cerr << "Error: " << m_ctx->errstr << endl;
- redisAsyncFree(m_ctx);
- emit finished();
- }
-
- m_adapter.setContext(m_ctx);
-
- redisAsyncCommand(m_ctx, NULL, NULL, "SET key %s", m_value);
- redisAsyncCommand(m_ctx, getCallback, this, "GET key");
-}
-
-int main (int argc, char **argv) {
-
- QCoreApplication app(argc, argv);
-
- ExampleQt example(argv[argc-1]);
-
- QObject::connect(&example, SIGNAL(finished()), &app, SLOT(quit()));
- QTimer::singleShot(0, &example, SLOT(run()));
-
- return app.exec();
-}
diff --git a/deps/hiredis/examples/example-qt.h b/deps/hiredis/examples/example-qt.h
deleted file mode 100644
index 374f47666..000000000
--- a/deps/hiredis/examples/example-qt.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __HIREDIS_EXAMPLE_QT_H
-#define __HIREDIS_EXAMPLE_QT_H
-
-#include <adapters/qt.h>
-
-class ExampleQt : public QObject {
-
- Q_OBJECT
-
- public:
- ExampleQt(const char * value, QObject * parent = 0)
- : QObject(parent), m_value(value) {}
-
- signals:
- void finished();
-
- public slots:
- void run();
-
- private:
- void finish() { emit finished(); }
-
- private:
- const char * m_value;
- redisAsyncContext * m_ctx;
- RedisQtAdapter m_adapter;
-
- friend
- void getCallback(redisAsyncContext *, void *, void *);
-};
-
-#endif /* !__HIREDIS_EXAMPLE_QT_H */
diff --git a/deps/hiredis/examples/example-ssl.c b/deps/hiredis/examples/example-ssl.c
deleted file mode 100644
index 81f4648c6..000000000
--- a/deps/hiredis/examples/example-ssl.c
+++ /dev/null
@@ -1,97 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <hiredis.h>
-#include <hiredis_ssl.h>
-
-int main(int argc, char **argv) {
- unsigned int j;
- redisContext *c;
- redisReply *reply;
- if (argc < 4) {
- printf("Usage: %s <host> <port> <cert> <key> [ca]\n", argv[0]);
- exit(1);
- }
- const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1";
- int port = atoi(argv[2]);
- const char *cert = argv[3];
- const char *key = argv[4];
- const char *ca = argc > 4 ? argv[5] : NULL;
-
- struct timeval tv = { 1, 500000 }; // 1.5 seconds
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, hostname, port);
- options.timeout = &tv;
- c = redisConnectWithOptions(&options);
-
- if (c == NULL || c->err) {
- if (c) {
- printf("Connection error: %s\n", c->errstr);
- redisFree(c);
- } else {
- printf("Connection error: can't allocate redis context\n");
- }
- exit(1);
- }
-
- if (redisSecureConnection(c, ca, cert, key, "sni") != REDIS_OK) {
- printf("Couldn't initialize SSL!\n");
- printf("Error: %s\n", c->errstr);
- redisFree(c);
- exit(1);
- }
-
- /* PING server */
- reply = redisCommand(c,"PING");
- printf("PING: %s\n", reply->str);
- freeReplyObject(reply);
-
- /* Set a key */
- reply = redisCommand(c,"SET %s %s", "foo", "hello world");
- printf("SET: %s\n", reply->str);
- freeReplyObject(reply);
-
- /* Set a key using binary safe API */
- reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5);
- printf("SET (binary API): %s\n", reply->str);
- freeReplyObject(reply);
-
- /* Try a GET and two INCR */
- reply = redisCommand(c,"GET foo");
- printf("GET foo: %s\n", reply->str);
- freeReplyObject(reply);
-
- reply = redisCommand(c,"INCR counter");
- printf("INCR counter: %lld\n", reply->integer);
- freeReplyObject(reply);
- /* again ... */
- reply = redisCommand(c,"INCR counter");
- printf("INCR counter: %lld\n", reply->integer);
- freeReplyObject(reply);
-
- /* Create a list of numbers, from 0 to 9 */
- reply = redisCommand(c,"DEL mylist");
- freeReplyObject(reply);
- for (j = 0; j < 10; j++) {
- char buf[64];
-
- snprintf(buf,64,"%u",j);
- reply = redisCommand(c,"LPUSH mylist element-%s", buf);
- freeReplyObject(reply);
- }
-
- /* Let's check what we have inside the list */
- reply = redisCommand(c,"LRANGE mylist 0 -1");
- if (reply->type == REDIS_REPLY_ARRAY) {
- for (j = 0; j < reply->elements; j++) {
- printf("%u) %s\n", j, reply->element[j]->str);
- }
- }
- freeReplyObject(reply);
-
- /* Disconnects and frees the context */
- redisFree(c);
-
- return 0;
-}
diff --git a/deps/hiredis/examples/example.c b/deps/hiredis/examples/example.c
deleted file mode 100644
index 0e93fc8b3..000000000
--- a/deps/hiredis/examples/example.c
+++ /dev/null
@@ -1,91 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <hiredis.h>
-
-int main(int argc, char **argv) {
- unsigned int j, isunix = 0;
- redisContext *c;
- redisReply *reply;
- const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1";
-
- if (argc > 2) {
- if (*argv[2] == 'u' || *argv[2] == 'U') {
- isunix = 1;
- /* in this case, host is the path to the unix socket */
- printf("Will connect to unix socket @%s\n", hostname);
- }
- }
-
- int port = (argc > 2) ? atoi(argv[2]) : 6379;
-
- struct timeval timeout = { 1, 500000 }; // 1.5 seconds
- if (isunix) {
- c = redisConnectUnixWithTimeout(hostname, timeout);
- } else {
- c = redisConnectWithTimeout(hostname, port, timeout);
- }
- if (c == NULL || c->err) {
- if (c) {
- printf("Connection error: %s\n", c->errstr);
- redisFree(c);
- } else {
- printf("Connection error: can't allocate redis context\n");
- }
- exit(1);
- }
-
- /* PING server */
- reply = redisCommand(c,"PING");
- printf("PING: %s\n", reply->str);
- freeReplyObject(reply);
-
- /* Set a key */
- reply = redisCommand(c,"SET %s %s", "foo", "hello world");
- printf("SET: %s\n", reply->str);
- freeReplyObject(reply);
-
- /* Set a key using binary safe API */
- reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5);
- printf("SET (binary API): %s\n", reply->str);
- freeReplyObject(reply);
-
- /* Try a GET and two INCR */
- reply = redisCommand(c,"GET foo");
- printf("GET foo: %s\n", reply->str);
- freeReplyObject(reply);
-
- reply = redisCommand(c,"INCR counter");
- printf("INCR counter: %lld\n", reply->integer);
- freeReplyObject(reply);
- /* again ... */
- reply = redisCommand(c,"INCR counter");
- printf("INCR counter: %lld\n", reply->integer);
- freeReplyObject(reply);
-
- /* Create a list of numbers, from 0 to 9 */
- reply = redisCommand(c,"DEL mylist");
- freeReplyObject(reply);
- for (j = 0; j < 10; j++) {
- char buf[64];
-
- snprintf(buf,64,"%u",j);
- reply = redisCommand(c,"LPUSH mylist element-%s", buf);
- freeReplyObject(reply);
- }
-
- /* Let's check what we have inside the list */
- reply = redisCommand(c,"LRANGE mylist 0 -1");
- if (reply->type == REDIS_REPLY_ARRAY) {
- for (j = 0; j < reply->elements; j++) {
- printf("%u) %s\n", j, reply->element[j]->str);
- }
- }
- freeReplyObject(reply);
-
- /* Disconnects and frees the context */
- redisFree(c);
-
- return 0;
-}
diff --git a/deps/hiredis/fmacros.h b/deps/hiredis/fmacros.h
deleted file mode 100644
index 3227faafd..000000000
--- a/deps/hiredis/fmacros.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __HIREDIS_FMACRO_H
-#define __HIREDIS_FMACRO_H
-
-#define _XOPEN_SOURCE 600
-#define _POSIX_C_SOURCE 200112L
-
-#if defined(__APPLE__) && defined(__MACH__)
-/* Enable TCP_KEEPALIVE */
-#define _DARWIN_C_SOURCE
-#endif
-
-#endif
diff --git a/deps/hiredis/hiredis.c b/deps/hiredis/hiredis.c
deleted file mode 100644
index abd94c01d..000000000
--- a/deps/hiredis/hiredis.c
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- * Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "fmacros.h"
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "hiredis.h"
-#include "net.h"
-#include "sds.h"
-#include "async.h"
-#include "win32.h"
-
-static redisContextFuncs redisContextDefaultFuncs = {
- .free_privdata = NULL,
- .async_read = redisAsyncRead,
- .async_write = redisAsyncWrite,
- .read = redisNetRead,
- .write = redisNetWrite
-};
-
-static redisReply *createReplyObject(int type);
-static void *createStringObject(const redisReadTask *task, char *str, size_t len);
-static void *createArrayObject(const redisReadTask *task, size_t elements);
-static void *createIntegerObject(const redisReadTask *task, long long value);
-static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len);
-static void *createNilObject(const redisReadTask *task);
-static void *createBoolObject(const redisReadTask *task, int bval);
-
-/* Default set of functions to build the reply. Keep in mind that such a
- * function returning NULL is interpreted as OOM. */
-static redisReplyObjectFunctions defaultFunctions = {
- createStringObject,
- createArrayObject,
- createIntegerObject,
- createDoubleObject,
- createNilObject,
- createBoolObject,
- freeReplyObject
-};
-
-/* Create a reply object */
-static redisReply *createReplyObject(int type) {
- redisReply *r = calloc(1,sizeof(*r));
-
- if (r == NULL)
- return NULL;
-
- r->type = type;
- return r;
-}
-
-/* Free a reply object */
-void freeReplyObject(void *reply) {
- redisReply *r = reply;
- size_t j;
-
- if (r == NULL)
- return;
-
- switch(r->type) {
- case REDIS_REPLY_INTEGER:
- break; /* Nothing to free */
- case REDIS_REPLY_ARRAY:
- case REDIS_REPLY_MAP:
- case REDIS_REPLY_SET:
- if (r->element != NULL) {
- for (j = 0; j < r->elements; j++)
- freeReplyObject(r->element[j]);
- free(r->element);
- }
- break;
- case REDIS_REPLY_ERROR:
- case REDIS_REPLY_STATUS:
- case REDIS_REPLY_STRING:
- case REDIS_REPLY_DOUBLE:
- free(r->str);
- break;
- }
- free(r);
-}
-
-static void *createStringObject(const redisReadTask *task, char *str, size_t len) {
- redisReply *r, *parent;
- char *buf;
-
- r = createReplyObject(task->type);
- if (r == NULL)
- return NULL;
-
- assert(task->type == REDIS_REPLY_ERROR ||
- task->type == REDIS_REPLY_STATUS ||
- task->type == REDIS_REPLY_STRING ||
- task->type == REDIS_REPLY_VERB);
-
- /* Copy string value */
- if (task->type == REDIS_REPLY_VERB) {
- buf = malloc(len-4+1); /* Skip 4 bytes of verbatim type header. */
- if (buf == NULL) {
- freeReplyObject(r);
- return NULL;
- }
- memcpy(r->vtype,str,3);
- r->vtype[3] = '\0';
- memcpy(buf,str+4,len-4);
- buf[len-4] = '\0';
- r->len = len-4;
- } else {
- buf = malloc(len+1);
- if (buf == NULL) {
- freeReplyObject(r);
- return NULL;
- }
- memcpy(buf,str,len);
- buf[len] = '\0';
- r->len = len;
- }
- r->str = buf;
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY ||
- parent->type == REDIS_REPLY_MAP ||
- parent->type == REDIS_REPLY_SET);
- parent->element[task->idx] = r;
- }
- return r;
-}
-
-static void *createArrayObject(const redisReadTask *task, size_t elements) {
- redisReply *r, *parent;
-
- r = createReplyObject(task->type);
- if (r == NULL)
- return NULL;
-
- if (elements > 0) {
- r->element = calloc(elements,sizeof(redisReply*));
- if (r->element == NULL) {
- freeReplyObject(r);
- return NULL;
- }
- }
-
- r->elements = elements;
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY ||
- parent->type == REDIS_REPLY_MAP ||
- parent->type == REDIS_REPLY_SET);
- parent->element[task->idx] = r;
- }
- return r;
-}
-
-static void *createIntegerObject(const redisReadTask *task, long long value) {
- redisReply *r, *parent;
-
- r = createReplyObject(REDIS_REPLY_INTEGER);
- if (r == NULL)
- return NULL;
-
- r->integer = value;
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY ||
- parent->type == REDIS_REPLY_MAP ||
- parent->type == REDIS_REPLY_SET);
- parent->element[task->idx] = r;
- }
- return r;
-}
-
-static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t len) {
- redisReply *r, *parent;
-
- r = createReplyObject(REDIS_REPLY_DOUBLE);
- if (r == NULL)
- return NULL;
-
- r->dval = value;
- r->str = malloc(len+1);
- if (r->str == NULL) {
- freeReplyObject(r);
- return NULL;
- }
-
- /* The double reply also has the original protocol string representing a
- * double as a null terminated string. This way the caller does not need
- * to format back for string conversion, especially since Redis does efforts
- * to make the string more human readable avoiding the calssical double
- * decimal string conversion artifacts. */
- memcpy(r->str, str, len);
- r->str[len] = '\0';
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY ||
- parent->type == REDIS_REPLY_MAP ||
- parent->type == REDIS_REPLY_SET);
- parent->element[task->idx] = r;
- }
- return r;
-}
-
-static void *createNilObject(const redisReadTask *task) {
- redisReply *r, *parent;
-
- r = createReplyObject(REDIS_REPLY_NIL);
- if (r == NULL)
- return NULL;
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY ||
- parent->type == REDIS_REPLY_MAP ||
- parent->type == REDIS_REPLY_SET);
- parent->element[task->idx] = r;
- }
- return r;
-}
-
-static void *createBoolObject(const redisReadTask *task, int bval) {
- redisReply *r, *parent;
-
- r = createReplyObject(REDIS_REPLY_BOOL);
- if (r == NULL)
- return NULL;
-
- r->integer = bval != 0;
-
- if (task->parent) {
- parent = task->parent->obj;
- assert(parent->type == REDIS_REPLY_ARRAY ||
- parent->type == REDIS_REPLY_MAP ||
- parent->type == REDIS_REPLY_SET);
- parent->element[task->idx] = r;
- }
- return r;
-}
-
-/* Return the number of digits of 'v' when converted to string in radix 10.
- * Implementation borrowed from link in redis/src/util.c:string2ll(). */
-static uint32_t countDigits(uint64_t v) {
- uint32_t result = 1;
- for (;;) {
- if (v < 10) return result;
- if (v < 100) return result + 1;
- if (v < 1000) return result + 2;
- if (v < 10000) return result + 3;
- v /= 10000U;
- result += 4;
- }
-}
-
-/* Helper that calculates the bulk length given a certain string length. */
-static size_t bulklen(size_t len) {
- return 1+countDigits(len)+2+len+2;
-}
-
-int redisvFormatCommand(char **target, const char *format, va_list ap) {
- const char *c = format;
- char *cmd = NULL; /* final command */
- int pos; /* position in final command */
- sds curarg, newarg; /* current argument */
- int touched = 0; /* was the current argument touched? */
- char **curargv = NULL, **newargv = NULL;
- int argc = 0;
- int totlen = 0;
- int error_type = 0; /* 0 = no error; -1 = memory error; -2 = format error */
- int j;
-
- /* Abort if there is not target to set */
- if (target == NULL)
- return -1;
-
- /* Build the command string accordingly to protocol */
- curarg = sdsempty();
- if (curarg == NULL)
- return -1;
-
- while(*c != '\0') {
- if (*c != '%' || c[1] == '\0') {
- if (*c == ' ') {
- if (touched) {
- newargv = realloc(curargv,sizeof(char*)*(argc+1));
- if (newargv == NULL) goto memory_err;
- curargv = newargv;
- curargv[argc++] = curarg;
- totlen += bulklen(sdslen(curarg));
-
- /* curarg is put in argv so it can be overwritten. */
- curarg = sdsempty();
- if (curarg == NULL) goto memory_err;
- touched = 0;
- }
- } else {
- newarg = sdscatlen(curarg,c,1);
- if (newarg == NULL) goto memory_err;
- curarg = newarg;
- touched = 1;
- }
- } else {
- char *arg;
- size_t size;
-
- /* Set newarg so it can be checked even if it is not touched. */
- newarg = curarg;
-
- switch(c[1]) {
- case 's':
- arg = va_arg(ap,char*);
- size = strlen(arg);
- if (size > 0)
- newarg = sdscatlen(curarg,arg,size);
- break;
- case 'b':
- arg = va_arg(ap,char*);
- size = va_arg(ap,size_t);
- if (size > 0)
- newarg = sdscatlen(curarg,arg,size);
- break;
- case '%':
- newarg = sdscat(curarg,"%");
- break;
- default:
- /* Try to detect printf format */
- {
- static const char intfmts[] = "diouxX";
- static const char flags[] = "#0-+ ";
- char _format[16];
- const char *_p = c+1;
- size_t _l = 0;
- va_list _cpy;
-
- /* Flags */
- while (*_p != '\0' && strchr(flags,*_p) != NULL) _p++;
-
- /* Field width */
- while (*_p != '\0' && isdigit(*_p)) _p++;
-
- /* Precision */
- if (*_p == '.') {
- _p++;
- while (*_p != '\0' && isdigit(*_p)) _p++;
- }
-
- /* Copy va_list before consuming with va_arg */
- va_copy(_cpy,ap);
-
- /* Integer conversion (without modifiers) */
- if (strchr(intfmts,*_p) != NULL) {
- va_arg(ap,int);
- goto fmt_valid;
- }
-
- /* Double conversion (without modifiers) */
- if (strchr("eEfFgGaA",*_p) != NULL) {
- va_arg(ap,double);
- goto fmt_valid;
- }
-
- /* Size: char */
- if (_p[0] == 'h' && _p[1] == 'h') {
- _p += 2;
- if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
- va_arg(ap,int); /* char gets promoted to int */
- goto fmt_valid;
- }
- goto fmt_invalid;
- }
-
- /* Size: short */
- if (_p[0] == 'h') {
- _p += 1;
- if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
- va_arg(ap,int); /* short gets promoted to int */
- goto fmt_valid;
- }
- goto fmt_invalid;
- }
-
- /* Size: long long */
- if (_p[0] == 'l' && _p[1] == 'l') {
- _p += 2;
- if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
- va_arg(ap,long long);
- goto fmt_valid;
- }
- goto fmt_invalid;
- }
-
- /* Size: long */
- if (_p[0] == 'l') {
- _p += 1;
- if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
- va_arg(ap,long);
- goto fmt_valid;
- }
- goto fmt_invalid;
- }
-
- fmt_invalid:
- va_end(_cpy);
- goto format_err;
-
- fmt_valid:
- _l = (_p+1)-c;
- if (_l < sizeof(_format)-2) {
- memcpy(_format,c,_l);
- _format[_l] = '\0';
- newarg = sdscatvprintf(curarg,_format,_cpy);
-
- /* Update current position (note: outer blocks
- * increment c twice so compensate here) */
- c = _p-1;
- }
-
- va_end(_cpy);
- break;
- }
- }
-
- if (newarg == NULL) goto memory_err;
- curarg = newarg;
-
- touched = 1;
- c++;
- }
- c++;
- }
-
- /* Add the last argument if needed */
- if (touched) {
- newargv = realloc(curargv,sizeof(char*)*(argc+1));
- if (newargv == NULL) goto memory_err;
- curargv = newargv;
- curargv[argc++] = curarg;
- totlen += bulklen(sdslen(curarg));
- } else {
- sdsfree(curarg);
- }
-
- /* Clear curarg because it was put in curargv or was free'd. */
- curarg = NULL;
-
- /* Add bytes needed to hold multi bulk count */
- totlen += 1+countDigits(argc)+2;
-
- /* Build the command at protocol level */
- cmd = malloc(totlen+1);
- if (cmd == NULL) goto memory_err;
-
- pos = sprintf(cmd,"*%d\r\n",argc);
- for (j = 0; j < argc; j++) {
- pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j]));
- memcpy(cmd+pos,curargv[j],sdslen(curargv[j]));
- pos += sdslen(curargv[j]);
- sdsfree(curargv[j]);
- cmd[pos++] = '\r';
- cmd[pos++] = '\n';
- }
- assert(pos == totlen);
- cmd[pos] = '\0';
-
- free(curargv);
- *target = cmd;
- return totlen;
-
-format_err:
- error_type = -2;
- goto cleanup;
-
-memory_err:
- error_type = -1;
- goto cleanup;
-
-cleanup:
- if (curargv) {
- while(argc--)
- sdsfree(curargv[argc]);
- free(curargv);
- }
-
- sdsfree(curarg);
- free(cmd);
-
- return error_type;
-}
-
-/* Format a command according to the Redis protocol. This function
- * takes a format similar to printf:
- *
- * %s represents a C null terminated string you want to interpolate
- * %b represents a binary safe string
- *
- * When using %b you need to provide both the pointer to the string
- * and the length in bytes as a size_t. Examples:
- *
- * len = redisFormatCommand(target, "GET %s", mykey);
- * len = redisFormatCommand(target, "SET %s %b", mykey, myval, myvallen);
- */
-int redisFormatCommand(char **target, const char *format, ...) {
- va_list ap;
- int len;
- va_start(ap,format);
- len = redisvFormatCommand(target,format,ap);
- va_end(ap);
-
- /* The API says "-1" means bad result, but we now also return "-2" in some
- * cases. Force the return value to always be -1. */
- if (len < 0)
- len = -1;
-
- return len;
-}
-
-/* Format a command according to the Redis protocol using an sds string and
- * sdscatfmt for the processing of arguments. This function takes the
- * number of arguments, an array with arguments and an array with their
- * lengths. If the latter is set to NULL, strlen will be used to compute the
- * argument lengths.
- */
-int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv,
- const size_t *argvlen)
-{
- sds cmd;
- unsigned long long totlen;
- int j;
- size_t len;
-
- /* Abort on a NULL target */
- if (target == NULL)
- return -1;
-
- /* Calculate our total size */
- totlen = 1+countDigits(argc)+2;
- for (j = 0; j < argc; j++) {
- len = argvlen ? argvlen[j] : strlen(argv[j]);
- totlen += bulklen(len);
- }
-
- /* Use an SDS string for command construction */
- cmd = sdsempty();
- if (cmd == NULL)
- return -1;
-
- /* We already know how much storage we need */
- cmd = sdsMakeRoomFor(cmd, totlen);
- if (cmd == NULL)
- return -1;
-
- /* Construct command */
- cmd = sdscatfmt(cmd, "*%i\r\n", argc);
- for (j=0; j < argc; j++) {
- len = argvlen ? argvlen[j] : strlen(argv[j]);
- cmd = sdscatfmt(cmd, "$%u\r\n", len);
- cmd = sdscatlen(cmd, argv[j], len);
- cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1);
- }
-
- assert(sdslen(cmd)==totlen);
-
- *target = cmd;
- return totlen;
-}
-
-void redisFreeSdsCommand(sds cmd) {
- sdsfree(cmd);
-}
-
-/* Format a command according to the Redis protocol. This function takes the
- * number of arguments, an array with arguments and an array with their
- * lengths. If the latter is set to NULL, strlen will be used to compute the
- * argument lengths.
- */
-int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) {
- char *cmd = NULL; /* final command */
- int pos; /* position in final command */
- size_t len;
- int totlen, j;
-
- /* Abort on a NULL target */
- if (target == NULL)
- return -1;
-
- /* Calculate number of bytes needed for the command */
- totlen = 1+countDigits(argc)+2;
- for (j = 0; j < argc; j++) {
- len = argvlen ? argvlen[j] : strlen(argv[j]);
- totlen += bulklen(len);
- }
-
- /* Build the command at protocol level */
- cmd = malloc(totlen+1);
- if (cmd == NULL)
- return -1;
-
- pos = sprintf(cmd,"*%d\r\n",argc);
- for (j = 0; j < argc; j++) {
- len = argvlen ? argvlen[j] : strlen(argv[j]);
- pos += sprintf(cmd+pos,"$%zu\r\n",len);
- memcpy(cmd+pos,argv[j],len);
- pos += len;
- cmd[pos++] = '\r';
- cmd[pos++] = '\n';
- }
- assert(pos == totlen);
- cmd[pos] = '\0';
-
- *target = cmd;
- return totlen;
-}
-
-void redisFreeCommand(char *cmd) {
- free(cmd);
-}
-
-void __redisSetError(redisContext *c, int type, const char *str) {
- size_t len;
-
- c->err = type;
- if (str != NULL) {
- len = strlen(str);
- len = len < (sizeof(c->errstr)-1) ? len : (sizeof(c->errstr)-1);
- memcpy(c->errstr,str,len);
- c->errstr[len] = '\0';
- } else {
- /* Only REDIS_ERR_IO may lack a description! */
- assert(type == REDIS_ERR_IO);
- strerror_r(errno, c->errstr, sizeof(c->errstr));
- }
-}
-
-redisReader *redisReaderCreate(void) {
- return redisReaderCreateWithFunctions(&defaultFunctions);
-}
-
-static redisContext *redisContextInit(const redisOptions *options) {
- redisContext *c;
-
- c = calloc(1, sizeof(*c));
- if (c == NULL)
- return NULL;
-
- c->funcs = &redisContextDefaultFuncs;
- c->obuf = sdsempty();
- c->reader = redisReaderCreate();
- c->fd = REDIS_INVALID_FD;
-
- if (c->obuf == NULL || c->reader == NULL) {
- redisFree(c);
- return NULL;
- }
- (void)options; /* options are used in other functions */
- return c;
-}
-
-void redisFree(redisContext *c) {
- if (c == NULL)
- return;
- redisNetClose(c);
-
- sdsfree(c->obuf);
- redisReaderFree(c->reader);
- free(c->tcp.host);
- free(c->tcp.source_addr);
- free(c->unix_sock.path);
- free(c->timeout);
- free(c->saddr);
- if (c->funcs->free_privdata) {
- c->funcs->free_privdata(c->privdata);
- }
- memset(c, 0xff, sizeof(*c));
- free(c);
-}
-
-redisFD redisFreeKeepFd(redisContext *c) {
- redisFD fd = c->fd;
- c->fd = REDIS_INVALID_FD;
- redisFree(c);
- return fd;
-}
-
-int redisReconnect(redisContext *c) {
- c->err = 0;
- memset(c->errstr, '\0', strlen(c->errstr));
-
- if (c->privdata && c->funcs->free_privdata) {
- c->funcs->free_privdata(c->privdata);
- c->privdata = NULL;
- }
-
- redisNetClose(c);
-
- sdsfree(c->obuf);
- redisReaderFree(c->reader);
-
- c->obuf = sdsempty();
- c->reader = redisReaderCreate();
-
- if (c->connection_type == REDIS_CONN_TCP) {
- return redisContextConnectBindTcp(c, c->tcp.host, c->tcp.port,
- c->timeout, c->tcp.source_addr);
- } else if (c->connection_type == REDIS_CONN_UNIX) {
- return redisContextConnectUnix(c, c->unix_sock.path, c->timeout);
- } else {
- /* Something bad happened here and shouldn't have. There isn't
- enough information in the context to reconnect. */
- __redisSetError(c,REDIS_ERR_OTHER,"Not enough information to reconnect");
- }
-
- return REDIS_ERR;
-}
-
-redisContext *redisConnectWithOptions(const redisOptions *options) {
- redisContext *c = redisContextInit(options);
- if (c == NULL) {
- return NULL;
- }
- if (!(options->options & REDIS_OPT_NONBLOCK)) {
- c->flags |= REDIS_BLOCK;
- }
- if (options->options & REDIS_OPT_REUSEADDR) {
- c->flags |= REDIS_REUSEADDR;
- }
- if (options->options & REDIS_OPT_NOAUTOFREE) {
- c->flags |= REDIS_NO_AUTO_FREE;
- }
-
- if (options->type == REDIS_CONN_TCP) {
- redisContextConnectBindTcp(c, options->endpoint.tcp.ip,
- options->endpoint.tcp.port, options->timeout,
- options->endpoint.tcp.source_addr);
- } else if (options->type == REDIS_CONN_UNIX) {
- redisContextConnectUnix(c, options->endpoint.unix_socket,
- options->timeout);
- } else if (options->type == REDIS_CONN_USERFD) {
- c->fd = options->endpoint.fd;
- c->flags |= REDIS_CONNECTED;
- } else {
- // Unknown type - FIXME - FREE
- return NULL;
- }
- if (options->timeout != NULL && (c->flags & REDIS_BLOCK) && c->fd != REDIS_INVALID_FD) {
- redisContextSetTimeout(c, *options->timeout);
- }
- return c;
-}
-
-/* Connect to a Redis instance. On error the field error in the returned
- * context will be set to the return value of the error function.
- * When no set of reply functions is given, the default set will be used. */
-redisContext *redisConnect(const char *ip, int port) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, ip, port);
- return redisConnectWithOptions(&options);
-}
-
-redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, ip, port);
- options.timeout = &tv;
- return redisConnectWithOptions(&options);
-}
-
-redisContext *redisConnectNonBlock(const char *ip, int port) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, ip, port);
- options.options |= REDIS_OPT_NONBLOCK;
- return redisConnectWithOptions(&options);
-}
-
-redisContext *redisConnectBindNonBlock(const char *ip, int port,
- const char *source_addr) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, ip, port);
- options.endpoint.tcp.source_addr = source_addr;
- options.options |= REDIS_OPT_NONBLOCK;
- return redisConnectWithOptions(&options);
-}
-
-redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
- const char *source_addr) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_TCP(&options, ip, port);
- options.endpoint.tcp.source_addr = source_addr;
- options.options |= REDIS_OPT_NONBLOCK|REDIS_OPT_REUSEADDR;
- return redisConnectWithOptions(&options);
-}
-
-redisContext *redisConnectUnix(const char *path) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_UNIX(&options, path);
- return redisConnectWithOptions(&options);
-}
-
-redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_UNIX(&options, path);
- options.timeout = &tv;
- return redisConnectWithOptions(&options);
-}
-
-redisContext *redisConnectUnixNonBlock(const char *path) {
- redisOptions options = {0};
- REDIS_OPTIONS_SET_UNIX(&options, path);
- options.options |= REDIS_OPT_NONBLOCK;
- return redisConnectWithOptions(&options);
-}
-
-redisContext *redisConnectFd(redisFD fd) {
- redisOptions options = {0};
- options.type = REDIS_CONN_USERFD;
- options.endpoint.fd = fd;
- return redisConnectWithOptions(&options);
-}
-
-/* Set read/write timeout on a blocking socket. */
-int redisSetTimeout(redisContext *c, const struct timeval tv) {
- if (c->flags & REDIS_BLOCK)
- return redisContextSetTimeout(c,tv);
- return REDIS_ERR;
-}
-
-/* Enable connection KeepAlive. */
-int redisEnableKeepAlive(redisContext *c) {
- if (redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL) != REDIS_OK)
- return REDIS_ERR;
- return REDIS_OK;
-}
-
-/* Use this function to handle a read event on the descriptor. It will try
- * and read some bytes from the socket and feed them to the reply parser.
- *
- * After this function is called, you may use redisGetReplyFromReader to
- * see if there is a reply available. */
-int redisBufferRead(redisContext *c) {
- char buf[1024*16];
- int nread;
-
- /* Return early when the context has seen an error. */
- if (c->err)
- return REDIS_ERR;
-
- nread = c->funcs->read(c, buf, sizeof(buf));
- if (nread > 0) {
- if (redisReaderFeed(c->reader, buf, nread) != REDIS_OK) {
- __redisSetError(c, c->reader->err, c->reader->errstr);
- return REDIS_ERR;
- } else {
- }
- } else if (nread < 0) {
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-/* Write the output buffer to the socket.
- *
- * Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
- * successfully written to the socket. When the buffer is empty after the
- * write operation, "done" is set to 1 (if given).
- *
- * Returns REDIS_ERR if an error occurred trying to write and sets
- * c->errstr to hold the appropriate error string.
- */
-int redisBufferWrite(redisContext *c, int *done) {
-
- /* Return early when the context has seen an error. */
- if (c->err)
- return REDIS_ERR;
-
- if (sdslen(c->obuf) > 0) {
- int nwritten = c->funcs->write(c);
- if (nwritten < 0) {
- return REDIS_ERR;
- } else if (nwritten > 0) {
- if (nwritten == (signed)sdslen(c->obuf)) {
- sdsfree(c->obuf);
- c->obuf = sdsempty();
- } else {
- sdsrange(c->obuf,nwritten,-1);
- }
- }
- }
- if (done != NULL) *done = (sdslen(c->obuf) == 0);
- return REDIS_OK;
-}
-
-/* Internal helper function to try and get a reply from the reader,
- * or set an error in the context otherwise. */
-int redisGetReplyFromReader(redisContext *c, void **reply) {
- if (redisReaderGetReply(c->reader,reply) == REDIS_ERR) {
- __redisSetError(c,c->reader->err,c->reader->errstr);
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-int redisGetReply(redisContext *c, void **reply) {
- int wdone = 0;
- void *aux = NULL;
-
- /* Try to read pending replies */
- if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
- return REDIS_ERR;
-
- /* For the blocking context, flush output buffer and read reply */
- if (aux == NULL && c->flags & REDIS_BLOCK) {
- /* Write until done */
- do {
- if (redisBufferWrite(c,&wdone) == REDIS_ERR)
- return REDIS_ERR;
- } while (!wdone);
-
- /* Read until there is a reply */
- do {
- if (redisBufferRead(c) == REDIS_ERR)
- return REDIS_ERR;
- if (redisGetReplyFromReader(c,&aux) == REDIS_ERR)
- return REDIS_ERR;
- } while (aux == NULL);
- }
-
- /* Set reply object */
- if (reply != NULL) *reply = aux;
- return REDIS_OK;
-}
-
-
-/* Helper function for the redisAppendCommand* family of functions.
- *
- * Write a formatted command to the output buffer. When this family
- * is used, you need to call redisGetReply yourself to retrieve
- * the reply (or replies in pub/sub).
- */
-int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) {
- sds newbuf;
-
- newbuf = sdscatlen(c->obuf,cmd,len);
- if (newbuf == NULL) {
- __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- }
-
- c->obuf = newbuf;
- return REDIS_OK;
-}
-
-int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len) {
-
- if (__redisAppendCommand(c, cmd, len) != REDIS_OK) {
- return REDIS_ERR;
- }
-
- return REDIS_OK;
-}
-
-int redisvAppendCommand(redisContext *c, const char *format, va_list ap) {
- char *cmd;
- int len;
-
- len = redisvFormatCommand(&cmd,format,ap);
- if (len == -1) {
- __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- } else if (len == -2) {
- __redisSetError(c,REDIS_ERR_OTHER,"Invalid format string");
- return REDIS_ERR;
- }
-
- if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
- free(cmd);
- return REDIS_ERR;
- }
-
- free(cmd);
- return REDIS_OK;
-}
-
-int redisAppendCommand(redisContext *c, const char *format, ...) {
- va_list ap;
- int ret;
-
- va_start(ap,format);
- ret = redisvAppendCommand(c,format,ap);
- va_end(ap);
- return ret;
-}
-
-int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
- sds cmd;
- int len;
-
- len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
- if (len == -1) {
- __redisSetError(c,REDIS_ERR_OOM,"Out of memory");
- return REDIS_ERR;
- }
-
- if (__redisAppendCommand(c,cmd,len) != REDIS_OK) {
- sdsfree(cmd);
- return REDIS_ERR;
- }
-
- sdsfree(cmd);
- return REDIS_OK;
-}
-
-/* Helper function for the redisCommand* family of functions.
- *
- * Write a formatted command to the output buffer. If the given context is
- * blocking, immediately read the reply into the "reply" pointer. When the
- * context is non-blocking, the "reply" pointer will not be used and the
- * command is simply appended to the write buffer.
- *
- * Returns the reply when a reply was successfully retrieved. Returns NULL
- * otherwise. When NULL is returned in a blocking context, the error field
- * in the context will be set.
- */
-static void *__redisBlockForReply(redisContext *c) {
- void *reply;
-
- if (c->flags & REDIS_BLOCK) {
- if (redisGetReply(c,&reply) != REDIS_OK)
- return NULL;
- return reply;
- }
- return NULL;
-}
-
-void *redisvCommand(redisContext *c, const char *format, va_list ap) {
- if (redisvAppendCommand(c,format,ap) != REDIS_OK)
- return NULL;
- return __redisBlockForReply(c);
-}
-
-void *redisCommand(redisContext *c, const char *format, ...) {
- va_list ap;
- va_start(ap,format);
- void *reply = redisvCommand(c,format,ap);
- va_end(ap);
- return reply;
-}
-
-void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
- if (redisAppendCommandArgv(c,argc,argv,argvlen) != REDIS_OK)
- return NULL;
- return __redisBlockForReply(c);
-}
diff --git a/deps/hiredis/hiredis.h b/deps/hiredis/hiredis.h
deleted file mode 100644
index 69dc39c5e..000000000
--- a/deps/hiredis/hiredis.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- * Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HIREDIS_H
-#define __HIREDIS_H
-#include "read.h"
-#include <stdarg.h> /* for va_list */
-#ifndef _MSC_VER
-#include <sys/time.h> /* for struct timeval */
-#else
-struct timeval; /* forward declaration */
-#endif
-#include <stdint.h> /* uintXX_t, etc */
-#include "sds.h" /* for sds */
-
-#define HIREDIS_MAJOR 0
-#define HIREDIS_MINOR 14
-#define HIREDIS_PATCH 0
-#define HIREDIS_SONAME 0.14
-
-/* Connection type can be blocking or non-blocking and is set in the
- * least significant bit of the flags field in redisContext. */
-#define REDIS_BLOCK 0x1
-
-/* Connection may be disconnected before being free'd. The second bit
- * in the flags field is set when the context is connected. */
-#define REDIS_CONNECTED 0x2
-
-/* The async API might try to disconnect cleanly and flush the output
- * buffer and read all subsequent replies before disconnecting.
- * This flag means no new commands can come in and the connection
- * should be terminated once all replies have been read. */
-#define REDIS_DISCONNECTING 0x4
-
-/* Flag specific to the async API which means that the context should be clean
- * up as soon as possible. */
-#define REDIS_FREEING 0x8
-
-/* Flag that is set when an async callback is executed. */
-#define REDIS_IN_CALLBACK 0x10
-
-/* Flag that is set when the async context has one or more subscriptions. */
-#define REDIS_SUBSCRIBED 0x20
-
-/* Flag that is set when monitor mode is active */
-#define REDIS_MONITORING 0x40
-
-/* Flag that is set when we should set SO_REUSEADDR before calling bind() */
-#define REDIS_REUSEADDR 0x80
-
-/**
- * Flag that indicates the user does not want the context to
- * be automatically freed upon error
- */
-#define REDIS_NO_AUTO_FREE 0x200
-
-#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */
-
-/* number of times we retry to connect in the case of EADDRNOTAVAIL and
- * SO_REUSEADDR is being used. */
-#define REDIS_CONNECT_RETRIES 10
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This is the reply object returned by redisCommand() */
-typedef struct redisReply {
- int type; /* REDIS_REPLY_* */
- long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
- double dval; /* The double when type is REDIS_REPLY_DOUBLE */
- size_t len; /* Length of string */
- char *str; /* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING
- and REDIS_REPLY_DOUBLE (in additionl to dval). */
- char vtype[4]; /* Used for REDIS_REPLY_VERB, contains the null
- terminated 3 character content type, such as "txt". */
- size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
- struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
-} redisReply;
-
-redisReader *redisReaderCreate(void);
-
-/* Function to free the reply objects hiredis returns by default. */
-void freeReplyObject(void *reply);
-
-/* Functions to format a command according to the protocol. */
-int redisvFormatCommand(char **target, const char *format, va_list ap);
-int redisFormatCommand(char **target, const char *format, ...);
-int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
-int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen);
-void redisFreeCommand(char *cmd);
-void redisFreeSdsCommand(sds cmd);
-
-enum redisConnectionType {
- REDIS_CONN_TCP,
- REDIS_CONN_UNIX,
- REDIS_CONN_USERFD
-};
-
-struct redisSsl;
-
-#define REDIS_OPT_NONBLOCK 0x01
-#define REDIS_OPT_REUSEADDR 0x02
-
-/**
- * Don't automatically free the async object on a connection failure,
- * or other implicit conditions. Only free on an explicit call to disconnect() or free()
- */
-#define REDIS_OPT_NOAUTOFREE 0x04
-
-/* In Unix systems a file descriptor is a regular signed int, with -1
- * representing an invalid descriptor. In Windows it is a SOCKET
- * (32- or 64-bit unsigned integer depending on the architecture), where
- * all bits set (~0) is INVALID_SOCKET. */
-#ifndef _WIN32
-typedef int redisFD;
-#define REDIS_INVALID_FD -1
-#else
-#ifdef _WIN64
-typedef unsigned long long redisFD; /* SOCKET = 64-bit UINT_PTR */
-#else
-typedef unsigned long redisFD; /* SOCKET = 32-bit UINT_PTR */
-#endif
-#define REDIS_INVALID_FD ((redisFD)(~0)) /* INVALID_SOCKET */
-#endif
-
-typedef struct {
- /*
- * the type of connection to use. This also indicates which
- * `endpoint` member field to use
- */
- int type;
- /* bit field of REDIS_OPT_xxx */
- int options;
- /* timeout value. if NULL, no timeout is used */
- const struct timeval *timeout;
- union {
- /** use this field for tcp/ip connections */
- struct {
- const char *source_addr;
- const char *ip;
- int port;
- } tcp;
- /** use this field for unix domain sockets */
- const char *unix_socket;
- /**
- * use this field to have hiredis operate an already-open
- * file descriptor */
- redisFD fd;
- } endpoint;
-} redisOptions;
-
-/**
- * Helper macros to initialize options to their specified fields.
- */
-#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \
- (opts)->type = REDIS_CONN_TCP; \
- (opts)->endpoint.tcp.ip = ip_; \
- (opts)->endpoint.tcp.port = port_;
-
-#define REDIS_OPTIONS_SET_UNIX(opts, path) \
- (opts)->type = REDIS_CONN_UNIX; \
- (opts)->endpoint.unix_socket = path;
-
-struct redisAsyncContext;
-struct redisContext;
-
-typedef struct redisContextFuncs {
- void (*free_privdata)(void *);
- void (*async_read)(struct redisAsyncContext *);
- void (*async_write)(struct redisAsyncContext *);
- int (*read)(struct redisContext *, char *, size_t);
- int (*write)(struct redisContext *);
-} redisContextFuncs;
-
-/* Context for a connection to Redis */
-typedef struct redisContext {
- const redisContextFuncs *funcs; /* Function table */
-
- int err; /* Error flags, 0 when there is no error */
- char errstr[128]; /* String representation of error when applicable */
- redisFD fd;
- int flags;
- char *obuf; /* Write buffer */
- redisReader *reader; /* Protocol reader */
-
- enum redisConnectionType connection_type;
- struct timeval *timeout;
-
- struct {
- char *host;
- char *source_addr;
- int port;
- } tcp;
-
- struct {
- char *path;
- } unix_sock;
-
- /* For non-blocking connect */
- struct sockadr *saddr;
- size_t addrlen;
-
- /* Additional private data for hiredis addons such as SSL */
- void *privdata;
-} redisContext;
-
-redisContext *redisConnectWithOptions(const redisOptions *options);
-redisContext *redisConnect(const char *ip, int port);
-redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
-redisContext *redisConnectNonBlock(const char *ip, int port);
-redisContext *redisConnectBindNonBlock(const char *ip, int port,
- const char *source_addr);
-redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
- const char *source_addr);
-redisContext *redisConnectUnix(const char *path);
-redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
-redisContext *redisConnectUnixNonBlock(const char *path);
-redisContext *redisConnectFd(redisFD fd);
-
-/**
- * Reconnect the given context using the saved information.
- *
- * This re-uses the exact same connect options as in the initial connection.
- * host, ip (or path), timeout and bind address are reused,
- * flags are used unmodified from the existing context.
- *
- * Returns REDIS_OK on successful connect or REDIS_ERR otherwise.
- */
-int redisReconnect(redisContext *c);
-
-int redisSetTimeout(redisContext *c, const struct timeval tv);
-int redisEnableKeepAlive(redisContext *c);
-void redisFree(redisContext *c);
-redisFD redisFreeKeepFd(redisContext *c);
-int redisBufferRead(redisContext *c);
-int redisBufferWrite(redisContext *c, int *done);
-
-/* In a blocking context, this function first checks if there are unconsumed
- * replies to return and returns one if so. Otherwise, it flushes the output
- * buffer to the socket and reads until it has a reply. In a non-blocking
- * context, it will return unconsumed replies until there are no more. */
-int redisGetReply(redisContext *c, void **reply);
-int redisGetReplyFromReader(redisContext *c, void **reply);
-
-/* Write a formatted command to the output buffer. Use these functions in blocking mode
- * to get a pipeline of commands. */
-int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len);
-
-/* Write a command to the output buffer. Use these functions in blocking mode
- * to get a pipeline of commands. */
-int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
-int redisAppendCommand(redisContext *c, const char *format, ...);
-int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
-
-/* Issue a command to Redis. In a blocking context, it is identical to calling
- * redisAppendCommand, followed by redisGetReply. The function will return
- * NULL if there was an error in performing the request, otherwise it will
- * return the reply. In a non-blocking context, it is identical to calling
- * only redisAppendCommand and will always return NULL. */
-void *redisvCommand(redisContext *c, const char *format, va_list ap);
-void *redisCommand(redisContext *c, const char *format, ...);
-void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/deps/hiredis/hiredis.pc.in b/deps/hiredis/hiredis.pc.in
deleted file mode 100644
index 140b040f1..000000000
--- a/deps/hiredis/hiredis.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=${exec_prefix}/lib
-includedir=${prefix}/include
-pkgincludedir=${includedir}/hiredis
-
-Name: hiredis
-Description: Minimalistic C client library for Redis.
-Version: @PROJECT_VERSION@
-Libs: -L${libdir} -lhiredis
-Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64
diff --git a/deps/hiredis/hiredis_ssl.h b/deps/hiredis/hiredis_ssl.h
deleted file mode 100644
index f844f9548..000000000
--- a/deps/hiredis/hiredis_ssl.h
+++ /dev/null
@@ -1,53 +0,0 @@
-
-/*
- * Copyright (c) 2019, Redis Labs
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __HIREDIS_SSL_H
-#define __HIREDIS_SSL_H
-
-/* This is the underlying struct for SSL in ssl.h, which is not included to
- * keep build dependencies short here.
- */
-struct ssl_st;
-
-/**
- * Secure the connection using SSL. This should be done before any command is
- * executed on the connection.
- */
-int redisSecureConnection(redisContext *c, const char *capath, const char *certpath,
- const char *keypath, const char *servername);
-
-/**
- * Initiate SSL/TLS negotiation on a provided context.
- */
-
-int redisInitiateSSL(redisContext *c, struct ssl_st *ssl);
-
-#endif /* __HIREDIS_SSL_H */
diff --git a/deps/hiredis/hiredis_ssl.pc.in b/deps/hiredis/hiredis_ssl.pc.in
deleted file mode 100644
index 588a978a5..000000000
--- a/deps/hiredis/hiredis_ssl.pc.in
+++ /dev/null
@@ -1,12 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=${exec_prefix}/lib
-includedir=${prefix}/include
-pkgincludedir=${includedir}/hiredis
-
-Name: hiredis_ssl
-Description: SSL Support for hiredis.
-Version: @PROJECT_VERSION@
-Requires: hiredis
-Libs: -L${libdir} -lhiredis_ssl
-Libs.private: -lssl -lcrypto
diff --git a/deps/hiredis/net.c b/deps/hiredis/net.c
deleted file mode 100644
index e5f40b0a4..000000000
--- a/deps/hiredis/net.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/* Extracted from anet.c to work properly with Hiredis error reporting.
- *
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- * Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "fmacros.h"
-#include <sys/types.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include "net.h"
-#include "sds.h"
-#include "sockcompat.h"
-#include "win32.h"
-
-/* Defined in hiredis.c */
-void __redisSetError(redisContext *c, int type, const char *str);
-
-void redisNetClose(redisContext *c) {
- if (c && c->fd != REDIS_INVALID_FD) {
- close(c->fd);
- c->fd = REDIS_INVALID_FD;
- }
-}
-
-int redisNetRead(redisContext *c, char *buf, size_t bufcap) {
- int nread = recv(c->fd, buf, bufcap, 0);
- if (nread == -1) {
- if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
- /* Try again later */
- return 0;
- } else if(errno == ETIMEDOUT && (c->flags & REDIS_BLOCK)) {
- /* especially in windows */
- __redisSetError(c, REDIS_ERR_TIMEOUT, "recv timeout");
- return -1;
- } else {
- __redisSetError(c, REDIS_ERR_IO, NULL);
- return -1;
- }
- } else if (nread == 0) {
- __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection");
- return -1;
- } else {
- return nread;
- }
-}
-
-int redisNetWrite(redisContext *c) {
- int nwritten = send(c->fd, c->obuf, sdslen(c->obuf), 0);
- if (nwritten < 0) {
- if ((errno == EWOULDBLOCK && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
- /* Try again later */
- } else {
- __redisSetError(c, REDIS_ERR_IO, NULL);
- return -1;
- }
- }
- return nwritten;
-}
-
-static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) {
- int errorno = errno; /* snprintf() may change errno */
- char buf[128] = { 0 };
- size_t len = 0;
-
- if (prefix != NULL)
- len = snprintf(buf,sizeof(buf),"%s: ",prefix);
- strerror_r(errorno, (char *)(buf + len), sizeof(buf) - len);
- __redisSetError(c,type,buf);
-}
-
-static int redisSetReuseAddr(redisContext *c) {
- int on = 1;
- if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- redisNetClose(c);
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-static int redisCreateSocket(redisContext *c, int type) {
- redisFD s;
- if ((s = socket(type, SOCK_STREAM, 0)) == REDIS_INVALID_FD) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- return REDIS_ERR;
- }
- c->fd = s;
- if (type == AF_INET) {
- if (redisSetReuseAddr(c) == REDIS_ERR) {
- return REDIS_ERR;
- }
- }
- return REDIS_OK;
-}
-
-static int redisSetBlocking(redisContext *c, int blocking) {
-#ifndef _WIN32
- int flags;
-
- /* Set the socket nonblocking.
- * Note that fcntl(2) for F_GETFL and F_SETFL can't be
- * interrupted by a signal. */
- if ((flags = fcntl(c->fd, F_GETFL)) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
- redisNetClose(c);
- return REDIS_ERR;
- }
-
- if (blocking)
- flags &= ~O_NONBLOCK;
- else
- flags |= O_NONBLOCK;
-
- if (fcntl(c->fd, F_SETFL, flags) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
- redisNetClose(c);
- return REDIS_ERR;
- }
-#else
- u_long mode = blocking ? 0 : 1;
- if (ioctl(c->fd, FIONBIO, &mode) == -1) {
- __redisSetErrorFromErrno(c, REDIS_ERR_IO, "ioctl(FIONBIO)");
- redisNetClose(c);
- return REDIS_ERR;
- }
-#endif /* _WIN32 */
- return REDIS_OK;
-}
-
-int redisKeepAlive(redisContext *c, int interval) {
- int val = 1;
- redisFD fd = c->fd;
-
- if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
- return REDIS_ERR;
- }
-
- val = interval;
-
-#if defined(__APPLE__) && defined(__MACH__)
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) {
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
- return REDIS_ERR;
- }
-#else
-#if defined(__GLIBC__) && !defined(__FreeBSD_kernel__)
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) {
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
- return REDIS_ERR;
- }
-
- val = interval/3;
- if (val == 0) val = 1;
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) {
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
- return REDIS_ERR;
- }
-
- val = 3;
- if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) {
- __redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
- return REDIS_ERR;
- }
-#endif
-#endif
-
- return REDIS_OK;
-}
-
-static int redisSetTcpNoDelay(redisContext *c) {
- int yes = 1;
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
- redisNetClose(c);
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-#define __MAX_MSEC (((LONG_MAX) - 999) / 1000)
-
-static int redisContextTimeoutMsec(redisContext *c, long *result)
-{
- const struct timeval *timeout = c->timeout;
- long msec = -1;
-
- /* Only use timeout when not NULL. */
- if (timeout != NULL) {
- if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
- *result = msec;
- return REDIS_ERR;
- }
-
- msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);
-
- if (msec < 0 || msec > INT_MAX) {
- msec = INT_MAX;
- }
- }
-
- *result = msec;
- return REDIS_OK;
-}
-
-static int redisContextWaitReady(redisContext *c, long msec) {
- struct pollfd wfd[1];
-
- wfd[0].fd = c->fd;
- wfd[0].events = POLLOUT;
-
- if (errno == EINPROGRESS) {
- int res;
-
- if ((res = poll(wfd, 1, msec)) == -1) {
- __redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
- redisNetClose(c);
- return REDIS_ERR;
- } else if (res == 0) {
- errno = ETIMEDOUT;
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- redisNetClose(c);
- return REDIS_ERR;
- }
-
- if (redisCheckConnectDone(c, &res) != REDIS_OK || res == 0) {
- redisCheckSocketError(c);
- return REDIS_ERR;
- }
-
- return REDIS_OK;
- }
-
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- redisNetClose(c);
- return REDIS_ERR;
-}
-
-int redisCheckConnectDone(redisContext *c, int *completed) {
- int rc = connect(c->fd, (const struct sockaddr *)c->saddr, c->addrlen);
- if (rc == 0) {
- *completed = 1;
- return REDIS_OK;
- }
- switch (errno) {
- case EISCONN:
- *completed = 1;
- return REDIS_OK;
- case EALREADY:
- case EINPROGRESS:
- case EWOULDBLOCK:
- *completed = 0;
- return REDIS_OK;
- default:
- return REDIS_ERR;
- }
-}
-
-int redisCheckSocketError(redisContext *c) {
- int err = 0, errno_saved = errno;
- socklen_t errlen = sizeof(err);
-
- if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
- return REDIS_ERR;
- }
-
- if (err == 0) {
- err = errno_saved;
- }
-
- if (err) {
- errno = err;
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
- return REDIS_ERR;
- }
-
- return REDIS_OK;
-}
-
-int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
- const void *to_ptr = &tv;
- size_t to_sz = sizeof(tv);
-#ifdef _WIN32
- DWORD timeout_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
- to_ptr = &timeout_msec;
- to_sz = sizeof(timeout_msec);
-#endif
- if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,to_ptr,to_sz) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)");
- return REDIS_ERR;
- }
- if (setsockopt(c->fd,SOL_SOCKET,SO_SNDTIMEO,to_ptr,to_sz) == -1) {
- __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_SNDTIMEO)");
- return REDIS_ERR;
- }
- return REDIS_OK;
-}
-
-static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
- const struct timeval *timeout,
- const char *source_addr) {
- redisFD s;
- int rv, n;
- char _port[6]; /* strlen("65535"); */
- struct addrinfo hints, *servinfo, *bservinfo, *p, *b;
- int blocking = (c->flags & REDIS_BLOCK);
- int reuseaddr = (c->flags & REDIS_REUSEADDR);
- int reuses = 0;
- long timeout_msec = -1;
-
- servinfo = NULL;
- c->connection_type = REDIS_CONN_TCP;
- c->tcp.port = port;
-
- /* We need to take possession of the passed parameters
- * to make them reusable for a reconnect.
- * We also carefully check we don't free data we already own,
- * as in the case of the reconnect method.
- *
- * This is a bit ugly, but atleast it works and doesn't leak memory.
- **/
- if (c->tcp.host != addr) {
- free(c->tcp.host);
-
- c->tcp.host = strdup(addr);
- }
-
- if (timeout) {
- if (c->timeout != timeout) {
- if (c->timeout == NULL)
- c->timeout = malloc(sizeof(struct timeval));
-
- memcpy(c->timeout, timeout, sizeof(struct timeval));
- }
- } else {
- free(c->timeout);
- c->timeout = NULL;
- }
-
- if (redisContextTimeoutMsec(c, &timeout_msec) != REDIS_OK) {
- __redisSetError(c, REDIS_ERR_IO, "Invalid timeout specified");
- goto error;
- }
-
- if (source_addr == NULL) {
- free(c->tcp.source_addr);
- c->tcp.source_addr = NULL;
- } else if (c->tcp.source_addr != source_addr) {
- free(c->tcp.source_addr);
- c->tcp.source_addr = strdup(source_addr);
- }
-
- snprintf(_port, 6, "%d", port);
- memset(&hints,0,sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
-
- /* Try with IPv6 if no IPv4 address was found. We do it in this order since
- * in a Redis client you can't afford to test if you have IPv6 connectivity
- * as this would add latency to every connect. Otherwise a more sensible
- * route could be: Use IPv6 if both addresses are available and there is IPv6
- * connectivity. */
- if ((rv = getaddrinfo(c->tcp.host,_port,&hints,&servinfo)) != 0) {
- hints.ai_family = AF_INET6;
- if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
- __redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv));
- return REDIS_ERR;
- }
- }
- for (p = servinfo; p != NULL; p = p->ai_next) {
-addrretry:
- if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == REDIS_INVALID_FD)
- continue;
-
- c->fd = s;
- if (redisSetBlocking(c,0) != REDIS_OK)
- goto error;
- if (c->tcp.source_addr) {
- int bound = 0;
- /* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */
- if ((rv = getaddrinfo(c->tcp.source_addr, NULL, &hints, &bservinfo)) != 0) {
- char buf[128];
- snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv));
- __redisSetError(c,REDIS_ERR_OTHER,buf);
- goto error;
- }
-
- if (reuseaddr) {
- n = 1;
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*) &n,
- sizeof(n)) < 0) {
- freeaddrinfo(bservinfo);
- goto error;
- }
- }
-
- for (b = bservinfo; b != NULL; b = b->ai_next) {
- if (bind(s,b->ai_addr,b->ai_addrlen) != -1) {
- bound = 1;
- break;
- }
- }
- freeaddrinfo(bservinfo);
- if (!bound) {
- char buf[128];
- snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno));
- __redisSetError(c,REDIS_ERR_OTHER,buf);
- goto error;
- }
- }
-
- /* For repeat connection */
- free(c->saddr);
- c->saddr = malloc(p->ai_addrlen);
- memcpy(c->saddr, p->ai_addr, p->ai_addrlen);
- c->addrlen = p->ai_addrlen;
-
- if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
- if (errno == EHOSTUNREACH) {
- redisNetClose(c);
- continue;
- } else if (errno == EINPROGRESS) {
- if (blocking) {
- goto wait_for_ready;
- }
- /* This is ok.
- * Note that even when it's in blocking mode, we unset blocking
- * for `connect()`
- */
- } else if (errno == EADDRNOTAVAIL && reuseaddr) {
- if (++reuses >= REDIS_CONNECT_RETRIES) {
- goto error;
- } else {
- redisNetClose(c);
- goto addrretry;
- }
- } else {
- wait_for_ready:
- if (redisContextWaitReady(c,timeout_msec) != REDIS_OK)
- goto error;
- }
- }
- if (blocking && redisSetBlocking(c,1) != REDIS_OK)
- goto error;
- if (redisSetTcpNoDelay(c) != REDIS_OK)
- goto error;
-
- c->flags |= REDIS_CONNECTED;
- rv = REDIS_OK;
- goto end;
- }
- if (p == NULL) {
- char buf[128];
- snprintf(buf,sizeof(buf),"Can't create socket: %s",strerror(errno));
- __redisSetError(c,REDIS_ERR_OTHER,buf);
- goto error;
- }
-
-error:
- rv = REDIS_ERR;
-end:
- if(servinfo) {
- freeaddrinfo(servinfo);
- }
-
- return rv; // Need to return REDIS_OK if alright
-}
-
-int redisContextConnectTcp(redisContext *c, const char *addr, int port,
- const struct timeval *timeout) {
- return _redisContextConnectTcp(c, addr, port, timeout, NULL);
-}
-
-int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
- const struct timeval *timeout,
- const char *source_addr) {
- return _redisContextConnectTcp(c, addr, port, timeout, source_addr);
-}
-
-int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) {
-#ifndef _WIN32
- int blocking = (c->flags & REDIS_BLOCK);
- struct sockaddr_un *sa;
- long timeout_msec = -1;
-
- if (redisCreateSocket(c,AF_UNIX) < 0)
- return REDIS_ERR;
- if (redisSetBlocking(c,0) != REDIS_OK)
- return REDIS_ERR;
-
- c->connection_type = REDIS_CONN_UNIX;
- if (c->unix_sock.path != path)
- c->unix_sock.path = strdup(path);
-
- if (timeout) {
- if (c->timeout != timeout) {
- if (c->timeout == NULL)
- c->timeout = malloc(sizeof(struct timeval));
-
- memcpy(c->timeout, timeout, sizeof(struct timeval));
- }
- } else {
- free(c->timeout);
- c->timeout = NULL;
- }
-
- if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK)
- return REDIS_ERR;
-
- sa = (struct sockaddr_un*)(c->saddr = malloc(sizeof(struct sockaddr_un)));
- c->addrlen = sizeof(struct sockaddr_un);
- sa->sun_family = AF_UNIX;
- strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1);
- if (connect(c->fd, (struct sockaddr*)sa, sizeof(*sa)) == -1) {
- if (errno == EINPROGRESS && !blocking) {
- /* This is ok. */
- } else {
- if (redisContextWaitReady(c,timeout_msec) != REDIS_OK)
- return REDIS_ERR;
- }
- }
-
- /* Reset socket to be blocking after connect(2). */
- if (blocking && redisSetBlocking(c,1) != REDIS_OK)
- return REDIS_ERR;
-
- c->flags |= REDIS_CONNECTED;
- return REDIS_OK;
-#else
- /* We currently do not support Unix sockets for Windows. */
- /* TODO(m): https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ */
- errno = EPROTONOSUPPORT;
- return REDIS_ERR;
-#endif /* _WIN32 */
-}
diff --git a/deps/hiredis/net.h b/deps/hiredis/net.h
deleted file mode 100644
index a4393c06b..000000000
--- a/deps/hiredis/net.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Extracted from anet.c to work properly with Hiredis error reporting.
- *
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2014, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2015, Matt Stancliff <matt at genges dot com>,
- * Jan-Erik Rediger <janerik at fnordig dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __NET_H
-#define __NET_H
-
-#include "hiredis.h"
-
-void redisNetClose(redisContext *c);
-int redisNetRead(redisContext *c, char *buf, size_t bufcap);
-int redisNetWrite(redisContext *c);
-
-int redisCheckSocketError(redisContext *c);
-int redisContextSetTimeout(redisContext *c, const struct timeval tv);
-int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout);
-int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
- const struct timeval *timeout,
- const char *source_addr);
-int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout);
-int redisKeepAlive(redisContext *c, int interval);
-int redisCheckConnectDone(redisContext *c, int *completed);
-
-#endif
diff --git a/deps/hiredis/read.c b/deps/hiredis/read.c
deleted file mode 100644
index b9853ea9a..000000000
--- a/deps/hiredis/read.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "fmacros.h"
-#include <string.h>
-#include <stdlib.h>
-#ifndef _MSC_VER
-#include <unistd.h>
-#include <strings.h>
-#endif
-#include <assert.h>
-#include <errno.h>
-#include <ctype.h>
-#include <limits.h>
-#include <math.h>
-
-#include "read.h"
-#include "sds.h"
-#include "win32.h"
-
-static void __redisReaderSetError(redisReader *r, int type, const char *str) {
- size_t len;
-
- if (r->reply != NULL && r->fn && r->fn->freeObject) {
- r->fn->freeObject(r->reply);
- r->reply = NULL;
- }
-
- /* Clear input buffer on errors. */
- sdsfree(r->buf);
- r->buf = NULL;
- r->pos = r->len = 0;
-
- /* Reset task stack. */
- r->ridx = -1;
-
- /* Set error. */
- r->err = type;
- len = strlen(str);
- len = len < (sizeof(r->errstr)-1) ? len : (sizeof(r->errstr)-1);
- memcpy(r->errstr,str,len);
- r->errstr[len] = '\0';
-}
-
-static size_t chrtos(char *buf, size_t size, char byte) {
- size_t len = 0;
-
- switch(byte) {
- case '\\':
- case '"':
- len = snprintf(buf,size,"\"\\%c\"",byte);
- break;
- case '\n': len = snprintf(buf,size,"\"\\n\""); break;
- case '\r': len = snprintf(buf,size,"\"\\r\""); break;
- case '\t': len = snprintf(buf,size,"\"\\t\""); break;
- case '\a': len = snprintf(buf,size,"\"\\a\""); break;
- case '\b': len = snprintf(buf,size,"\"\\b\""); break;
- default:
- if (isprint(byte))
- len = snprintf(buf,size,"\"%c\"",byte);
- else
- len = snprintf(buf,size,"\"\\x%02x\"",(unsigned char)byte);
- break;
- }
-
- return len;
-}
-
-static void __redisReaderSetErrorProtocolByte(redisReader *r, char byte) {
- char cbuf[8], sbuf[128];
-
- chrtos(cbuf,sizeof(cbuf),byte);
- snprintf(sbuf,sizeof(sbuf),
- "Protocol error, got %s as reply type byte", cbuf);
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,sbuf);
-}
-
-static void __redisReaderSetErrorOOM(redisReader *r) {
- __redisReaderSetError(r,REDIS_ERR_OOM,"Out of memory");
-}
-
-static char *readBytes(redisReader *r, unsigned int bytes) {
- char *p;
- if (r->len-r->pos >= bytes) {
- p = r->buf+r->pos;
- r->pos += bytes;
- return p;
- }
- return NULL;
-}
-
-/* Find pointer to \r\n. */
-static char *seekNewline(char *s, size_t len) {
- int pos = 0;
- int _len = len-1;
-
- /* Position should be < len-1 because the character at "pos" should be
- * followed by a \n. Note that strchr cannot be used because it doesn't
- * allow to search a limited length and the buffer that is being searched
- * might not have a trailing NULL character. */
- while (pos < _len) {
- while(pos < _len && s[pos] != '\r') pos++;
- if (pos==_len) {
- /* Not found. */
- return NULL;
- } else {
- if (s[pos+1] == '\n') {
- /* Found. */
- return s+pos;
- } else {
- /* Continue searching. */
- pos++;
- }
- }
- }
- return NULL;
-}
-
-/* Convert a string into a long long. Returns REDIS_OK if the string could be
- * parsed into a (non-overflowing) long long, REDIS_ERR otherwise. The value
- * will be set to the parsed value when appropriate.
- *
- * Note that this function demands that the string strictly represents
- * a long long: no spaces or other characters before or after the string
- * representing the number are accepted, nor zeroes at the start if not
- * for the string "0" representing the zero number.
- *
- * Because of its strictness, it is safe to use this function to check if
- * you can convert a string into a long long, and obtain back the string
- * from the number without any loss in the string representation. */
-static int string2ll(const char *s, size_t slen, long long *value) {
- const char *p = s;
- size_t plen = 0;
- int negative = 0;
- unsigned long long v;
-
- if (plen == slen)
- return REDIS_ERR;
-
- /* Special case: first and only digit is 0. */
- if (slen == 1 && p[0] == '0') {
- if (value != NULL) *value = 0;
- return REDIS_OK;
- }
-
- if (p[0] == '-') {
- negative = 1;
- p++; plen++;
-
- /* Abort on only a negative sign. */
- if (plen == slen)
- return REDIS_ERR;
- }
-
- /* First digit should be 1-9, otherwise the string should just be 0. */
- if (p[0] >= '1' && p[0] <= '9') {
- v = p[0]-'0';
- p++; plen++;
- } else if (p[0] == '0' && slen == 1) {
- *value = 0;
- return REDIS_OK;
- } else {
- return REDIS_ERR;
- }
-
- while (plen < slen && p[0] >= '0' && p[0] <= '9') {
- if (v > (ULLONG_MAX / 10)) /* Overflow. */
- return REDIS_ERR;
- v *= 10;
-
- if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */
- return REDIS_ERR;
- v += p[0]-'0';
-
- p++; plen++;
- }
-
- /* Return if not all bytes were used. */
- if (plen < slen)
- return REDIS_ERR;
-
- if (negative) {
- if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */
- return REDIS_ERR;
- if (value != NULL) *value = -v;
- } else {
- if (v > LLONG_MAX) /* Overflow. */
- return REDIS_ERR;
- if (value != NULL) *value = v;
- }
- return REDIS_OK;
-}
-
-static char *readLine(redisReader *r, int *_len) {
- char *p, *s;
- int len;
-
- p = r->buf+r->pos;
- s = seekNewline(p,(r->len-r->pos));
- if (s != NULL) {
- len = s-(r->buf+r->pos);
- r->pos += len+2; /* skip \r\n */
- if (_len) *_len = len;
- return p;
- }
- return NULL;
-}
-
-static void moveToNextTask(redisReader *r) {
- redisReadTask *cur, *prv;
- while (r->ridx >= 0) {
- /* Return a.s.a.p. when the stack is now empty. */
- if (r->ridx == 0) {
- r->ridx--;
- return;
- }
-
- cur = &(r->rstack[r->ridx]);
- prv = &(r->rstack[r->ridx-1]);
- assert(prv->type == REDIS_REPLY_ARRAY ||
- prv->type == REDIS_REPLY_MAP ||
- prv->type == REDIS_REPLY_SET);
- if (cur->idx == prv->elements-1) {
- r->ridx--;
- } else {
- /* Reset the type because the next item can be anything */
- assert(cur->idx < prv->elements);
- cur->type = -1;
- cur->elements = -1;
- cur->idx++;
- return;
- }
- }
-}
-
-static int processLineItem(redisReader *r) {
- redisReadTask *cur = &(r->rstack[r->ridx]);
- void *obj;
- char *p;
- int len;
-
- if ((p = readLine(r,&len)) != NULL) {
- if (cur->type == REDIS_REPLY_INTEGER) {
- if (r->fn && r->fn->createInteger) {
- long long v;
- if (string2ll(p, len, &v) == REDIS_ERR) {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "Bad integer value");
- return REDIS_ERR;
- }
- obj = r->fn->createInteger(cur,v);
- } else {
- obj = (void*)REDIS_REPLY_INTEGER;
- }
- } else if (cur->type == REDIS_REPLY_DOUBLE) {
- if (r->fn && r->fn->createDouble) {
- char buf[326], *eptr;
- double d;
-
- if ((size_t)len >= sizeof(buf)) {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "Double value is too large");
- return REDIS_ERR;
- }
-
- memcpy(buf,p,len);
- buf[len] = '\0';
-
- if (strcasecmp(buf,",inf") == 0) {
- d = INFINITY; /* Positive infinite. */
- } else if (strcasecmp(buf,",-inf") == 0) {
- d = -INFINITY; /* Nevative infinite. */
- } else {
- d = strtod((char*)buf,&eptr);
- if (buf[0] == '\0' || eptr[0] != '\0' || isnan(d)) {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "Bad double value");
- return REDIS_ERR;
- }
- }
- obj = r->fn->createDouble(cur,d,buf,len);
- } else {
- obj = (void*)REDIS_REPLY_DOUBLE;
- }
- } else if (cur->type == REDIS_REPLY_NIL) {
- if (r->fn && r->fn->createNil)
- obj = r->fn->createNil(cur);
- else
- obj = (void*)REDIS_REPLY_NIL;
- } else if (cur->type == REDIS_REPLY_BOOL) {
- int bval = p[0] == 't' || p[0] == 'T';
- if (r->fn && r->fn->createBool)
- obj = r->fn->createBool(cur,bval);
- else
- obj = (void*)REDIS_REPLY_BOOL;
- } else {
- /* Type will be error or status. */
- if (r->fn && r->fn->createString)
- obj = r->fn->createString(cur,p,len);
- else
- obj = (void*)(size_t)(cur->type);
- }
-
- if (obj == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- /* Set reply if this is the root object. */
- if (r->ridx == 0) r->reply = obj;
- moveToNextTask(r);
- return REDIS_OK;
- }
-
- return REDIS_ERR;
-}
-
-static int processBulkItem(redisReader *r) {
- redisReadTask *cur = &(r->rstack[r->ridx]);
- void *obj = NULL;
- char *p, *s;
- long long len;
- unsigned long bytelen;
- int success = 0;
-
- p = r->buf+r->pos;
- s = seekNewline(p,r->len-r->pos);
- if (s != NULL) {
- p = r->buf+r->pos;
- bytelen = s-(r->buf+r->pos)+2; /* include \r\n */
-
- if (string2ll(p, bytelen - 2, &len) == REDIS_ERR) {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "Bad bulk string length");
- return REDIS_ERR;
- }
-
- if (len < -1 || (LLONG_MAX > SIZE_MAX && len > (long long)SIZE_MAX)) {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "Bulk string length out of range");
- return REDIS_ERR;
- }
-
- if (len == -1) {
- /* The nil object can always be created. */
- if (r->fn && r->fn->createNil)
- obj = r->fn->createNil(cur);
- else
- obj = (void*)REDIS_REPLY_NIL;
- success = 1;
- } else {
- /* Only continue when the buffer contains the entire bulk item. */
- bytelen += len+2; /* include \r\n */
- if (r->pos+bytelen <= r->len) {
- if ((cur->type == REDIS_REPLY_VERB && len < 4) ||
- (cur->type == REDIS_REPLY_VERB && s[5] != ':'))
- {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "Verbatim string 4 bytes of content type are "
- "missing or incorrectly encoded.");
- return REDIS_ERR;
- }
- if (r->fn && r->fn->createString)
- obj = r->fn->createString(cur,s+2,len);
- else
- obj = (void*)(long)cur->type;
- success = 1;
- }
- }
-
- /* Proceed when obj was created. */
- if (success) {
- if (obj == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- r->pos += bytelen;
-
- /* Set reply if this is the root object. */
- if (r->ridx == 0) r->reply = obj;
- moveToNextTask(r);
- return REDIS_OK;
- }
- }
-
- return REDIS_ERR;
-}
-
-/* Process the array, map and set types. */
-static int processAggregateItem(redisReader *r) {
- redisReadTask *cur = &(r->rstack[r->ridx]);
- void *obj;
- char *p;
- long long elements;
- int root = 0, len;
-
- /* Set error for nested multi bulks with depth > 7 */
- if (r->ridx == 8) {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "No support for nested multi bulk replies with depth > 7");
- return REDIS_ERR;
- }
-
- if ((p = readLine(r,&len)) != NULL) {
- if (string2ll(p, len, &elements) == REDIS_ERR) {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "Bad multi-bulk length");
- return REDIS_ERR;
- }
-
- root = (r->ridx == 0);
-
- if (elements < -1 || (LLONG_MAX > SIZE_MAX && elements > SIZE_MAX)) {
- __redisReaderSetError(r,REDIS_ERR_PROTOCOL,
- "Multi-bulk length out of range");
- return REDIS_ERR;
- }
-
- if (elements == -1) {
- if (r->fn && r->fn->createNil)
- obj = r->fn->createNil(cur);
- else
- obj = (void*)REDIS_REPLY_NIL;
-
- if (obj == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- moveToNextTask(r);
- } else {
- if (cur->type == REDIS_REPLY_MAP) elements *= 2;
-
- if (r->fn && r->fn->createArray)
- obj = r->fn->createArray(cur,elements);
- else
- obj = (void*)(long)cur->type;
-
- if (obj == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- /* Modify task stack when there are more than 0 elements. */
- if (elements > 0) {
- cur->elements = elements;
- cur->obj = obj;
- r->ridx++;
- r->rstack[r->ridx].type = -1;
- r->rstack[r->ridx].elements = -1;
- r->rstack[r->ridx].idx = 0;
- r->rstack[r->ridx].obj = NULL;
- r->rstack[r->ridx].parent = cur;
- r->rstack[r->ridx].privdata = r->privdata;
- } else {
- moveToNextTask(r);
- }
- }
-
- /* Set reply if this is the root object. */
- if (root) r->reply = obj;
- return REDIS_OK;
- }
-
- return REDIS_ERR;
-}
-
-static int processItem(redisReader *r) {
- redisReadTask *cur = &(r->rstack[r->ridx]);
- char *p;
-
- /* check if we need to read type */
- if (cur->type < 0) {
- if ((p = readBytes(r,1)) != NULL) {
- switch (p[0]) {
- case '-':
- cur->type = REDIS_REPLY_ERROR;
- break;
- case '+':
- cur->type = REDIS_REPLY_STATUS;
- break;
- case ':':
- cur->type = REDIS_REPLY_INTEGER;
- break;
- case ',':
- cur->type = REDIS_REPLY_DOUBLE;
- break;
- case '_':
- cur->type = REDIS_REPLY_NIL;
- break;
- case '$':
- cur->type = REDIS_REPLY_STRING;
- break;
- case '*':
- cur->type = REDIS_REPLY_ARRAY;
- break;
- case '%':
- cur->type = REDIS_REPLY_MAP;
- break;
- case '~':
- cur->type = REDIS_REPLY_SET;
- break;
- case '#':
- cur->type = REDIS_REPLY_BOOL;
- break;
- case '=':
- cur->type = REDIS_REPLY_VERB;
- break;
- default:
- __redisReaderSetErrorProtocolByte(r,*p);
- return REDIS_ERR;
- }
- } else {
- /* could not consume 1 byte */
- return REDIS_ERR;
- }
- }
-
- /* process typed item */
- switch(cur->type) {
- case REDIS_REPLY_ERROR:
- case REDIS_REPLY_STATUS:
- case REDIS_REPLY_INTEGER:
- case REDIS_REPLY_DOUBLE:
- case REDIS_REPLY_NIL:
- case REDIS_REPLY_BOOL:
- return processLineItem(r);
- case REDIS_REPLY_STRING:
- case REDIS_REPLY_VERB:
- return processBulkItem(r);
- case REDIS_REPLY_ARRAY:
- case REDIS_REPLY_MAP:
- case REDIS_REPLY_SET:
- return processAggregateItem(r);
- default:
- assert(NULL);
- return REDIS_ERR; /* Avoid warning. */
- }
-}
-
-redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn) {
- redisReader *r;
-
- r = calloc(1,sizeof(redisReader));
- if (r == NULL)
- return NULL;
-
- r->fn = fn;
- r->buf = sdsempty();
- r->maxbuf = REDIS_READER_MAX_BUF;
- if (r->buf == NULL) {
- free(r);
- return NULL;
- }
-
- r->ridx = -1;
- return r;
-}
-
-void redisReaderFree(redisReader *r) {
- if (r == NULL)
- return;
- if (r->reply != NULL && r->fn && r->fn->freeObject)
- r->fn->freeObject(r->reply);
- sdsfree(r->buf);
- free(r);
-}
-
-int redisReaderFeed(redisReader *r, const char *buf, size_t len) {
- sds newbuf;
-
- /* Return early when this reader is in an erroneous state. */
- if (r->err)
- return REDIS_ERR;
-
- /* Copy the provided buffer. */
- if (buf != NULL && len >= 1) {
- /* Destroy internal buffer when it is empty and is quite large. */
- if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) {
- sdsfree(r->buf);
- r->buf = sdsempty();
- r->pos = 0;
-
- /* r->buf should not be NULL since we just free'd a larger one. */
- assert(r->buf != NULL);
- }
-
- newbuf = sdscatlen(r->buf,buf,len);
- if (newbuf == NULL) {
- __redisReaderSetErrorOOM(r);
- return REDIS_ERR;
- }
-
- r->buf = newbuf;
- r->len = sdslen(r->buf);
- }
-
- return REDIS_OK;
-}
-
-int redisReaderGetReply(redisReader *r, void **reply) {
- /* Default target pointer to NULL. */
- if (reply != NULL)
- *reply = NULL;
-
- /* Return early when this reader is in an erroneous state. */
- if (r->err)
- return REDIS_ERR;
-
- /* When the buffer is empty, there will never be a reply. */
- if (r->len == 0)
- return REDIS_OK;
-
- /* Set first item to process when the stack is empty. */
- if (r->ridx == -1) {
- r->rstack[0].type = -1;
- r->rstack[0].elements = -1;
- r->rstack[0].idx = -1;
- r->rstack[0].obj = NULL;
- r->rstack[0].parent = NULL;
- r->rstack[0].privdata = r->privdata;
- r->ridx = 0;
- }
-
- /* Process items in reply. */
- while (r->ridx >= 0)
- if (processItem(r) != REDIS_OK)
- break;
-
- /* Return ASAP when an error occurred. */
- if (r->err)
- return REDIS_ERR;
-
- /* Discard part of the buffer when we've consumed at least 1k, to avoid
- * doing unnecessary calls to memmove() in sds.c. */
- if (r->pos >= 1024) {
- sdsrange(r->buf,r->pos,-1);
- r->pos = 0;
- r->len = sdslen(r->buf);
- }
-
- /* Emit a reply when there is one. */
- if (r->ridx == -1) {
- if (reply != NULL) {
- *reply = r->reply;
- } else if (r->reply != NULL && r->fn && r->fn->freeObject) {
- r->fn->freeObject(r->reply);
- }
- r->reply = NULL;
- }
- return REDIS_OK;
-}
diff --git a/deps/hiredis/read.h b/deps/hiredis/read.h
deleted file mode 100644
index 58105312a..000000000
--- a/deps/hiredis/read.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef __HIREDIS_READ_H
-#define __HIREDIS_READ_H
-#include <stdio.h> /* for size_t */
-
-#define REDIS_ERR -1
-#define REDIS_OK 0
-
-/* When an error occurs, the err flag in a context is set to hold the type of
- * error that occurred. REDIS_ERR_IO means there was an I/O error and you
- * should use the "errno" variable to find out what is wrong.
- * For other values, the "errstr" field will hold a description. */
-#define REDIS_ERR_IO 1 /* Error in read or write */
-#define REDIS_ERR_EOF 3 /* End of file */
-#define REDIS_ERR_PROTOCOL 4 /* Protocol error */
-#define REDIS_ERR_OOM 5 /* Out of memory */
-#define REDIS_ERR_TIMEOUT 6 /* Timed out */
-#define REDIS_ERR_OTHER 2 /* Everything else... */
-
-#define REDIS_REPLY_STRING 1
-#define REDIS_REPLY_ARRAY 2
-#define REDIS_REPLY_INTEGER 3
-#define REDIS_REPLY_NIL 4
-#define REDIS_REPLY_STATUS 5
-#define REDIS_REPLY_ERROR 6
-#define REDIS_REPLY_DOUBLE 7
-#define REDIS_REPLY_BOOL 8
-#define REDIS_REPLY_MAP 9
-#define REDIS_REPLY_SET 10
-#define REDIS_REPLY_ATTR 11
-#define REDIS_REPLY_PUSH 12
-#define REDIS_REPLY_BIGNUM 13
-#define REDIS_REPLY_VERB 14
-
-#define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct redisReadTask {
- int type;
- int elements; /* number of elements in multibulk container */
- int idx; /* index in parent (array) object */
- void *obj; /* holds user-generated value for a read task */
- struct redisReadTask *parent; /* parent task */
- void *privdata; /* user-settable arbitrary field */
-} redisReadTask;
-
-typedef struct redisReplyObjectFunctions {
- void *(*createString)(const redisReadTask*, char*, size_t);
- void *(*createArray)(const redisReadTask*, size_t);
- void *(*createInteger)(const redisReadTask*, long long);
- void *(*createDouble)(const redisReadTask*, double, char*, size_t);
- void *(*createNil)(const redisReadTask*);
- void *(*createBool)(const redisReadTask*, int);
- void (*freeObject)(void*);
-} redisReplyObjectFunctions;
-
-typedef struct redisReader {
- int err; /* Error flags, 0 when there is no error */
- char errstr[128]; /* String representation of error when applicable */
-
- char *buf; /* Read buffer */
- size_t pos; /* Buffer cursor */
- size_t len; /* Buffer length */
- size_t maxbuf; /* Max length of unused buffer */
-
- redisReadTask rstack[9];
- int ridx; /* Index of current read task */
- void *reply; /* Temporary reply pointer */
-
- redisReplyObjectFunctions *fn;
- void *privdata;
-} redisReader;
-
-/* Public API for the protocol parser. */
-redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn);
-void redisReaderFree(redisReader *r);
-int redisReaderFeed(redisReader *r, const char *buf, size_t len);
-int redisReaderGetReply(redisReader *r, void **reply);
-
-#define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p))
-#define redisReaderGetObject(_r) (((redisReader*)(_r))->reply)
-#define redisReaderGetError(_r) (((redisReader*)(_r))->errstr)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/deps/hiredis/sds.c b/deps/hiredis/sds.c
deleted file mode 100644
index 6cf75841c..000000000
--- a/deps/hiredis/sds.c
+++ /dev/null
@@ -1,1291 +0,0 @@
-/* SDSLib 2.0 -- A C dynamic strings library
- *
- * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2015, Oran Agra
- * Copyright (c) 2015, Redis Labs, Inc
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-#include "sds.h"
-#include "sdsalloc.h"
-
-static inline int sdsHdrSize(char type) {
- switch(type&SDS_TYPE_MASK) {
- case SDS_TYPE_5:
- return sizeof(struct sdshdr5);
- case SDS_TYPE_8:
- return sizeof(struct sdshdr8);
- case SDS_TYPE_16:
- return sizeof(struct sdshdr16);
- case SDS_TYPE_32:
- return sizeof(struct sdshdr32);
- case SDS_TYPE_64:
- return sizeof(struct sdshdr64);
- }
- return 0;
-}
-
-static inline char sdsReqType(size_t string_size) {
- if (string_size < 32)
- return SDS_TYPE_5;
- if (string_size < 0xff)
- return SDS_TYPE_8;
- if (string_size < 0xffff)
- return SDS_TYPE_16;
- if (string_size < 0xffffffff)
- return SDS_TYPE_32;
- return SDS_TYPE_64;
-}
-
-/* Create a new sds string with the content specified by the 'init' pointer
- * and 'initlen'.
- * If NULL is used for 'init' the string is initialized with zero bytes.
- *
- * The string is always null-termined (all the sds strings are, always) so
- * even if you create an sds string with:
- *
- * mystring = sdsnewlen("abc",3);
- *
- * You can print the string with printf() as there is an implicit \0 at the
- * end of the string. However the string is binary safe and can contain
- * \0 characters in the middle, as the length is stored in the sds header. */
-sds sdsnewlen(const void *init, size_t initlen) {
- void *sh;
- sds s;
- char type = sdsReqType(initlen);
- /* Empty strings are usually created in order to append. Use type 8
- * since type 5 is not good at this. */
- if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8;
- int hdrlen = sdsHdrSize(type);
- unsigned char *fp; /* flags pointer. */
-
- sh = s_malloc(hdrlen+initlen+1);
- if (sh == NULL) return NULL;
- if (!init)
- memset(sh, 0, hdrlen+initlen+1);
- s = (char*)sh+hdrlen;
- fp = ((unsigned char*)s)-1;
- switch(type) {
- case SDS_TYPE_5: {
- *fp = type | (initlen << SDS_TYPE_BITS);
- break;
- }
- case SDS_TYPE_8: {
- SDS_HDR_VAR(8,s);
- sh->len = initlen;
- sh->alloc = initlen;
- *fp = type;
- break;
- }
- case SDS_TYPE_16: {
- SDS_HDR_VAR(16,s);
- sh->len = initlen;
- sh->alloc = initlen;
- *fp = type;
- break;
- }
- case SDS_TYPE_32: {
- SDS_HDR_VAR(32,s);
- sh->len = initlen;
- sh->alloc = initlen;
- *fp = type;
- break;
- }
- case SDS_TYPE_64: {
- SDS_HDR_VAR(64,s);
- sh->len = initlen;
- sh->alloc = initlen;
- *fp = type;
- break;
- }
- }
- if (initlen && init)
- memcpy(s, init, initlen);
- s[initlen] = '\0';
- return s;
-}
-
-/* Create an empty (zero length) sds string. Even in this case the string
- * always has an implicit null term. */
-sds sdsempty(void) {
- return sdsnewlen("",0);
-}
-
-/* Create a new sds string starting from a null terminated C string. */
-sds sdsnew(const char *init) {
- size_t initlen = (init == NULL) ? 0 : strlen(init);
- return sdsnewlen(init, initlen);
-}
-
-/* Duplicate an sds string. */
-sds sdsdup(const sds s) {
- return sdsnewlen(s, sdslen(s));
-}
-
-/* Free an sds string. No operation is performed if 's' is NULL. */
-void sdsfree(sds s) {
- if (s == NULL) return;
- s_free((char*)s-sdsHdrSize(s[-1]));
-}
-
-/* Set the sds string length to the length as obtained with strlen(), so
- * considering as content only up to the first null term character.
- *
- * This function is useful when the sds string is hacked manually in some
- * way, like in the following example:
- *
- * s = sdsnew("foobar");
- * s[2] = '\0';
- * sdsupdatelen(s);
- * printf("%d\n", sdslen(s));
- *
- * The output will be "2", but if we comment out the call to sdsupdatelen()
- * the output will be "6" as the string was modified but the logical length
- * remains 6 bytes. */
-void sdsupdatelen(sds s) {
- int reallen = strlen(s);
- sdssetlen(s, reallen);
-}
-
-/* Modify an sds string in-place to make it empty (zero length).
- * However all the existing buffer is not discarded but set as free space
- * so that next append operations will not require allocations up to the
- * number of bytes previously available. */
-void sdsclear(sds s) {
- sdssetlen(s, 0);
- s[0] = '\0';
-}
-
-/* Enlarge the free space at the end of the sds string so that the caller
- * is sure that after calling this function can overwrite up to addlen
- * bytes after the end of the string, plus one more byte for nul term.
- *
- * Note: this does not change the *length* of the sds string as returned
- * by sdslen(), but only the free buffer space we have. */
-sds sdsMakeRoomFor(sds s, size_t addlen) {
- void *sh, *newsh;
- size_t avail = sdsavail(s);
- size_t len, newlen;
- char type, oldtype = s[-1] & SDS_TYPE_MASK;
- int hdrlen;
-
- /* Return ASAP if there is enough space left. */
- if (avail >= addlen) return s;
-
- len = sdslen(s);
- sh = (char*)s-sdsHdrSize(oldtype);
- newlen = (len+addlen);
- if (newlen < SDS_MAX_PREALLOC)
- newlen *= 2;
- else
- newlen += SDS_MAX_PREALLOC;
-
- type = sdsReqType(newlen);
-
- /* Don't use type 5: the user is appending to the string and type 5 is
- * not able to remember empty space, so sdsMakeRoomFor() must be called
- * at every appending operation. */
- if (type == SDS_TYPE_5) type = SDS_TYPE_8;
-
- hdrlen = sdsHdrSize(type);
- if (oldtype==type) {
- newsh = s_realloc(sh, hdrlen+newlen+1);
- if (newsh == NULL) {
- s_free(sh);
- return NULL;
- }
- s = (char*)newsh+hdrlen;
- } else {
- /* Since the header size changes, need to move the string forward,
- * and can't use realloc */
- newsh = s_malloc(hdrlen+newlen+1);
- if (newsh == NULL) return NULL;
- memcpy((char*)newsh+hdrlen, s, len+1);
- s_free(sh);
- s = (char*)newsh+hdrlen;
- s[-1] = type;
- sdssetlen(s, len);
- }
- sdssetalloc(s, newlen);
- return s;
-}
-
-/* Reallocate the sds string so that it has no free space at the end. The
- * contained string remains not altered, but next concatenation operations
- * will require a reallocation.
- *
- * After the call, the passed sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdsRemoveFreeSpace(sds s) {
- void *sh, *newsh;
- char type, oldtype = s[-1] & SDS_TYPE_MASK;
- int hdrlen;
- size_t len = sdslen(s);
- sh = (char*)s-sdsHdrSize(oldtype);
-
- type = sdsReqType(len);
- hdrlen = sdsHdrSize(type);
- if (oldtype==type) {
- newsh = s_realloc(sh, hdrlen+len+1);
- if (newsh == NULL) return NULL;
- s = (char*)newsh+hdrlen;
- } else {
- newsh = s_malloc(hdrlen+len+1);
- if (newsh == NULL) return NULL;
- memcpy((char*)newsh+hdrlen, s, len+1);
- s_free(sh);
- s = (char*)newsh+hdrlen;
- s[-1] = type;
- sdssetlen(s, len);
- }
- sdssetalloc(s, len);
- return s;
-}
-
-/* Return the total size of the allocation of the specifed sds string,
- * including:
- * 1) The sds header before the pointer.
- * 2) The string.
- * 3) The free buffer at the end if any.
- * 4) The implicit null term.
- */
-size_t sdsAllocSize(sds s) {
- size_t alloc = sdsalloc(s);
- return sdsHdrSize(s[-1])+alloc+1;
-}
-
-/* Return the pointer of the actual SDS allocation (normally SDS strings
- * are referenced by the start of the string buffer). */
-void *sdsAllocPtr(sds s) {
- return (void*) (s-sdsHdrSize(s[-1]));
-}
-
-/* Increment the sds length and decrements the left free space at the
- * end of the string according to 'incr'. Also set the null term
- * in the new end of the string.
- *
- * This function is used in order to fix the string length after the
- * user calls sdsMakeRoomFor(), writes something after the end of
- * the current string, and finally needs to set the new length.
- *
- * Note: it is possible to use a negative increment in order to
- * right-trim the string.
- *
- * Usage example:
- *
- * Using sdsIncrLen() and sdsMakeRoomFor() it is possible to mount the
- * following schema, to cat bytes coming from the kernel to the end of an
- * sds string without copying into an intermediate buffer:
- *
- * oldlen = sdslen(s);
- * s = sdsMakeRoomFor(s, BUFFER_SIZE);
- * nread = read(fd, s+oldlen, BUFFER_SIZE);
- * ... check for nread <= 0 and handle it ...
- * sdsIncrLen(s, nread);
- */
-void sdsIncrLen(sds s, int incr) {
- unsigned char flags = s[-1];
- size_t len;
- switch(flags&SDS_TYPE_MASK) {
- case SDS_TYPE_5: {
- unsigned char *fp = ((unsigned char*)s)-1;
- unsigned char oldlen = SDS_TYPE_5_LEN(flags);
- assert((incr > 0 && oldlen+incr < 32) || (incr < 0 && oldlen >= (unsigned int)(-incr)));
- *fp = SDS_TYPE_5 | ((oldlen+incr) << SDS_TYPE_BITS);
- len = oldlen+incr;
- break;
- }
- case SDS_TYPE_8: {
- SDS_HDR_VAR(8,s);
- assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
- len = (sh->len += incr);
- break;
- }
- case SDS_TYPE_16: {
- SDS_HDR_VAR(16,s);
- assert((incr >= 0 && sh->alloc-sh->len >= incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
- len = (sh->len += incr);
- break;
- }
- case SDS_TYPE_32: {
- SDS_HDR_VAR(32,s);
- assert((incr >= 0 && sh->alloc-sh->len >= (unsigned int)incr) || (incr < 0 && sh->len >= (unsigned int)(-incr)));
- len = (sh->len += incr);
- break;
- }
- case SDS_TYPE_64: {
- SDS_HDR_VAR(64,s);
- assert((incr >= 0 && sh->alloc-sh->len >= (uint64_t)incr) || (incr < 0 && sh->len >= (uint64_t)(-incr)));
- len = (sh->len += incr);
- break;
- }
- default: len = 0; /* Just to avoid compilation warnings. */
- }
- s[len] = '\0';
-}
-
-/* Grow the sds to have the specified length. Bytes that were not part of
- * the original length of the sds will be set to zero.
- *
- * if the specified length is smaller than the current length, no operation
- * is performed. */
-sds sdsgrowzero(sds s, size_t len) {
- size_t curlen = sdslen(s);
-
- if (len <= curlen) return s;
- s = sdsMakeRoomFor(s,len-curlen);
- if (s == NULL) return NULL;
-
- /* Make sure added region doesn't contain garbage */
- memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */
- sdssetlen(s, len);
- return s;
-}
-
-/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the
- * end of the specified sds string 's'.
- *
- * After the call, the passed sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscatlen(sds s, const void *t, size_t len) {
- size_t curlen = sdslen(s);
-
- s = sdsMakeRoomFor(s,len);
- if (s == NULL) return NULL;
- memcpy(s+curlen, t, len);
- sdssetlen(s, curlen+len);
- s[curlen+len] = '\0';
- return s;
-}
-
-/* Append the specified null termianted C string to the sds string 's'.
- *
- * After the call, the passed sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscat(sds s, const char *t) {
- return sdscatlen(s, t, strlen(t));
-}
-
-/* Append the specified sds 't' to the existing sds 's'.
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscatsds(sds s, const sds t) {
- return sdscatlen(s, t, sdslen(t));
-}
-
-/* Destructively modify the sds string 's' to hold the specified binary
- * safe string pointed by 't' of length 'len' bytes. */
-sds sdscpylen(sds s, const char *t, size_t len) {
- if (sdsalloc(s) < len) {
- s = sdsMakeRoomFor(s,len-sdslen(s));
- if (s == NULL) return NULL;
- }
- memcpy(s, t, len);
- s[len] = '\0';
- sdssetlen(s, len);
- return s;
-}
-
-/* Like sdscpylen() but 't' must be a null-termined string so that the length
- * of the string is obtained with strlen(). */
-sds sdscpy(sds s, const char *t) {
- return sdscpylen(s, t, strlen(t));
-}
-
-/* Helper for sdscatlonglong() doing the actual number -> string
- * conversion. 's' must point to a string with room for at least
- * SDS_LLSTR_SIZE bytes.
- *
- * The function returns the length of the null-terminated string
- * representation stored at 's'. */
-#define SDS_LLSTR_SIZE 21
-int sdsll2str(char *s, long long value) {
- char *p, aux;
- unsigned long long v;
- size_t l;
-
- /* Generate the string representation, this method produces
- * an reversed string. */
- v = (value < 0) ? -value : value;
- p = s;
- do {
- *p++ = '0'+(v%10);
- v /= 10;
- } while(v);
- if (value < 0) *p++ = '-';
-
- /* Compute length and add null term. */
- l = p-s;
- *p = '\0';
-
- /* Reverse the string. */
- p--;
- while(s < p) {
- aux = *s;
- *s = *p;
- *p = aux;
- s++;
- p--;
- }
- return l;
-}
-
-/* Identical sdsll2str(), but for unsigned long long type. */
-int sdsull2str(char *s, unsigned long long v) {
- char *p, aux;
- size_t l;
-
- /* Generate the string representation, this method produces
- * an reversed string. */
- p = s;
- do {
- *p++ = '0'+(v%10);
- v /= 10;
- } while(v);
-
- /* Compute length and add null term. */
- l = p-s;
- *p = '\0';
-
- /* Reverse the string. */
- p--;
- while(s < p) {
- aux = *s;
- *s = *p;
- *p = aux;
- s++;
- p--;
- }
- return l;
-}
-
-/* Create an sds string from a long long value. It is much faster than:
- *
- * sdscatprintf(sdsempty(),"%lld\n", value);
- */
-sds sdsfromlonglong(long long value) {
- char buf[SDS_LLSTR_SIZE];
- int len = sdsll2str(buf,value);
-
- return sdsnewlen(buf,len);
-}
-
-/* Like sdscatprintf() but gets va_list instead of being variadic. */
-sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
- va_list cpy;
- char staticbuf[1024], *buf = staticbuf, *t;
- size_t buflen = strlen(fmt)*2;
-
- /* We try to start using a static buffer for speed.
- * If not possible we revert to heap allocation. */
- if (buflen > sizeof(staticbuf)) {
- buf = s_malloc(buflen);
- if (buf == NULL) return NULL;
- } else {
- buflen = sizeof(staticbuf);
- }
-
- /* Try with buffers two times bigger every time we fail to
- * fit the string in the current buffer size. */
- while(1) {
- buf[buflen-2] = '\0';
- va_copy(cpy,ap);
- vsnprintf(buf, buflen, fmt, cpy);
- va_end(cpy);
- if (buf[buflen-2] != '\0') {
- if (buf != staticbuf) s_free(buf);
- buflen *= 2;
- buf = s_malloc(buflen);
- if (buf == NULL) return NULL;
- continue;
- }
- break;
- }
-
- /* Finally concat the obtained string to the SDS string and return it. */
- t = sdscat(s, buf);
- if (buf != staticbuf) s_free(buf);
- return t;
-}
-
-/* Append to the sds string 's' a string obtained using printf-alike format
- * specifier.
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call.
- *
- * Example:
- *
- * s = sdsnew("Sum is: ");
- * s = sdscatprintf(s,"%d+%d = %d",a,b,a+b).
- *
- * Often you need to create a string from scratch with the printf-alike
- * format. When this is the need, just use sdsempty() as the target string:
- *
- * s = sdscatprintf(sdsempty(), "... your format ...", args);
- */
-sds sdscatprintf(sds s, const char *fmt, ...) {
- va_list ap;
- char *t;
- va_start(ap, fmt);
- t = sdscatvprintf(s,fmt,ap);
- va_end(ap);
- return t;
-}
-
-/* This function is similar to sdscatprintf, but much faster as it does
- * not rely on sprintf() family functions implemented by the libc that
- * are often very slow. Moreover directly handling the sds string as
- * new data is concatenated provides a performance improvement.
- *
- * However this function only handles an incompatible subset of printf-alike
- * format specifiers:
- *
- * %s - C String
- * %S - SDS string
- * %i - signed int
- * %I - 64 bit signed integer (long long, int64_t)
- * %u - unsigned int
- * %U - 64 bit unsigned integer (unsigned long long, uint64_t)
- * %% - Verbatim "%" character.
- */
-sds sdscatfmt(sds s, char const *fmt, ...) {
- const char *f = fmt;
- int i;
- va_list ap;
-
- va_start(ap,fmt);
- i = sdslen(s); /* Position of the next byte to write to dest str. */
- while(*f) {
- char next, *str;
- size_t l;
- long long num;
- unsigned long long unum;
-
- /* Make sure there is always space for at least 1 char. */
- if (sdsavail(s)==0) {
- s = sdsMakeRoomFor(s,1);
- if (s == NULL) goto fmt_error;
- }
-
- switch(*f) {
- case '%':
- next = *(f+1);
- f++;
- switch(next) {
- case 's':
- case 'S':
- str = va_arg(ap,char*);
- l = (next == 's') ? strlen(str) : sdslen(str);
- if (sdsavail(s) < l) {
- s = sdsMakeRoomFor(s,l);
- if (s == NULL) goto fmt_error;
- }
- memcpy(s+i,str,l);
- sdsinclen(s,l);
- i += l;
- break;
- case 'i':
- case 'I':
- if (next == 'i')
- num = va_arg(ap,int);
- else
- num = va_arg(ap,long long);
- {
- char buf[SDS_LLSTR_SIZE];
- l = sdsll2str(buf,num);
- if (sdsavail(s) < l) {
- s = sdsMakeRoomFor(s,l);
- if (s == NULL) goto fmt_error;
- }
- memcpy(s+i,buf,l);
- sdsinclen(s,l);
- i += l;
- }
- break;
- case 'u':
- case 'U':
- if (next == 'u')
- unum = va_arg(ap,unsigned int);
- else
- unum = va_arg(ap,unsigned long long);
- {
- char buf[SDS_LLSTR_SIZE];
- l = sdsull2str(buf,unum);
- if (sdsavail(s) < l) {
- s = sdsMakeRoomFor(s,l);
- if (s == NULL) goto fmt_error;
- }
- memcpy(s+i,buf,l);
- sdsinclen(s,l);
- i += l;
- }
- break;
- default: /* Handle %% and generally %<unknown>. */
- s[i++] = next;
- sdsinclen(s,1);
- break;
- }
- break;
- default:
- s[i++] = *f;
- sdsinclen(s,1);
- break;
- }
- f++;
- }
- va_end(ap);
-
- /* Add null-term */
- s[i] = '\0';
- return s;
-
-fmt_error:
- va_end(ap);
- return NULL;
-}
-
-/* Remove the part of the string from left and from right composed just of
- * contiguous characters found in 'cset', that is a null terminted C string.
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call.
- *
- * Example:
- *
- * s = sdsnew("AA...AA.a.aa.aHelloWorld :::");
- * s = sdstrim(s,"Aa. :");
- * printf("%s\n", s);
- *
- * Output will be just "Hello World".
- */
-sds sdstrim(sds s, const char *cset) {
- char *start, *end, *sp, *ep;
- size_t len;
-
- sp = start = s;
- ep = end = s+sdslen(s)-1;
- while(sp <= end && strchr(cset, *sp)) sp++;
- while(ep > sp && strchr(cset, *ep)) ep--;
- len = (sp > ep) ? 0 : ((ep-sp)+1);
- if (s != sp) memmove(s, sp, len);
- s[len] = '\0';
- sdssetlen(s,len);
- return s;
-}
-
-/* Turn the string into a smaller (or equal) string containing only the
- * substring specified by the 'start' and 'end' indexes.
- *
- * start and end can be negative, where -1 means the last character of the
- * string, -2 the penultimate character, and so forth.
- *
- * The interval is inclusive, so the start and end characters will be part
- * of the resulting string.
- *
- * The string is modified in-place.
- *
- * Example:
- *
- * s = sdsnew("Hello World");
- * sdsrange(s,1,-1); => "ello World"
- */
-void sdsrange(sds s, int start, int end) {
- size_t newlen, len = sdslen(s);
-
- if (len == 0) return;
- if (start < 0) {
- start = len+start;
- if (start < 0) start = 0;
- }
- if (end < 0) {
- end = len+end;
- if (end < 0) end = 0;
- }
- newlen = (start > end) ? 0 : (end-start)+1;
- if (newlen != 0) {
- if (start >= (signed)len) {
- newlen = 0;
- } else if (end >= (signed)len) {
- end = len-1;
- newlen = (start > end) ? 0 : (end-start)+1;
- }
- } else {
- start = 0;
- }
- if (start && newlen) memmove(s, s+start, newlen);
- s[newlen] = 0;
- sdssetlen(s,newlen);
-}
-
-/* Apply tolower() to every character of the sds string 's'. */
-void sdstolower(sds s) {
- int len = sdslen(s), j;
-
- for (j = 0; j < len; j++) s[j] = tolower(s[j]);
-}
-
-/* Apply toupper() to every character of the sds string 's'. */
-void sdstoupper(sds s) {
- int len = sdslen(s), j;
-
- for (j = 0; j < len; j++) s[j] = toupper(s[j]);
-}
-
-/* Compare two sds strings s1 and s2 with memcmp().
- *
- * Return value:
- *
- * positive if s1 > s2.
- * negative if s1 < s2.
- * 0 if s1 and s2 are exactly the same binary string.
- *
- * If two strings share exactly the same prefix, but one of the two has
- * additional characters, the longer string is considered to be greater than
- * the smaller one. */
-int sdscmp(const sds s1, const sds s2) {
- size_t l1, l2, minlen;
- int cmp;
-
- l1 = sdslen(s1);
- l2 = sdslen(s2);
- minlen = (l1 < l2) ? l1 : l2;
- cmp = memcmp(s1,s2,minlen);
- if (cmp == 0) return l1-l2;
- return cmp;
-}
-
-/* Split 's' with separator in 'sep'. An array
- * of sds strings is returned. *count will be set
- * by reference to the number of tokens returned.
- *
- * On out of memory, zero length string, zero length
- * separator, NULL is returned.
- *
- * Note that 'sep' is able to split a string using
- * a multi-character separator. For example
- * sdssplit("foo_-_bar","_-_"); will return two
- * elements "foo" and "bar".
- *
- * This version of the function is binary-safe but
- * requires length arguments. sdssplit() is just the
- * same function but for zero-terminated strings.
- */
-sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count) {
- int elements = 0, slots = 5, start = 0, j;
- sds *tokens;
-
- if (seplen < 1 || len < 0) return NULL;
-
- tokens = s_malloc(sizeof(sds)*slots);
- if (tokens == NULL) return NULL;
-
- if (len == 0) {
- *count = 0;
- return tokens;
- }
- for (j = 0; j < (len-(seplen-1)); j++) {
- /* make sure there is room for the next element and the final one */
- if (slots < elements+2) {
- sds *newtokens;
-
- slots *= 2;
- newtokens = s_realloc(tokens,sizeof(sds)*slots);
- if (newtokens == NULL) goto cleanup;
- tokens = newtokens;
- }
- /* search the separator */
- if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
- tokens[elements] = sdsnewlen(s+start,j-start);
- if (tokens[elements] == NULL) goto cleanup;
- elements++;
- start = j+seplen;
- j = j+seplen-1; /* skip the separator */
- }
- }
- /* Add the final element. We are sure there is room in the tokens array. */
- tokens[elements] = sdsnewlen(s+start,len-start);
- if (tokens[elements] == NULL) goto cleanup;
- elements++;
- *count = elements;
- return tokens;
-
-cleanup:
- {
- int i;
- for (i = 0; i < elements; i++) sdsfree(tokens[i]);
- s_free(tokens);
- *count = 0;
- return NULL;
- }
-}
-
-/* Free the result returned by sdssplitlen(), or do nothing if 'tokens' is NULL. */
-void sdsfreesplitres(sds *tokens, int count) {
- if (!tokens) return;
- while(count--)
- sdsfree(tokens[count]);
- s_free(tokens);
-}
-
-/* Append to the sds string "s" an escaped string representation where
- * all the non-printable characters (tested with isprint()) are turned into
- * escapes in the form "\n\r\a...." or "\x<hex-number>".
- *
- * After the call, the modified sds string is no longer valid and all the
- * references must be substituted with the new pointer returned by the call. */
-sds sdscatrepr(sds s, const char *p, size_t len) {
- s = sdscatlen(s,"\"",1);
- while(len--) {
- switch(*p) {
- case '\\':
- case '"':
- s = sdscatprintf(s,"\\%c",*p);
- break;
- case '\n': s = sdscatlen(s,"\\n",2); break;
- case '\r': s = sdscatlen(s,"\\r",2); break;
- case '\t': s = sdscatlen(s,"\\t",2); break;
- case '\a': s = sdscatlen(s,"\\a",2); break;
- case '\b': s = sdscatlen(s,"\\b",2); break;
- default:
- if (isprint(*p))
- s = sdscatprintf(s,"%c",*p);
- else
- s = sdscatprintf(s,"\\x%02x",(unsigned char)*p);
- break;
- }
- p++;
- }
- return sdscatlen(s,"\"",1);
-}
-
-/* Helper function for sdssplitargs() that returns non zero if 'c'
- * is a valid hex digit. */
-int is_hex_digit(char c) {
- return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
- (c >= 'A' && c <= 'F');
-}
-
-/* Helper function for sdssplitargs() that converts a hex digit into an
- * integer from 0 to 15 */
-int hex_digit_to_int(char c) {
- switch(c) {
- case '0': return 0;
- case '1': return 1;
- case '2': return 2;
- case '3': return 3;
- case '4': return 4;
- case '5': return 5;
- case '6': return 6;
- case '7': return 7;
- case '8': return 8;
- case '9': return 9;
- case 'a': case 'A': return 10;
- case 'b': case 'B': return 11;
- case 'c': case 'C': return 12;
- case 'd': case 'D': return 13;
- case 'e': case 'E': return 14;
- case 'f': case 'F': return 15;
- default: return 0;
- }
-}
-
-/* Split a line into arguments, where every argument can be in the
- * following programming-language REPL-alike form:
- *
- * foo bar "newline are supported\n" and "\xff\x00otherstuff"
- *
- * The number of arguments is stored into *argc, and an array
- * of sds is returned.
- *
- * The caller should free the resulting array of sds strings with
- * sdsfreesplitres().
- *
- * Note that sdscatrepr() is able to convert back a string into
- * a quoted string in the same format sdssplitargs() is able to parse.
- *
- * The function returns the allocated tokens on success, even when the
- * input string is empty, or NULL if the input contains unbalanced
- * quotes or closed quotes followed by non space characters
- * as in: "foo"bar or "foo'
- */
-sds *sdssplitargs(const char *line, int *argc) {
- const char *p = line;
- char *current = NULL;
- char **vector = NULL;
-
- *argc = 0;
- while(1) {
- /* skip blanks */
- while(*p && isspace(*p)) p++;
- if (*p) {
- /* get a token */
- int inq=0; /* set to 1 if we are in "quotes" */
- int insq=0; /* set to 1 if we are in 'single quotes' */
- int done=0;
-
- if (current == NULL) current = sdsempty();
- while(!done) {
- if (inq) {
- if (*p == '\\' && *(p+1) == 'x' &&
- is_hex_digit(*(p+2)) &&
- is_hex_digit(*(p+3)))
- {
- unsigned char byte;
-
- byte = (hex_digit_to_int(*(p+2))*16)+
- hex_digit_to_int(*(p+3));
- current = sdscatlen(current,(char*)&byte,1);
- p += 3;
- } else if (*p == '\\' && *(p+1)) {
- char c;
-
- p++;
- switch(*p) {
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'b': c = '\b'; break;
- case 'a': c = '\a'; break;
- default: c = *p; break;
- }
- current = sdscatlen(current,&c,1);
- } else if (*p == '"') {
- /* closing quote must be followed by a space or
- * nothing at all. */
- if (*(p+1) && !isspace(*(p+1))) goto err;
- done=1;
- } else if (!*p) {
- /* unterminated quotes */
- goto err;
- } else {
- current = sdscatlen(current,p,1);
- }
- } else if (insq) {
- if (*p == '\\' && *(p+1) == '\'') {
- p++;
- current = sdscatlen(current,"'",1);
- } else if (*p == '\'') {
- /* closing quote must be followed by a space or
- * nothing at all. */
- if (*(p+1) && !isspace(*(p+1))) goto err;
- done=1;
- } else if (!*p) {
- /* unterminated quotes */
- goto err;
- } else {
- current = sdscatlen(current,p,1);
- }
- } else {
- switch(*p) {
- case ' ':
- case '\n':
- case '\r':
- case '\t':
- case '\0':
- done=1;
- break;
- case '"':
- inq=1;
- break;
- case '\'':
- insq=1;
- break;
- default:
- current = sdscatlen(current,p,1);
- break;
- }
- }
- if (*p) p++;
- }
- /* add the token to the vector */
- {
- char **new_vector = s_realloc(vector,((*argc)+1)*sizeof(char*));
- if (new_vector == NULL) {
- s_free(vector);
- return NULL;
- }
-
- vector = new_vector;
- vector[*argc] = current;
- (*argc)++;
- current = NULL;
- }
- } else {
- /* Even on empty input string return something not NULL. */
- if (vector == NULL) vector = s_malloc(sizeof(void*));
- return vector;
- }
- }
-
-err:
- while((*argc)--)
- sdsfree(vector[*argc]);
- s_free(vector);
- if (current) sdsfree(current);
- *argc = 0;
- return NULL;
-}
-
-/* Modify the string substituting all the occurrences of the set of
- * characters specified in the 'from' string to the corresponding character
- * in the 'to' array.
- *
- * For instance: sdsmapchars(mystring, "ho", "01", 2)
- * will have the effect of turning the string "hello" into "0ell1".
- *
- * The function returns the sds string pointer, that is always the same
- * as the input pointer since no resize is needed. */
-sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) {
- size_t j, i, l = sdslen(s);
-
- for (j = 0; j < l; j++) {
- for (i = 0; i < setlen; i++) {
- if (s[j] == from[i]) {
- s[j] = to[i];
- break;
- }
- }
- }
- return s;
-}
-
-/* Join an array of C strings using the specified separator (also a C string).
- * Returns the result as an sds string. */
-sds sdsjoin(char **argv, int argc, char *sep) {
- sds join = sdsempty();
- int j;
-
- for (j = 0; j < argc; j++) {
- join = sdscat(join, argv[j]);
- if (j != argc-1) join = sdscat(join,sep);
- }
- return join;
-}
-
-/* Like sdsjoin, but joins an array of SDS strings. */
-sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen) {
- sds join = sdsempty();
- int j;
-
- for (j = 0; j < argc; j++) {
- join = sdscatsds(join, argv[j]);
- if (j != argc-1) join = sdscatlen(join,sep,seplen);
- }
- return join;
-}
-
-/* Wrappers to the allocators used by SDS. Note that SDS will actually
- * just use the macros defined into sdsalloc.h in order to avoid to pay
- * the overhead of function calls. Here we define these wrappers only for
- * the programs SDS is linked to, if they want to touch the SDS internals
- * even if they use a different allocator. */
-void *sds_malloc(size_t size) { return s_malloc(size); }
-void *sds_realloc(void *ptr, size_t size) { return s_realloc(ptr,size); }
-void sds_free(void *ptr) { s_free(ptr); }
-
-#if defined(SDS_TEST_MAIN)
-#include <stdio.h>
-#include "testhelp.h"
-#include "limits.h"
-
-#define UNUSED(x) (void)(x)
-int sdsTest(void) {
- {
- sds x = sdsnew("foo"), y;
-
- test_cond("Create a string and obtain the length",
- sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)
-
- sdsfree(x);
- x = sdsnewlen("foo",2);
- test_cond("Create a string with specified length",
- sdslen(x) == 2 && memcmp(x,"fo\0",3) == 0)
-
- x = sdscat(x,"bar");
- test_cond("Strings concatenation",
- sdslen(x) == 5 && memcmp(x,"fobar\0",6) == 0);
-
- x = sdscpy(x,"a");
- test_cond("sdscpy() against an originally longer string",
- sdslen(x) == 1 && memcmp(x,"a\0",2) == 0)
-
- x = sdscpy(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk");
- test_cond("sdscpy() against an originally shorter string",
- sdslen(x) == 33 &&
- memcmp(x,"xyzxxxxxxxxxxyyyyyyyyyykkkkkkkkkk\0",33) == 0)
-
- sdsfree(x);
- x = sdscatprintf(sdsempty(),"%d",123);
- test_cond("sdscatprintf() seems working in the base case",
- sdslen(x) == 3 && memcmp(x,"123\0",4) == 0)
-
- sdsfree(x);
- x = sdsnew("--");
- x = sdscatfmt(x, "Hello %s World %I,%I--", "Hi!", LLONG_MIN,LLONG_MAX);
- test_cond("sdscatfmt() seems working in the base case",
- sdslen(x) == 60 &&
- memcmp(x,"--Hello Hi! World -9223372036854775808,"
- "9223372036854775807--",60) == 0)
- printf("[%s]\n",x);
-
- sdsfree(x);
- x = sdsnew("--");
- x = sdscatfmt(x, "%u,%U--", UINT_MAX, ULLONG_MAX);
- test_cond("sdscatfmt() seems working with unsigned numbers",
- sdslen(x) == 35 &&
- memcmp(x,"--4294967295,18446744073709551615--",35) == 0)
-
- sdsfree(x);
- x = sdsnew(" x ");
- sdstrim(x," x");
- test_cond("sdstrim() works when all chars match",
- sdslen(x) == 0)
-
- sdsfree(x);
- x = sdsnew(" x ");
- sdstrim(x," ");
- test_cond("sdstrim() works when a single char remains",
- sdslen(x) == 1 && x[0] == 'x')
-
- sdsfree(x);
- x = sdsnew("xxciaoyyy");
- sdstrim(x,"xy");
- test_cond("sdstrim() correctly trims characters",
- sdslen(x) == 4 && memcmp(x,"ciao\0",5) == 0)
-
- y = sdsdup(x);
- sdsrange(y,1,1);
- test_cond("sdsrange(...,1,1)",
- sdslen(y) == 1 && memcmp(y,"i\0",2) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,1,-1);
- test_cond("sdsrange(...,1,-1)",
- sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,-2,-1);
- test_cond("sdsrange(...,-2,-1)",
- sdslen(y) == 2 && memcmp(y,"ao\0",3) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,2,1);
- test_cond("sdsrange(...,2,1)",
- sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,1,100);
- test_cond("sdsrange(...,1,100)",
- sdslen(y) == 3 && memcmp(y,"iao\0",4) == 0)
-
- sdsfree(y);
- y = sdsdup(x);
- sdsrange(y,100,100);
- test_cond("sdsrange(...,100,100)",
- sdslen(y) == 0 && memcmp(y,"\0",1) == 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnew("foo");
- y = sdsnew("foa");
- test_cond("sdscmp(foo,foa)", sdscmp(x,y) > 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnew("bar");
- y = sdsnew("bar");
- test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnew("aar");
- y = sdsnew("bar");
- test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
-
- sdsfree(y);
- sdsfree(x);
- x = sdsnewlen("\a\n\0foo\r",7);
- y = sdscatrepr(sdsempty(),x,sdslen(x));
- test_cond("sdscatrepr(...data...)",
- memcmp(y,"\"\\a\\n\\x00foo\\r\"",15) == 0)
-
- {
- unsigned int oldfree;
- char *p;
- int step = 10, j, i;
-
- sdsfree(x);
- sdsfree(y);
- x = sdsnew("0");
- test_cond("sdsnew() free/len buffers", sdslen(x) == 1 && sdsavail(x) == 0);
-
- /* Run the test a few times in order to hit the first two
- * SDS header types. */
- for (i = 0; i < 10; i++) {
- int oldlen = sdslen(x);
- x = sdsMakeRoomFor(x,step);
- int type = x[-1]&SDS_TYPE_MASK;
-
- test_cond("sdsMakeRoomFor() len", sdslen(x) == oldlen);
- if (type != SDS_TYPE_5) {
- test_cond("sdsMakeRoomFor() free", sdsavail(x) >= step);
- oldfree = sdsavail(x);
- }
- p = x+oldlen;
- for (j = 0; j < step; j++) {
- p[j] = 'A'+j;
- }
- sdsIncrLen(x,step);
- }
- test_cond("sdsMakeRoomFor() content",
- memcmp("0ABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJABCDEFGHIJ",x,101) == 0);
- test_cond("sdsMakeRoomFor() final length",sdslen(x)==101);
-
- sdsfree(x);
- }
- }
- test_report()
- return 0;
-}
-#endif
-
-#ifdef SDS_TEST_MAIN
-int main(void) {
- return sdsTest();
-}
-#endif
diff --git a/deps/hiredis/sds.h b/deps/hiredis/sds.h
deleted file mode 100644
index 3f9a96457..000000000
--- a/deps/hiredis/sds.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* SDSLib 2.0 -- A C dynamic strings library
- *
- * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2015, Oran Agra
- * Copyright (c) 2015, Redis Labs, Inc
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __SDS_H
-#define __SDS_H
-
-#define SDS_MAX_PREALLOC (1024*1024)
-#ifdef _MSC_VER
-#define __attribute__(x)
-#endif
-
-#include <sys/types.h>
-#include <stdarg.h>
-#include <stdint.h>
-
-typedef char *sds;
-
-/* Note: sdshdr5 is never used, we just access the flags byte directly.
- * However is here to document the layout of type 5 SDS strings. */
-struct __attribute__ ((__packed__)) sdshdr5 {
- unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
- char buf[];
-};
-struct __attribute__ ((__packed__)) sdshdr8 {
- uint8_t len; /* used */
- uint8_t alloc; /* excluding the header and null terminator */
- unsigned char flags; /* 3 lsb of type, 5 unused bits */
- char buf[];
-};
-struct __attribute__ ((__packed__)) sdshdr16 {
- uint16_t len; /* used */
- uint16_t alloc; /* excluding the header and null terminator */
- unsigned char flags; /* 3 lsb of type, 5 unused bits */
- char buf[];
-};
-struct __attribute__ ((__packed__)) sdshdr32 {
- uint32_t len; /* used */
- uint32_t alloc; /* excluding the header and null terminator */
- unsigned char flags; /* 3 lsb of type, 5 unused bits */
- char buf[];
-};
-struct __attribute__ ((__packed__)) sdshdr64 {
- uint64_t len; /* used */
- uint64_t alloc; /* excluding the header and null terminator */
- unsigned char flags; /* 3 lsb of type, 5 unused bits */
- char buf[];
-};
-
-#define SDS_TYPE_5 0
-#define SDS_TYPE_8 1
-#define SDS_TYPE_16 2
-#define SDS_TYPE_32 3
-#define SDS_TYPE_64 4
-#define SDS_TYPE_MASK 7
-#define SDS_TYPE_BITS 3
-#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)));
-#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
-#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)
-
-static inline size_t sdslen(const sds s) {
- unsigned char flags = s[-1];
- switch(flags&SDS_TYPE_MASK) {
- case SDS_TYPE_5:
- return SDS_TYPE_5_LEN(flags);
- case SDS_TYPE_8:
- return SDS_HDR(8,s)->len;
- case SDS_TYPE_16:
- return SDS_HDR(16,s)->len;
- case SDS_TYPE_32:
- return SDS_HDR(32,s)->len;
- case SDS_TYPE_64:
- return SDS_HDR(64,s)->len;
- }
- return 0;
-}
-
-static inline size_t sdsavail(const sds s) {
- unsigned char flags = s[-1];
- switch(flags&SDS_TYPE_MASK) {
- case SDS_TYPE_5: {
- return 0;
- }
- case SDS_TYPE_8: {
- SDS_HDR_VAR(8,s);
- return sh->alloc - sh->len;
- }
- case SDS_TYPE_16: {
- SDS_HDR_VAR(16,s);
- return sh->alloc - sh->len;
- }
- case SDS_TYPE_32: {
- SDS_HDR_VAR(32,s);
- return sh->alloc - sh->len;
- }
- case SDS_TYPE_64: {
- SDS_HDR_VAR(64,s);
- return sh->alloc - sh->len;
- }
- }
- return 0;
-}
-
-static inline void sdssetlen(sds s, size_t newlen) {
- unsigned char flags = s[-1];
- switch(flags&SDS_TYPE_MASK) {
- case SDS_TYPE_5:
- {
- unsigned char *fp = ((unsigned char*)s)-1;
- *fp = (unsigned char)(SDS_TYPE_5 | (newlen << SDS_TYPE_BITS));
- }
- break;
- case SDS_TYPE_8:
- SDS_HDR(8,s)->len = (uint8_t)newlen;
- break;
- case SDS_TYPE_16:
- SDS_HDR(16,s)->len = (uint16_t)newlen;
- break;
- case SDS_TYPE_32:
- SDS_HDR(32,s)->len = (uint32_t)newlen;
- break;
- case SDS_TYPE_64:
- SDS_HDR(64,s)->len = (uint64_t)newlen;
- break;
- }
-}
-
-static inline void sdsinclen(sds s, size_t inc) {
- unsigned char flags = s[-1];
- switch(flags&SDS_TYPE_MASK) {
- case SDS_TYPE_5:
- {
- unsigned char *fp = ((unsigned char*)s)-1;
- unsigned char newlen = SDS_TYPE_5_LEN(flags)+(unsigned char)inc;
- *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
- }
- break;
- case SDS_TYPE_8:
- SDS_HDR(8,s)->len += (uint8_t)inc;
- break;
- case SDS_TYPE_16:
- SDS_HDR(16,s)->len += (uint16_t)inc;
- break;
- case SDS_TYPE_32:
- SDS_HDR(32,s)->len += (uint32_t)inc;
- break;
- case SDS_TYPE_64:
- SDS_HDR(64,s)->len += (uint64_t)inc;
- break;
- }
-}
-
-/* sdsalloc() = sdsavail() + sdslen() */
-static inline size_t sdsalloc(const sds s) {
- unsigned char flags = s[-1];
- switch(flags&SDS_TYPE_MASK) {
- case SDS_TYPE_5:
- return SDS_TYPE_5_LEN(flags);
- case SDS_TYPE_8:
- return SDS_HDR(8,s)->alloc;
- case SDS_TYPE_16:
- return SDS_HDR(16,s)->alloc;
- case SDS_TYPE_32:
- return SDS_HDR(32,s)->alloc;
- case SDS_TYPE_64:
- return SDS_HDR(64,s)->alloc;
- }
- return 0;
-}
-
-static inline void sdssetalloc(sds s, size_t newlen) {
- unsigned char flags = s[-1];
- switch(flags&SDS_TYPE_MASK) {
- case SDS_TYPE_5:
- /* Nothing to do, this type has no total allocation info. */
- break;
- case SDS_TYPE_8:
- SDS_HDR(8,s)->alloc = (uint8_t)newlen;
- break;
- case SDS_TYPE_16:
- SDS_HDR(16,s)->alloc = (uint16_t)newlen;
- break;
- case SDS_TYPE_32:
- SDS_HDR(32,s)->alloc = (uint32_t)newlen;
- break;
- case SDS_TYPE_64:
- SDS_HDR(64,s)->alloc = (uint64_t)newlen;
- break;
- }
-}
-
-sds sdsnewlen(const void *init, size_t initlen);
-sds sdsnew(const char *init);
-sds sdsempty(void);
-sds sdsdup(const sds s);
-void sdsfree(sds s);
-sds sdsgrowzero(sds s, size_t len);
-sds sdscatlen(sds s, const void *t, size_t len);
-sds sdscat(sds s, const char *t);
-sds sdscatsds(sds s, const sds t);
-sds sdscpylen(sds s, const char *t, size_t len);
-sds sdscpy(sds s, const char *t);
-
-sds sdscatvprintf(sds s, const char *fmt, va_list ap);
-#ifdef __GNUC__
-sds sdscatprintf(sds s, const char *fmt, ...)
- __attribute__((format(printf, 2, 3)));
-#else
-sds sdscatprintf(sds s, const char *fmt, ...);
-#endif
-
-sds sdscatfmt(sds s, char const *fmt, ...);
-sds sdstrim(sds s, const char *cset);
-void sdsrange(sds s, int start, int end);
-void sdsupdatelen(sds s);
-void sdsclear(sds s);
-int sdscmp(const sds s1, const sds s2);
-sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
-void sdsfreesplitres(sds *tokens, int count);
-void sdstolower(sds s);
-void sdstoupper(sds s);
-sds sdsfromlonglong(long long value);
-sds sdscatrepr(sds s, const char *p, size_t len);
-sds *sdssplitargs(const char *line, int *argc);
-sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
-sds sdsjoin(char **argv, int argc, char *sep);
-sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
-
-/* Low level functions exposed to the user API */
-sds sdsMakeRoomFor(sds s, size_t addlen);
-void sdsIncrLen(sds s, int incr);
-sds sdsRemoveFreeSpace(sds s);
-size_t sdsAllocSize(sds s);
-void *sdsAllocPtr(sds s);
-
-/* Export the allocator used by SDS to the program using SDS.
- * Sometimes the program SDS is linked to, may use a different set of
- * allocators, but may want to allocate or free things that SDS will
- * respectively free or allocate. */
-void *sds_malloc(size_t size);
-void *sds_realloc(void *ptr, size_t size);
-void sds_free(void *ptr);
-
-#ifdef REDIS_TEST
-int sdsTest(int argc, char *argv[]);
-#endif
-
-#endif
diff --git a/deps/hiredis/sdsalloc.h b/deps/hiredis/sdsalloc.h
deleted file mode 100644
index f43023c48..000000000
--- a/deps/hiredis/sdsalloc.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SDSLib 2.0 -- A C dynamic strings library
- *
- * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2015, Oran Agra
- * Copyright (c) 2015, Redis Labs, Inc
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* SDS allocator selection.
- *
- * This file is used in order to change the SDS allocator at compile time.
- * Just define the following defines to what you want to use. Also add
- * the include of your alternate allocator if needed (not needed in order
- * to use the default libc allocator). */
-
-#define s_malloc malloc
-#define s_realloc realloc
-#define s_free free
diff --git a/deps/hiredis/sockcompat.c b/deps/hiredis/sockcompat.c
deleted file mode 100644
index 4cc2f414f..000000000
--- a/deps/hiredis/sockcompat.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 2019, Marcus Geelnard <m at bitsnbites dot eu>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define REDIS_SOCKCOMPAT_IMPLEMENTATION
-#include "sockcompat.h"
-
-#ifdef _WIN32
-static int _wsaErrorToErrno(int err) {
- switch (err) {
- case WSAEWOULDBLOCK:
- return EWOULDBLOCK;
- case WSAEINPROGRESS:
- return EINPROGRESS;
- case WSAEALREADY:
- return EALREADY;
- case WSAENOTSOCK:
- return ENOTSOCK;
- case WSAEDESTADDRREQ:
- return EDESTADDRREQ;
- case WSAEMSGSIZE:
- return EMSGSIZE;
- case WSAEPROTOTYPE:
- return EPROTOTYPE;
- case WSAENOPROTOOPT:
- return ENOPROTOOPT;
- case WSAEPROTONOSUPPORT:
- return EPROTONOSUPPORT;
- case WSAEOPNOTSUPP:
- return EOPNOTSUPP;
- case WSAEAFNOSUPPORT:
- return EAFNOSUPPORT;
- case WSAEADDRINUSE:
- return EADDRINUSE;
- case WSAEADDRNOTAVAIL:
- return EADDRNOTAVAIL;
- case WSAENETDOWN:
- return ENETDOWN;
- case WSAENETUNREACH:
- return ENETUNREACH;
- case WSAENETRESET:
- return ENETRESET;
- case WSAECONNABORTED:
- return ECONNABORTED;
- case WSAECONNRESET:
- return ECONNRESET;
- case WSAENOBUFS:
- return ENOBUFS;
- case WSAEISCONN:
- return EISCONN;
- case WSAENOTCONN:
- return ENOTCONN;
- case WSAETIMEDOUT:
- return ETIMEDOUT;
- case WSAECONNREFUSED:
- return ECONNREFUSED;
- case WSAELOOP:
- return ELOOP;
- case WSAENAMETOOLONG:
- return ENAMETOOLONG;
- case WSAEHOSTUNREACH:
- return EHOSTUNREACH;
- case WSAENOTEMPTY:
- return ENOTEMPTY;
- default:
- /* We just return a generic I/O error if we could not find a relevant error. */
- return EIO;
- }
-}
-
-static void _updateErrno(int success) {
- errno = success ? 0 : _wsaErrorToErrno(WSAGetLastError());
-}
-
-static int _initWinsock() {
- static int s_initialized = 0;
- if (!s_initialized) {
- static WSADATA wsadata;
- int err = WSAStartup(MAKEWORD(2,2), &wsadata);
- if (err != 0) {
- errno = _wsaErrorToErrno(err);
- return 0;
- }
- s_initialized = 1;
- }
- return 1;
-}
-
-int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
- /* Note: This function is likely to be called before other functions, so run init here. */
- if (!_initWinsock()) {
- return EAI_FAIL;
- }
-
- switch (getaddrinfo(node, service, hints, res)) {
- case 0: return 0;
- case WSATRY_AGAIN: return EAI_AGAIN;
- case WSAEINVAL: return EAI_BADFLAGS;
- case WSAEAFNOSUPPORT: return EAI_FAMILY;
- case WSA_NOT_ENOUGH_MEMORY: return EAI_MEMORY;
- case WSAHOST_NOT_FOUND: return EAI_NONAME;
- case WSATYPE_NOT_FOUND: return EAI_SERVICE;
- case WSAESOCKTNOSUPPORT: return EAI_SOCKTYPE;
- default: return EAI_FAIL; /* Including WSANO_RECOVERY */
- }
-}
-
-const char *win32_gai_strerror(int errcode) {
- switch (errcode) {
- case 0: errcode = 0; break;
- case EAI_AGAIN: errcode = WSATRY_AGAIN; break;
- case EAI_BADFLAGS: errcode = WSAEINVAL; break;
- case EAI_FAMILY: errcode = WSAEAFNOSUPPORT; break;
- case EAI_MEMORY: errcode = WSA_NOT_ENOUGH_MEMORY; break;
- case EAI_NONAME: errcode = WSAHOST_NOT_FOUND; break;
- case EAI_SERVICE: errcode = WSATYPE_NOT_FOUND; break;
- case EAI_SOCKTYPE: errcode = WSAESOCKTNOSUPPORT; break;
- default: errcode = WSANO_RECOVERY; break; /* Including EAI_FAIL */
- }
- return gai_strerror(errcode);
-}
-
-void win32_freeaddrinfo(struct addrinfo *res) {
- freeaddrinfo(res);
-}
-
-SOCKET win32_socket(int domain, int type, int protocol) {
- SOCKET s;
-
- /* Note: This function is likely to be called before other functions, so run init here. */
- if (!_initWinsock()) {
- return INVALID_SOCKET;
- }
-
- _updateErrno((s = socket(domain, type, protocol)) != INVALID_SOCKET);
- return s;
-}
-
-int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp) {
- int ret = ioctlsocket(fd, (long)request, argp);
- _updateErrno(ret != SOCKET_ERROR);
- return ret != SOCKET_ERROR ? ret : -1;
-}
-
-int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) {
- int ret = bind(sockfd, addr, addrlen);
- _updateErrno(ret != SOCKET_ERROR);
- return ret != SOCKET_ERROR ? ret : -1;
-}
-
-int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen) {
- int ret = connect(sockfd, addr, addrlen);
- _updateErrno(ret != SOCKET_ERROR);
-
- /* For Winsock connect(), the WSAEWOULDBLOCK error means the same thing as
- * EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX
- * logic consistent. */
- if (errno == EWOULDBLOCK) {
- errno = EINPROGRESS;
- }
-
- return ret != SOCKET_ERROR ? ret : -1;
-}
-
-int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen) {
- int ret = 0;
- if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) {
- if (*optlen >= sizeof (struct timeval)) {
- struct timeval *tv = optval;
- DWORD timeout = 0;
- socklen_t dwlen = 0;
- ret = getsockopt(sockfd, level, optname, (char *)&timeout, &dwlen);
- tv->tv_sec = timeout / 1000;
- tv->tv_usec = (timeout * 1000) % 1000000;
- } else {
- ret = WSAEFAULT;
- }
- *optlen = sizeof (struct timeval);
- } else {
- ret = getsockopt(sockfd, level, optname, (char*)optval, optlen);
- }
- _updateErrno(ret != SOCKET_ERROR);
- return ret != SOCKET_ERROR ? ret : -1;
-}
-
-int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen) {
- int ret = 0;
- if ((level == SOL_SOCKET) && ((optname == SO_RCVTIMEO) || (optname == SO_SNDTIMEO))) {
- struct timeval *tv = optval;
- DWORD timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
- ret = setsockopt(sockfd, level, optname, (const char*)&timeout, sizeof(DWORD));
- } else {
- ret = setsockopt(sockfd, level, optname, (const char*)optval, optlen);
- }
- _updateErrno(ret != SOCKET_ERROR);
- return ret != SOCKET_ERROR ? ret : -1;
-}
-
-int win32_close(SOCKET fd) {
- int ret = closesocket(fd);
- _updateErrno(ret != SOCKET_ERROR);
- return ret != SOCKET_ERROR ? ret : -1;
-}
-
-ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags) {
- int ret = recv(sockfd, (char*)buf, (int)len, flags);
- _updateErrno(ret != SOCKET_ERROR);
- return ret != SOCKET_ERROR ? ret : -1;
-}
-
-ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags) {
- int ret = send(sockfd, (const char*)buf, (int)len, flags);
- _updateErrno(ret != SOCKET_ERROR);
- return ret != SOCKET_ERROR ? ret : -1;
-}
-
-int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
- int ret = WSAPoll(fds, nfds, timeout);
- _updateErrno(ret != SOCKET_ERROR);
- return ret != SOCKET_ERROR ? ret : -1;
-}
-#endif /* _WIN32 */
diff --git a/deps/hiredis/sockcompat.h b/deps/hiredis/sockcompat.h
deleted file mode 100644
index 56006c163..000000000
--- a/deps/hiredis/sockcompat.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2019, Marcus Geelnard <m at bitsnbites dot eu>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __SOCKCOMPAT_H
-#define __SOCKCOMPAT_H
-
-#ifndef _WIN32
-/* For POSIX systems we use the standard BSD socket API. */
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <poll.h>
-#else
-/* For Windows we use winsock. */
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600 /* To get WSAPoll etc. */
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <stddef.h>
-
-#ifdef _MSC_VER
-typedef signed long ssize_t;
-#endif
-
-/* Emulate the parts of the BSD socket API that we need (override the winsock signatures). */
-int win32_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
-const char *win32_gai_strerror(int errcode);
-void win32_freeaddrinfo(struct addrinfo *res);
-SOCKET win32_socket(int domain, int type, int protocol);
-int win32_ioctl(SOCKET fd, unsigned long request, unsigned long *argp);
-int win32_bind(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen);
-int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen);
-int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, socklen_t *optlen);
-int win32_setsockopt(SOCKET sockfd, int level, int optname, const void *optval, socklen_t optlen);
-int win32_close(SOCKET fd);
-ssize_t win32_recv(SOCKET sockfd, void *buf, size_t len, int flags);
-ssize_t win32_send(SOCKET sockfd, const void *buf, size_t len, int flags);
-typedef ULONG nfds_t;
-int win32_poll(struct pollfd *fds, nfds_t nfds, int timeout);
-
-#ifndef REDIS_SOCKCOMPAT_IMPLEMENTATION
-#define getaddrinfo(node, service, hints, res) win32_getaddrinfo(node, service, hints, res)
-#undef gai_strerror
-#define gai_strerror(errcode) win32_gai_strerror(errcode)
-#define freeaddrinfo(res) win32_freeaddrinfo(res)
-#define socket(domain, type, protocol) win32_socket(domain, type, protocol)
-#define ioctl(fd, request, argp) win32_ioctl(fd, request, argp)
-#define bind(sockfd, addr, addrlen) win32_bind(sockfd, addr, addrlen)
-#define connect(sockfd, addr, addrlen) win32_connect(sockfd, addr, addrlen)
-#define getsockopt(sockfd, level, optname, optval, optlen) win32_getsockopt(sockfd, level, optname, optval, optlen)
-#define setsockopt(sockfd, level, optname, optval, optlen) win32_setsockopt(sockfd, level, optname, optval, optlen)
-#define close(fd) win32_close(fd)
-#define recv(sockfd, buf, len, flags) win32_recv(sockfd, buf, len, flags)
-#define send(sockfd, buf, len, flags) win32_send(sockfd, buf, len, flags)
-#define poll(fds, nfds, timeout) win32_poll(fds, nfds, timeout)
-#endif /* REDIS_SOCKCOMPAT_IMPLEMENTATION */
-#endif /* _WIN32 */
-
-#endif /* __SOCKCOMPAT_H */
diff --git a/deps/hiredis/ssl.c b/deps/hiredis/ssl.c
deleted file mode 100644
index 78ab9e43e..000000000
--- a/deps/hiredis/ssl.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com>
- * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- * Copyright (c) 2019, Redis Labs
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Redis nor the names of its contributors may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "hiredis.h"
-#include "async.h"
-
-#include <assert.h>
-#include <pthread.h>
-#include <errno.h>
-#include <string.h>
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
-#include "async_private.h"
-
-void __redisSetError(redisContext *c, int type, const char *str);
-
-/* The SSL context is attached to SSL/TLS connections as a privdata. */
-typedef struct redisSSLContext {
- /**
- * OpenSSL SSL_CTX; It is optional and will not be set when using
- * user-supplied SSL.
- */
- SSL_CTX *ssl_ctx;
-
- /**
- * OpenSSL SSL object.
- */
- SSL *ssl;
-
- /**
- * SSL_write() requires to be called again with the same arguments it was
- * previously called with in the event of an SSL_read/SSL_write situation
- */
- size_t lastLen;
-
- /** Whether the SSL layer requires read (possibly before a write) */
- int wantRead;
-
- /**
- * Whether a write was requested prior to a read. If set, the write()
- * should resume whenever a read takes place, if possible
- */
- int pendingWrite;
-} redisSSLContext;
-
-/* Forward declaration */
-redisContextFuncs redisContextSSLFuncs;
-
-#ifdef HIREDIS_SSL_TRACE
-/**
- * Callback used for debugging
- */
-static void sslLogCallback(const SSL *ssl, int where, int ret) {
- const char *retstr = "";
- int should_log = 1;
- /* Ignore low-level SSL stuff */
-
- if (where & SSL_CB_ALERT) {
- should_log = 1;
- }
- if (where == SSL_CB_HANDSHAKE_START || where == SSL_CB_HANDSHAKE_DONE) {
- should_log = 1;
- }
- if ((where & SSL_CB_EXIT) && ret == 0) {
- should_log = 1;
- }
-
- if (!should_log) {
- return;
- }
-
- retstr = SSL_alert_type_string(ret);
- printf("ST(0x%x). %s. R(0x%x)%s\n", where, SSL_state_string_long(ssl), ret, retstr);
-
- if (where == SSL_CB_HANDSHAKE_DONE) {
- printf("Using SSL version %s. Cipher=%s\n", SSL_get_version(ssl), SSL_get_cipher_name(ssl));
- }
-}
-#endif
-
-/**
- * OpenSSL global initialization and locking handling callbacks.
- * Note that this is only required for OpenSSL < 1.1.0.
- */
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-#define HIREDIS_USE_CRYPTO_LOCKS
-#endif
-
-#ifdef HIREDIS_USE_CRYPTO_LOCKS
-typedef pthread_mutex_t sslLockType;
-static void sslLockInit(sslLockType *l) {
- pthread_mutex_init(l, NULL);
-}
-static void sslLockAcquire(sslLockType *l) {
- pthread_mutex_lock(l);
-}
-static void sslLockRelease(sslLockType *l) {
- pthread_mutex_unlock(l);
-}
-static pthread_mutex_t *ossl_locks;
-
-static void opensslDoLock(int mode, int lkid, const char *f, int line) {
- sslLockType *l = ossl_locks + lkid;
-
- if (mode & CRYPTO_LOCK) {
- sslLockAcquire(l);
- } else {
- sslLockRelease(l);
- }
-
- (void)f;
- (void)line;
-}
-
-static void initOpensslLocks(void) {
- unsigned ii, nlocks;
- if (CRYPTO_get_locking_callback() != NULL) {
- /* Someone already set the callback before us. Don't destroy it! */
- return;
- }
- nlocks = CRYPTO_num_locks();
- ossl_locks = malloc(sizeof(*ossl_locks) * nlocks);
- for (ii = 0; ii < nlocks; ii++) {
- sslLockInit(ossl_locks + ii);
- }
- CRYPTO_set_locking_callback(opensslDoLock);
-}
-#endif /* HIREDIS_USE_CRYPTO_LOCKS */
-
-/**
- * SSL Connection initialization.
- */
-
-static int redisSSLConnect(redisContext *c, SSL_CTX *ssl_ctx, SSL *ssl) {
- if (c->privdata) {
- __redisSetError(c, REDIS_ERR_OTHER, "redisContext was already associated");
- return REDIS_ERR;
- }
- c->privdata = calloc(1, sizeof(redisSSLContext));
-
- c->funcs = &redisContextSSLFuncs;
- redisSSLContext *rssl = c->privdata;
-
- rssl->ssl_ctx = ssl_ctx;
- rssl->ssl = ssl;
-
- SSL_set_mode(rssl->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
- SSL_set_fd(rssl->ssl, c->fd);
- SSL_set_connect_state(rssl->ssl);
-
- ERR_clear_error();
- int rv = SSL_connect(rssl->ssl);
- if (rv == 1) {
- return REDIS_OK;
- }
-
- rv = SSL_get_error(rssl->ssl, rv);
- if (((c->flags & REDIS_BLOCK) == 0) &&
- (rv == SSL_ERROR_WANT_READ || rv == SSL_ERROR_WANT_WRITE)) {
- return REDIS_OK;
- }
-
- if (c->err == 0) {
- char err[512];
- if (rv == SSL_ERROR_SYSCALL)
- snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",strerror(errno));
- else {
- unsigned long e = ERR_peek_last_error();
- snprintf(err,sizeof(err)-1,"SSL_connect failed: %s",
- ERR_reason_error_string(e));
- }
- __redisSetError(c, REDIS_ERR_IO, err);
- }
- return REDIS_ERR;
-}
-
-int redisInitiateSSL(redisContext *c, SSL *ssl) {
- return redisSSLConnect(c, NULL, ssl);
-}
-
-int redisSecureConnection(redisContext *c, const char *capath,
- const char *certpath, const char *keypath, const char *servername) {
-
- SSL_CTX *ssl_ctx = NULL;
- SSL *ssl = NULL;
-
- /* Initialize global OpenSSL stuff */
- static int isInit = 0;
- if (!isInit) {
- isInit = 1;
- SSL_library_init();
-#ifdef HIREDIS_USE_CRYPTO_LOCKS
- initOpensslLocks();
-#endif
- }
-
- ssl_ctx = SSL_CTX_new(SSLv23_client_method());
- if (!ssl_ctx) {
- __redisSetError(c, REDIS_ERR_OTHER, "Failed to create SSL_CTX");
- goto error;
- }
-
-#ifdef HIREDIS_SSL_TRACE
- SSL_CTX_set_info_callback(ssl_ctx, sslLogCallback);
-#endif
- SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
- SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
- if ((certpath != NULL && keypath == NULL) || (keypath != NULL && certpath == NULL)) {
- __redisSetError(c, REDIS_ERR_OTHER, "certpath and keypath must be specified together");
- goto error;
- }
-
- if (capath) {
- if (!SSL_CTX_load_verify_locations(ssl_ctx, capath, NULL)) {
- __redisSetError(c, REDIS_ERR_OTHER, "Invalid CA certificate");
- goto error;
- }
- }
- if (certpath) {
- if (!SSL_CTX_use_certificate_chain_file(ssl_ctx, certpath)) {
- __redisSetError(c, REDIS_ERR_OTHER, "Invalid client certificate");
- goto error;
- }
- if (!SSL_CTX_use_PrivateKey_file(ssl_ctx, keypath, SSL_FILETYPE_PEM)) {
- __redisSetError(c, REDIS_ERR_OTHER, "Invalid client key");
- goto error;
- }
- }
-
- ssl = SSL_new(ssl_ctx);
- if (!ssl) {
- __redisSetError(c, REDIS_ERR_OTHER, "Couldn't create new SSL instance");
- goto error;
- }
- if (servername) {
- if (!SSL_set_tlsext_host_name(ssl, servername)) {
- __redisSetError(c, REDIS_ERR_OTHER, "Couldn't set server name indication");
- goto error;
- }
- }
-
- return redisSSLConnect(c, ssl_ctx, ssl);
-
-error:
- if (ssl) SSL_free(ssl);
- if (ssl_ctx) SSL_CTX_free(ssl_ctx);
- return REDIS_ERR;
-}
-
-static int maybeCheckWant(redisSSLContext *rssl, int rv) {
- /**
- * If the error is WANT_READ or WANT_WRITE, the appropriate flags are set
- * and true is returned. False is returned otherwise
- */
- if (rv == SSL_ERROR_WANT_READ) {
- rssl->wantRead = 1;
- return 1;
- } else if (rv == SSL_ERROR_WANT_WRITE) {
- rssl->pendingWrite = 1;
- return 1;
- } else {
- return 0;
- }
-}
-
-/**
- * Implementation of redisContextFuncs for SSL connections.
- */
-
-static void redisSSLFreeContext(void *privdata){
- redisSSLContext *rsc = privdata;
-
- if (!rsc) return;
- if (rsc->ssl) {
- SSL_free(rsc->ssl);
- rsc->ssl = NULL;
- }
- if (rsc->ssl_ctx) {
- SSL_CTX_free(rsc->ssl_ctx);
- rsc->ssl_ctx = NULL;
- }
- free(rsc);
-}
-
-static int redisSSLRead(redisContext *c, char *buf, size_t bufcap) {
- redisSSLContext *rssl = c->privdata;
-
- int nread = SSL_read(rssl->ssl, buf, bufcap);
- if (nread > 0) {
- return nread;
- } else if (nread == 0) {
- __redisSetError(c, REDIS_ERR_EOF, "Server closed the connection");
- return -1;
- } else {
- int err = SSL_get_error(rssl->ssl, nread);
- if (c->flags & REDIS_BLOCK) {
- /**
- * In blocking mode, we should never end up in a situation where
- * we get an error without it being an actual error, except
- * in the case of EINTR, which can be spuriously received from
- * debuggers or whatever.
- */
- if (errno == EINTR) {
- return 0;
- } else {
- const char *msg = NULL;
- if (errno == EAGAIN) {
- msg = "Resource temporarily unavailable";
- }
- __redisSetError(c, REDIS_ERR_IO, msg);
- return -1;
- }
- }
-
- /**
- * We can very well get an EWOULDBLOCK/EAGAIN, however
- */
- if (maybeCheckWant(rssl, err)) {
- return 0;
- } else {
- __redisSetError(c, REDIS_ERR_IO, NULL);
- return -1;
- }
- }
-}
-
-static int redisSSLWrite(redisContext *c) {
- redisSSLContext *rssl = c->privdata;
-
- size_t len = rssl->lastLen ? rssl->lastLen : sdslen(c->obuf);
- int rv = SSL_write(rssl->ssl, c->obuf, len);
-
- if (rv > 0) {
- rssl->lastLen = 0;
- } else if (rv < 0) {
- rssl->lastLen = len;
-
- int err = SSL_get_error(rssl->ssl, rv);
- if ((c->flags & REDIS_BLOCK) == 0 && maybeCheckWant(rssl, err)) {
- return 0;
- } else {
- __redisSetError(c, REDIS_ERR_IO, NULL);
- return -1;
- }
- }
- return rv;
-}
-
-static void redisSSLAsyncRead(redisAsyncContext *ac) {
- int rv;
- redisSSLContext *rssl = ac->c.privdata;
- redisContext *c = &ac->c;
-
- rssl->wantRead = 0;
-
- if (rssl->pendingWrite) {
- int done;
-
- /* This is probably just a write event */
- rssl->pendingWrite = 0;
- rv = redisBufferWrite(c, &done);
- if (rv == REDIS_ERR) {
- __redisAsyncDisconnect(ac);
- return;
- } else if (!done) {
- _EL_ADD_WRITE(ac);
- }
- }
-
- rv = redisBufferRead(c);
- if (rv == REDIS_ERR) {
- __redisAsyncDisconnect(ac);
- } else {
- _EL_ADD_READ(ac);
- redisProcessCallbacks(ac);
- }
-}
-
-static void redisSSLAsyncWrite(redisAsyncContext *ac) {
- int rv, done = 0;
- redisSSLContext *rssl = ac->c.privdata;
- redisContext *c = &ac->c;
-
- rssl->pendingWrite = 0;
- rv = redisBufferWrite(c, &done);
- if (rv == REDIS_ERR) {
- __redisAsyncDisconnect(ac);
- return;
- }
-
- if (!done) {
- if (rssl->wantRead) {
- /* Need to read-before-write */
- rssl->pendingWrite = 1;
- _EL_DEL_WRITE(ac);
- } else {
- /* No extra reads needed, just need to write more */
- _EL_ADD_WRITE(ac);
- }
- } else {
- /* Already done! */
- _EL_DEL_WRITE(ac);
- }
-
- /* Always reschedule a read */
- _EL_ADD_READ(ac);
-}
-
-redisContextFuncs redisContextSSLFuncs = {
- .free_privdata = redisSSLFreeContext,
- .async_read = redisSSLAsyncRead,
- .async_write = redisSSLAsyncWrite,
- .read = redisSSLRead,
- .write = redisSSLWrite
-};
-
diff --git a/deps/hiredis/test.c b/deps/hiredis/test.c
deleted file mode 100644
index 8668e1856..000000000
--- a/deps/hiredis/test.c
+++ /dev/null
@@ -1,1012 +0,0 @@
-#include "fmacros.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netdb.h>
-#include <assert.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <limits.h>
-
-#include "hiredis.h"
-#ifdef HIREDIS_TEST_SSL
-#include "hiredis_ssl.h"
-#endif
-#include "net.h"
-
-enum connection_type {
- CONN_TCP,
- CONN_UNIX,
- CONN_FD,
- CONN_SSL
-};
-
-struct config {
- enum connection_type type;
-
- struct {
- const char *host;
- int port;
- struct timeval timeout;
- } tcp;
-
- struct {
- const char *path;
- } unix_sock;
-
- struct {
- const char *host;
- int port;
- const char *ca_cert;
- const char *cert;
- const char *key;
- } ssl;
-};
-
-/* The following lines make up our testing "framework" :) */
-static int tests = 0, fails = 0;
-#define test(_s) { printf("#%02d ", ++tests); printf(_s); }
-#define test_cond(_c) if(_c) printf("\033[0;32mPASSED\033[0;0m\n"); else {printf("\033[0;31mFAILED\033[0;0m\n"); fails++;}
-
-static long long usec(void) {
- struct timeval tv;
- gettimeofday(&tv,NULL);
- return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
-}
-
-/* The assert() calls below have side effects, so we need assert()
- * even if we are compiling without asserts (-DNDEBUG). */
-#ifdef NDEBUG
-#undef assert
-#define assert(e) (void)(e)
-#endif
-
-static redisContext *select_database(redisContext *c) {
- redisReply *reply;
-
- /* Switch to DB 9 for testing, now that we know we can chat. */
- reply = redisCommand(c,"SELECT 9");
- assert(reply != NULL);
- freeReplyObject(reply);
-
- /* Make sure the DB is emtpy */
- reply = redisCommand(c,"DBSIZE");
- assert(reply != NULL);
- if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) {
- /* Awesome, DB 9 is empty and we can continue. */
- freeReplyObject(reply);
- } else {
- printf("Database #9 is not empty, test can not continue\n");
- exit(1);
- }
-
- return c;
-}
-
-static int disconnect(redisContext *c, int keep_fd) {
- redisReply *reply;
-
- /* Make sure we're on DB 9. */
- reply = redisCommand(c,"SELECT 9");
- assert(reply != NULL);
- freeReplyObject(reply);
- reply = redisCommand(c,"FLUSHDB");
- assert(reply != NULL);
- freeReplyObject(reply);
-
- /* Free the context as well, but keep the fd if requested. */
- if (keep_fd)
- return redisFreeKeepFd(c);
- redisFree(c);
- return -1;
-}
-
-static void do_ssl_handshake(redisContext *c, struct config config) {
-#ifdef HIREDIS_TEST_SSL
- redisSecureConnection(c, config.ssl.ca_cert, config.ssl.cert, config.ssl.key, NULL);
- if (c->err) {
- printf("SSL error: %s\n", c->errstr);
- redisFree(c);
- exit(1);
- }
-#else
- (void) c;
- (void) config;
-#endif
-}
-
-static redisContext *do_connect(struct config config) {
- redisContext *c = NULL;
-
- if (config.type == CONN_TCP) {
- c = redisConnect(config.tcp.host, config.tcp.port);
- } else if (config.type == CONN_SSL) {
- c = redisConnect(config.ssl.host, config.ssl.port);
- } else if (config.type == CONN_UNIX) {
- c = redisConnectUnix(config.unix_sock.path);
- } else if (config.type == CONN_FD) {
- /* Create a dummy connection just to get an fd to inherit */
- redisContext *dummy_ctx = redisConnectUnix(config.unix_sock.path);
- if (dummy_ctx) {
- int fd = disconnect(dummy_ctx, 1);
- printf("Connecting to inherited fd %d\n", fd);
- c = redisConnectFd(fd);
- }
- } else {
- assert(NULL);
- }
-
- if (c == NULL) {
- printf("Connection error: can't allocate redis context\n");
- exit(1);
- } else if (c->err) {
- printf("Connection error: %s\n", c->errstr);
- redisFree(c);
- exit(1);
- }
-
- if (config.type == CONN_SSL) {
- do_ssl_handshake(c, config);
- }
-
- return select_database(c);
-}
-
-static void do_reconnect(redisContext *c, struct config config) {
- redisReconnect(c);
-
- if (config.type == CONN_SSL) {
- do_ssl_handshake(c, config);
- }
-}
-
-static void test_format_commands(void) {
- char *cmd;
- int len;
-
- test("Format command without interpolation: ");
- len = redisFormatCommand(&cmd,"SET foo bar");
- test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
- len == 4+4+(3+2)+4+(3+2)+4+(3+2));
- free(cmd);
-
- test("Format command with %%s string interpolation: ");
- len = redisFormatCommand(&cmd,"SET %s %s","foo","bar");
- test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
- len == 4+4+(3+2)+4+(3+2)+4+(3+2));
- free(cmd);
-
- test("Format command with %%s and an empty string: ");
- len = redisFormatCommand(&cmd,"SET %s %s","foo","");
- test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
- len == 4+4+(3+2)+4+(3+2)+4+(0+2));
- free(cmd);
-
- test("Format command with an empty string in between proper interpolations: ");
- len = redisFormatCommand(&cmd,"SET %s %s","","foo");
- test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len) == 0 &&
- len == 4+4+(3+2)+4+(0+2)+4+(3+2));
- free(cmd);
-
- test("Format command with %%b string interpolation: ");
- len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3);
- 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 &&
- len == 4+4+(3+2)+4+(3+2)+4+(3+2));
- free(cmd);
-
- test("Format command with %%b and an empty string: ");
- len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0);
- test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
- len == 4+4+(3+2)+4+(3+2)+4+(0+2));
- free(cmd);
-
- test("Format command with literal %%: ");
- len = redisFormatCommand(&cmd,"SET %% %%");
- test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len) == 0 &&
- len == 4+4+(3+2)+4+(1+2)+4+(1+2));
- free(cmd);
-
- /* Vararg width depends on the type. These tests make sure that the
- * width is correctly determined using the format and subsequent varargs
- * can correctly be interpolated. */
-#define INTEGER_WIDTH_TEST(fmt, type) do { \
- type value = 123; \
- test("Format command with printf-delegation (" #type "): "); \
- len = redisFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello"); \
- test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:00000123\r\n$9\r\nstr:hello\r\n",len) == 0 && \
- len == 4+5+(12+2)+4+(9+2)); \
- free(cmd); \
-} while(0)
-
-#define FLOAT_WIDTH_TEST(type) do { \
- type value = 123.0; \
- test("Format command with printf-delegation (" #type "): "); \
- len = redisFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello"); \
- test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:0123.000\r\n$9\r\nstr:hello\r\n",len) == 0 && \
- len == 4+5+(12+2)+4+(9+2)); \
- free(cmd); \
-} while(0)
-
- INTEGER_WIDTH_TEST("d", int);
- INTEGER_WIDTH_TEST("hhd", char);
- INTEGER_WIDTH_TEST("hd", short);
- INTEGER_WIDTH_TEST("ld", long);
- INTEGER_WIDTH_TEST("lld", long long);
- INTEGER_WIDTH_TEST("u", unsigned int);
- INTEGER_WIDTH_TEST("hhu", unsigned char);
- INTEGER_WIDTH_TEST("hu", unsigned short);
- INTEGER_WIDTH_TEST("lu", unsigned long);
- INTEGER_WIDTH_TEST("llu", unsigned long long);
- FLOAT_WIDTH_TEST(float);
- FLOAT_WIDTH_TEST(double);
-
- test("Format command with invalid printf format: ");
- len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3);
- test_cond(len == -1);
-
- const char *argv[3];
- argv[0] = "SET";
- argv[1] = "foo\0xxx";
- argv[2] = "bar";
- size_t lens[3] = { 3, 7, 3 };
- int argc = 3;
-
- test("Format command by passing argc/argv without lengths: ");
- len = redisFormatCommandArgv(&cmd,argc,argv,NULL);
- test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
- len == 4+4+(3+2)+4+(3+2)+4+(3+2));
- free(cmd);
-
- test("Format command by passing argc/argv with lengths: ");
- len = redisFormatCommandArgv(&cmd,argc,argv,lens);
- 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 &&
- len == 4+4+(3+2)+4+(7+2)+4+(3+2));
- free(cmd);
-
- sds sds_cmd;
-
- sds_cmd = sdsempty();
- test("Format command into sds by passing argc/argv without lengths: ");
- len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,NULL);
- 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 &&
- len == 4+4+(3+2)+4+(3+2)+4+(3+2));
- sdsfree(sds_cmd);
-
- sds_cmd = sdsempty();
- test("Format command into sds by passing argc/argv with lengths: ");
- len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,lens);
- 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 &&
- len == 4+4+(3+2)+4+(7+2)+4+(3+2));
- sdsfree(sds_cmd);
-}
-
-static void test_append_formatted_commands(struct config config) {
- redisContext *c;
- redisReply *reply;
- char *cmd;
- int len;
-
- c = do_connect(config);
-
- test("Append format command: ");
-
- len = redisFormatCommand(&cmd, "SET foo bar");
-
- test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK);
-
- assert(redisGetReply(c, (void*)&reply) == REDIS_OK);
-
- free(cmd);
- freeReplyObject(reply);
-
- disconnect(c, 0);
-}
-
-static void test_reply_reader(void) {
- redisReader *reader;
- void *reply;
- int ret;
- int i;
-
- test("Error handling in reply parser: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader,(char*)"@foo\r\n",6);
- ret = redisReaderGetReply(reader,NULL);
- test_cond(ret == REDIS_ERR &&
- strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0);
- redisReaderFree(reader);
-
- /* when the reply already contains multiple items, they must be free'd
- * on an error. valgrind will bark when this doesn't happen. */
- test("Memory cleanup in reply parser: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader,(char*)"*2\r\n",4);
- redisReaderFeed(reader,(char*)"$5\r\nhello\r\n",11);
- redisReaderFeed(reader,(char*)"@foo\r\n",6);
- ret = redisReaderGetReply(reader,NULL);
- test_cond(ret == REDIS_ERR &&
- strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0);
- redisReaderFree(reader);
-
- test("Set error on nested multi bulks with depth > 7: ");
- reader = redisReaderCreate();
-
- for (i = 0; i < 9; i++) {
- redisReaderFeed(reader,(char*)"*1\r\n",4);
- }
-
- ret = redisReaderGetReply(reader,NULL);
- test_cond(ret == REDIS_ERR &&
- strncasecmp(reader->errstr,"No support for",14) == 0);
- redisReaderFree(reader);
-
- test("Correctly parses LLONG_MAX: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader, ":9223372036854775807\r\n",22);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_OK &&
- ((redisReply*)reply)->type == REDIS_REPLY_INTEGER &&
- ((redisReply*)reply)->integer == LLONG_MAX);
- freeReplyObject(reply);
- redisReaderFree(reader);
-
- test("Set error when > LLONG_MAX: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader, ":9223372036854775808\r\n",22);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_ERR &&
- strcasecmp(reader->errstr,"Bad integer value") == 0);
- freeReplyObject(reply);
- redisReaderFree(reader);
-
- test("Correctly parses LLONG_MIN: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader, ":-9223372036854775808\r\n",23);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_OK &&
- ((redisReply*)reply)->type == REDIS_REPLY_INTEGER &&
- ((redisReply*)reply)->integer == LLONG_MIN);
- freeReplyObject(reply);
- redisReaderFree(reader);
-
- test("Set error when < LLONG_MIN: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader, ":-9223372036854775809\r\n",23);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_ERR &&
- strcasecmp(reader->errstr,"Bad integer value") == 0);
- freeReplyObject(reply);
- redisReaderFree(reader);
-
- test("Set error when array < -1: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader, "*-2\r\n+asdf\r\n",12);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_ERR &&
- strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0);
- freeReplyObject(reply);
- redisReaderFree(reader);
-
- test("Set error when bulk < -1: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader, "$-2\r\nasdf\r\n",11);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_ERR &&
- strcasecmp(reader->errstr,"Bulk string length out of range") == 0);
- freeReplyObject(reply);
- redisReaderFree(reader);
-
-#if LLONG_MAX > SIZE_MAX
- test("Set error when array > SIZE_MAX: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader, "*9223372036854775807\r\n+asdf\r\n",29);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_ERR &&
- strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0);
- freeReplyObject(reply);
- redisReaderFree(reader);
-
- test("Set error when bulk > SIZE_MAX: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader, "$9223372036854775807\r\nasdf\r\n",28);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_ERR &&
- strcasecmp(reader->errstr,"Bulk string length out of range") == 0);
- freeReplyObject(reply);
- redisReaderFree(reader);
-#endif
-
- test("Works with NULL functions for reply: ");
- reader = redisReaderCreate();
- reader->fn = NULL;
- redisReaderFeed(reader,(char*)"+OK\r\n",5);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS);
- redisReaderFree(reader);
-
- test("Works when a single newline (\\r\\n) covers two calls to feed: ");
- reader = redisReaderCreate();
- reader->fn = NULL;
- redisReaderFeed(reader,(char*)"+OK\r",4);
- ret = redisReaderGetReply(reader,&reply);
- assert(ret == REDIS_OK && reply == NULL);
- redisReaderFeed(reader,(char*)"\n",1);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_OK && reply == (void*)REDIS_REPLY_STATUS);
- redisReaderFree(reader);
-
- test("Don't reset state after protocol error: ");
- reader = redisReaderCreate();
- reader->fn = NULL;
- redisReaderFeed(reader,(char*)"x",1);
- ret = redisReaderGetReply(reader,&reply);
- assert(ret == REDIS_ERR);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_ERR && reply == NULL);
- redisReaderFree(reader);
-
- /* Regression test for issue #45 on GitHub. */
- test("Don't do empty allocation for empty multi bulk: ");
- reader = redisReaderCreate();
- redisReaderFeed(reader,(char*)"*0\r\n",4);
- ret = redisReaderGetReply(reader,&reply);
- test_cond(ret == REDIS_OK &&
- ((redisReply*)reply)->type == REDIS_REPLY_ARRAY &&
- ((redisReply*)reply)->elements == 0);
- freeReplyObject(reply);
- redisReaderFree(reader);
-}
-
-static void test_free_null(void) {
- void *redisCtx = NULL;
- void *reply = NULL;
-
- test("Don't fail when redisFree is passed a NULL value: ");
- redisFree(redisCtx);
- test_cond(redisCtx == NULL);
-
- test("Don't fail when freeReplyObject is passed a NULL value: ");
- freeReplyObject(reply);
- test_cond(reply == NULL);
-}
-
-#define HIREDIS_BAD_DOMAIN "idontexist-noreally.com"
-static void test_blocking_connection_errors(void) {
- redisContext *c;
- struct addrinfo hints = {.ai_family = AF_INET};
- struct addrinfo *ai_tmp = NULL;
-
- int rv = getaddrinfo(HIREDIS_BAD_DOMAIN, "6379", &hints, &ai_tmp);
- if (rv != 0) {
- // Address does *not* exist
- test("Returns error when host cannot be resolved: ");
- // First see if this domain name *actually* resolves to NXDOMAIN
- c = redisConnect(HIREDIS_BAD_DOMAIN, 6379);
- test_cond(
- c->err == REDIS_ERR_OTHER &&
- (strcmp(c->errstr, "Name or service not known") == 0 ||
- strcmp(c->errstr, "Can't resolve: " HIREDIS_BAD_DOMAIN) == 0 ||
- strcmp(c->errstr, "Name does not resolve") == 0 ||
- strcmp(c->errstr,
- "nodename nor servname provided, or not known") == 0 ||
- strcmp(c->errstr, "No address associated with hostname") == 0 ||
- strcmp(c->errstr, "Temporary failure in name resolution") == 0 ||
- strcmp(c->errstr,
- "hostname nor servname provided, or not known") == 0 ||
- strcmp(c->errstr, "no address associated with name") == 0));
- redisFree(c);
- } else {
- printf("Skipping NXDOMAIN test. Found evil ISP!\n");
- freeaddrinfo(ai_tmp);
- }
-
- test("Returns error when the port is not open: ");
- c = redisConnect((char*)"localhost", 1);
- test_cond(c->err == REDIS_ERR_IO &&
- strcmp(c->errstr,"Connection refused") == 0);
- redisFree(c);
-
- test("Returns error when the unix_sock socket path doesn't accept connections: ");
- c = redisConnectUnix((char*)"/tmp/idontexist.sock");
- test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */
- redisFree(c);
-}
-
-static void test_blocking_connection(struct config config) {
- redisContext *c;
- redisReply *reply;
-
- c = do_connect(config);
-
- test("Is able to deliver commands: ");
- reply = redisCommand(c,"PING");
- test_cond(reply->type == REDIS_REPLY_STATUS &&
- strcasecmp(reply->str,"pong") == 0)
- freeReplyObject(reply);
-
- test("Is a able to send commands verbatim: ");
- reply = redisCommand(c,"SET foo bar");
- test_cond (reply->type == REDIS_REPLY_STATUS &&
- strcasecmp(reply->str,"ok") == 0)
- freeReplyObject(reply);
-
- test("%%s String interpolation works: ");
- reply = redisCommand(c,"SET %s %s","foo","hello world");
- freeReplyObject(reply);
- reply = redisCommand(c,"GET foo");
- test_cond(reply->type == REDIS_REPLY_STRING &&
- strcmp(reply->str,"hello world") == 0);
- freeReplyObject(reply);
-
- test("%%b String interpolation works: ");
- reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11);
- freeReplyObject(reply);
- reply = redisCommand(c,"GET foo");
- test_cond(reply->type == REDIS_REPLY_STRING &&
- memcmp(reply->str,"hello\x00world",11) == 0)
-
- test("Binary reply length is correct: ");
- test_cond(reply->len == 11)
- freeReplyObject(reply);
-
- test("Can parse nil replies: ");
- reply = redisCommand(c,"GET nokey");
- test_cond(reply->type == REDIS_REPLY_NIL)
- freeReplyObject(reply);
-
- /* test 7 */
- test("Can parse integer replies: ");
- reply = redisCommand(c,"INCR mycounter");
- test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1)
- freeReplyObject(reply);
-
- test("Can parse multi bulk replies: ");
- freeReplyObject(redisCommand(c,"LPUSH mylist foo"));
- freeReplyObject(redisCommand(c,"LPUSH mylist bar"));
- reply = redisCommand(c,"LRANGE mylist 0 -1");
- test_cond(reply->type == REDIS_REPLY_ARRAY &&
- reply->elements == 2 &&
- !memcmp(reply->element[0]->str,"bar",3) &&
- !memcmp(reply->element[1]->str,"foo",3))
- freeReplyObject(reply);
-
- /* m/e with multi bulk reply *before* other reply.
- * specifically test ordering of reply items to parse. */
- test("Can handle nested multi bulk replies: ");
- freeReplyObject(redisCommand(c,"MULTI"));
- freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1"));
- freeReplyObject(redisCommand(c,"PING"));
- reply = (redisCommand(c,"EXEC"));
- test_cond(reply->type == REDIS_REPLY_ARRAY &&
- reply->elements == 2 &&
- reply->element[0]->type == REDIS_REPLY_ARRAY &&
- reply->element[0]->elements == 2 &&
- !memcmp(reply->element[0]->element[0]->str,"bar",3) &&
- !memcmp(reply->element[0]->element[1]->str,"foo",3) &&
- reply->element[1]->type == REDIS_REPLY_STATUS &&
- strcasecmp(reply->element[1]->str,"pong") == 0);
- freeReplyObject(reply);
-
- disconnect(c, 0);
-}
-
-static void test_blocking_connection_timeouts(struct config config) {
- redisContext *c;
- redisReply *reply;
- ssize_t s;
- const char *cmd = "DEBUG SLEEP 3\r\n";
- struct timeval tv;
-
- c = do_connect(config);
- test("Successfully completes a command when the timeout is not exceeded: ");
- reply = redisCommand(c,"SET foo fast");
- freeReplyObject(reply);
- tv.tv_sec = 0;
- tv.tv_usec = 10000;
- redisSetTimeout(c, tv);
- reply = redisCommand(c, "GET foo");
- test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0);
- freeReplyObject(reply);
- disconnect(c, 0);
-
- c = do_connect(config);
- test("Does not return a reply when the command times out: ");
- redisAppendFormattedCommand(c, cmd, strlen(cmd));
- s = c->funcs->write(c);
- tv.tv_sec = 0;
- tv.tv_usec = 10000;
- redisSetTimeout(c, tv);
- reply = redisCommand(c, "GET foo");
- test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0);
- freeReplyObject(reply);
-
- test("Reconnect properly reconnects after a timeout: ");
- do_reconnect(c, config);
- reply = redisCommand(c, "PING");
- test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
- freeReplyObject(reply);
-
- test("Reconnect properly uses owned parameters: ");
- config.tcp.host = "foo";
- config.unix_sock.path = "foo";
- do_reconnect(c, config);
- reply = redisCommand(c, "PING");
- test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
- freeReplyObject(reply);
-
- disconnect(c, 0);
-}
-
-static void test_blocking_io_errors(struct config config) {
- redisContext *c;
- redisReply *reply;
- void *_reply;
- int major, minor;
-
- /* Connect to target given by config. */
- c = do_connect(config);
- {
- /* Find out Redis version to determine the path for the next test */
- const char *field = "redis_version:";
- char *p, *eptr;
-
- reply = redisCommand(c,"INFO");
- p = strstr(reply->str,field);
- major = strtol(p+strlen(field),&eptr,10);
- p = eptr+1; /* char next to the first "." */
- minor = strtol(p,&eptr,10);
- freeReplyObject(reply);
- }
-
- test("Returns I/O error when the connection is lost: ");
- reply = redisCommand(c,"QUIT");
- if (major > 2 || (major == 2 && minor > 0)) {
- /* > 2.0 returns OK on QUIT and read() should be issued once more
- * to know the descriptor is at EOF. */
- test_cond(strcasecmp(reply->str,"OK") == 0 &&
- redisGetReply(c,&_reply) == REDIS_ERR);
- freeReplyObject(reply);
- } else {
- test_cond(reply == NULL);
- }
-
- /* On 2.0, QUIT will cause the connection to be closed immediately and
- * the read(2) for the reply on QUIT will set the error to EOF.
- * On >2.0, QUIT will return with OK and another read(2) needed to be
- * issued to find out the socket was closed by the server. In both
- * conditions, the error will be set to EOF. */
- assert(c->err == REDIS_ERR_EOF &&
- strcmp(c->errstr,"Server closed the connection") == 0);
- redisFree(c);
-
- c = do_connect(config);
- test("Returns I/O error on socket timeout: ");
- struct timeval tv = { 0, 1000 };
- assert(redisSetTimeout(c,tv) == REDIS_OK);
- test_cond(redisGetReply(c,&_reply) == REDIS_ERR &&
- c->err == REDIS_ERR_IO && errno == EAGAIN);
- redisFree(c);
-}
-
-static void test_invalid_timeout_errors(struct config config) {
- redisContext *c;
-
- test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: ");
-
- config.tcp.timeout.tv_sec = 0;
- config.tcp.timeout.tv_usec = 10000001;
-
- c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
-
- test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0);
- redisFree(c);
-
- test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: ");
-
- config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1;
- config.tcp.timeout.tv_usec = 0;
-
- c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
-
- test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0);
- redisFree(c);
-}
-
-static void test_throughput(struct config config) {
- redisContext *c = do_connect(config);
- redisReply **replies;
- int i, num;
- long long t1, t2;
-
- test("Throughput:\n");
- for (i = 0; i < 500; i++)
- freeReplyObject(redisCommand(c,"LPUSH mylist foo"));
-
- num = 1000;
- replies = malloc(sizeof(redisReply*)*num);
- t1 = usec();
- for (i = 0; i < num; i++) {
- replies[i] = redisCommand(c,"PING");
- assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx PING: %.3fs)\n", num, (t2-t1)/1000000.0);
-
- replies = malloc(sizeof(redisReply*)*num);
- t1 = usec();
- for (i = 0; i < num; i++) {
- replies[i] = redisCommand(c,"LRANGE mylist 0 499");
- assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY);
- assert(replies[i] != NULL && replies[i]->elements == 500);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0);
-
- replies = malloc(sizeof(redisReply*)*num);
- t1 = usec();
- for (i = 0; i < num; i++) {
- replies[i] = redisCommand(c, "INCRBY incrkey %d", 1000000);
- assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx INCRBY: %.3fs)\n", num, (t2-t1)/1000000.0);
-
- num = 10000;
- replies = malloc(sizeof(redisReply*)*num);
- for (i = 0; i < num; i++)
- redisAppendCommand(c,"PING");
- t1 = usec();
- for (i = 0; i < num; i++) {
- assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK);
- assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx PING (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
-
- replies = malloc(sizeof(redisReply*)*num);
- for (i = 0; i < num; i++)
- redisAppendCommand(c,"LRANGE mylist 0 499");
- t1 = usec();
- for (i = 0; i < num; i++) {
- assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK);
- assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY);
- assert(replies[i] != NULL && replies[i]->elements == 500);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
-
- replies = malloc(sizeof(redisReply*)*num);
- for (i = 0; i < num; i++)
- redisAppendCommand(c,"INCRBY incrkey %d", 1000000);
- t1 = usec();
- for (i = 0; i < num; i++) {
- assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK);
- assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER);
- }
- t2 = usec();
- for (i = 0; i < num; i++) freeReplyObject(replies[i]);
- free(replies);
- printf("\t(%dx INCRBY (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
-
- disconnect(c, 0);
-}
-
-// static long __test_callback_flags = 0;
-// static void __test_callback(redisContext *c, void *privdata) {
-// ((void)c);
-// /* Shift to detect execution order */
-// __test_callback_flags <<= 8;
-// __test_callback_flags |= (long)privdata;
-// }
-//
-// static void __test_reply_callback(redisContext *c, redisReply *reply, void *privdata) {
-// ((void)c);
-// /* Shift to detect execution order */
-// __test_callback_flags <<= 8;
-// __test_callback_flags |= (long)privdata;
-// if (reply) freeReplyObject(reply);
-// }
-//
-// static redisContext *__connect_nonblock() {
-// /* Reset callback flags */
-// __test_callback_flags = 0;
-// return redisConnectNonBlock("127.0.0.1", port, NULL);
-// }
-//
-// static void test_nonblocking_connection() {
-// redisContext *c;
-// int wdone = 0;
-//
-// test("Calls command callback when command is issued: ");
-// c = __connect_nonblock();
-// redisSetCommandCallback(c,__test_callback,(void*)1);
-// redisCommand(c,"PING");
-// test_cond(__test_callback_flags == 1);
-// redisFree(c);
-//
-// test("Calls disconnect callback on redisDisconnect: ");
-// c = __connect_nonblock();
-// redisSetDisconnectCallback(c,__test_callback,(void*)2);
-// redisDisconnect(c);
-// test_cond(__test_callback_flags == 2);
-// redisFree(c);
-//
-// test("Calls disconnect callback and free callback on redisFree: ");
-// c = __connect_nonblock();
-// redisSetDisconnectCallback(c,__test_callback,(void*)2);
-// redisSetFreeCallback(c,__test_callback,(void*)4);
-// redisFree(c);
-// test_cond(__test_callback_flags == ((2 << 8) | 4));
-//
-// test("redisBufferWrite against empty write buffer: ");
-// c = __connect_nonblock();
-// test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1);
-// redisFree(c);
-//
-// test("redisBufferWrite against not yet connected fd: ");
-// c = __connect_nonblock();
-// redisCommand(c,"PING");
-// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
-// strncmp(c->error,"write:",6) == 0);
-// redisFree(c);
-//
-// test("redisBufferWrite against closed fd: ");
-// c = __connect_nonblock();
-// redisCommand(c,"PING");
-// redisDisconnect(c);
-// test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
-// strncmp(c->error,"write:",6) == 0);
-// redisFree(c);
-//
-// test("Process callbacks in the right sequence: ");
-// c = __connect_nonblock();
-// redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING");
-// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
-// redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING");
-//
-// /* Write output buffer */
-// wdone = 0;
-// while(!wdone) {
-// usleep(500);
-// redisBufferWrite(c,&wdone);
-// }
-//
-// /* Read until at least one callback is executed (the 3 replies will
-// * arrive in a single packet, causing all callbacks to be executed in
-// * a single pass). */
-// while(__test_callback_flags == 0) {
-// assert(redisBufferRead(c) == REDIS_OK);
-// redisProcessCallbacks(c);
-// }
-// test_cond(__test_callback_flags == 0x010203);
-// redisFree(c);
-//
-// test("redisDisconnect executes pending callbacks with NULL reply: ");
-// c = __connect_nonblock();
-// redisSetDisconnectCallback(c,__test_callback,(void*)1);
-// redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
-// redisDisconnect(c);
-// test_cond(__test_callback_flags == 0x0201);
-// redisFree(c);
-// }
-
-int main(int argc, char **argv) {
- struct config cfg = {
- .tcp = {
- .host = "127.0.0.1",
- .port = 6379
- },
- .unix_sock = {
- .path = "/tmp/redis.sock"
- }
- };
- int throughput = 1;
- int test_inherit_fd = 1;
-
- /* Ignore broken pipe signal (for I/O error tests). */
- signal(SIGPIPE, SIG_IGN);
-
- /* Parse command line options. */
- argv++; argc--;
- while (argc) {
- if (argc >= 2 && !strcmp(argv[0],"-h")) {
- argv++; argc--;
- cfg.tcp.host = argv[0];
- } else if (argc >= 2 && !strcmp(argv[0],"-p")) {
- argv++; argc--;
- cfg.tcp.port = atoi(argv[0]);
- } else if (argc >= 2 && !strcmp(argv[0],"-s")) {
- argv++; argc--;
- cfg.unix_sock.path = argv[0];
- } else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) {
- throughput = 0;
- } else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) {
- test_inherit_fd = 0;
-#ifdef HIREDIS_TEST_SSL
- } else if (argc >= 2 && !strcmp(argv[0],"--ssl-port")) {
- argv++; argc--;
- cfg.ssl.port = atoi(argv[0]);
- } else if (argc >= 2 && !strcmp(argv[0],"--ssl-host")) {
- argv++; argc--;
- cfg.ssl.host = argv[0];
- } else if (argc >= 2 && !strcmp(argv[0],"--ssl-ca-cert")) {
- argv++; argc--;
- cfg.ssl.ca_cert = argv[0];
- } else if (argc >= 2 && !strcmp(argv[0],"--ssl-cert")) {
- argv++; argc--;
- cfg.ssl.cert = argv[0];
- } else if (argc >= 2 && !strcmp(argv[0],"--ssl-key")) {
- argv++; argc--;
- cfg.ssl.key = argv[0];
-#endif
- } else {
- fprintf(stderr, "Invalid argument: %s\n", argv[0]);
- exit(1);
- }
- argv++; argc--;
- }
-
- test_format_commands();
- test_reply_reader();
- test_blocking_connection_errors();
- test_free_null();
-
- printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port);
- cfg.type = CONN_TCP;
- test_blocking_connection(cfg);
- test_blocking_connection_timeouts(cfg);
- test_blocking_io_errors(cfg);
- test_invalid_timeout_errors(cfg);
- test_append_formatted_commands(cfg);
- if (throughput) test_throughput(cfg);
-
- printf("\nTesting against Unix socket connection (%s):\n", cfg.unix_sock.path);
- cfg.type = CONN_UNIX;
- test_blocking_connection(cfg);
- test_blocking_connection_timeouts(cfg);
- test_blocking_io_errors(cfg);
- if (throughput) test_throughput(cfg);
-
-#ifdef HIREDIS_TEST_SSL
- if (cfg.ssl.port && cfg.ssl.host) {
- printf("\nTesting against SSL connection (%s:%d):\n", cfg.ssl.host, cfg.ssl.port);
- cfg.type = CONN_SSL;
-
- test_blocking_connection(cfg);
- test_blocking_connection_timeouts(cfg);
- test_blocking_io_errors(cfg);
- test_invalid_timeout_errors(cfg);
- test_append_formatted_commands(cfg);
- if (throughput) test_throughput(cfg);
- }
-#endif
-
- if (test_inherit_fd) {
- printf("\nTesting against inherited fd (%s):\n", cfg.unix_sock.path);
- cfg.type = CONN_FD;
- test_blocking_connection(cfg);
- }
-
-
- if (fails) {
- printf("*** %d TESTS FAILED ***\n", fails);
- return 1;
- }
-
- printf("ALL TESTS PASSED\n");
- return 0;
-}
diff --git a/deps/hiredis/test.sh b/deps/hiredis/test.sh
deleted file mode 100755
index 2cab9e6fb..000000000
--- a/deps/hiredis/test.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh -ue
-
-REDIS_SERVER=${REDIS_SERVER:-redis-server}
-REDIS_PORT=${REDIS_PORT:-56379}
-REDIS_SSL_PORT=${REDIS_SSL_PORT:-56443}
-TEST_SSL=${TEST_SSL:-0}
-SSL_TEST_ARGS=
-
-tmpdir=$(mktemp -d)
-PID_FILE=${tmpdir}/hiredis-test-redis.pid
-SOCK_FILE=${tmpdir}/hiredis-test-redis.sock
-
-if [ "$TEST_SSL" = "1" ]; then
- SSL_CA_CERT=${tmpdir}/ca.crt
- SSL_CA_KEY=${tmpdir}/ca.key
- SSL_CERT=${tmpdir}/redis.crt
- SSL_KEY=${tmpdir}/redis.key
-
- openssl genrsa -out ${tmpdir}/ca.key 4096
- openssl req \
- -x509 -new -nodes -sha256 \
- -key ${SSL_CA_KEY} \
- -days 3650 \
- -subj '/CN=Hiredis Test CA' \
- -out ${SSL_CA_CERT}
- openssl genrsa -out ${SSL_KEY} 2048
- openssl req \
- -new -sha256 \
- -key ${SSL_KEY} \
- -subj '/CN=Hiredis Test Cert' | \
- openssl x509 \
- -req -sha256 \
- -CA ${SSL_CA_CERT} \
- -CAkey ${SSL_CA_KEY} \
- -CAserial ${tmpdir}/ca.txt \
- -CAcreateserial \
- -days 365 \
- -out ${SSL_CERT}
-
- SSL_TEST_ARGS="--ssl-host 127.0.0.1 --ssl-port ${REDIS_SSL_PORT} --ssl-ca-cert ${SSL_CA_CERT} --ssl-cert ${SSL_CERT} --ssl-key ${SSL_KEY}"
-fi
-
-cleanup() {
- set +e
- kill $(cat ${PID_FILE})
- rm -rf ${tmpdir}
-}
-trap cleanup INT TERM EXIT
-
-cat > ${tmpdir}/redis.conf <<EOF
-daemonize yes
-pidfile ${PID_FILE}
-port ${REDIS_PORT}
-bind 127.0.0.1
-unixsocket ${SOCK_FILE}
-EOF
-
-if [ "$TEST_SSL" = "1" ]; then
- cat >> ${tmpdir}/redis.conf <<EOF
-tls-port ${REDIS_SSL_PORT}
-tls-ca-cert-file ${SSL_CA_CERT}
-tls-cert-file ${SSL_CERT}
-tls-key-file ${SSL_KEY}
-EOF
-fi
-
-cat ${tmpdir}/redis.conf
-${REDIS_SERVER} ${tmpdir}/redis.conf
-
-${TEST_PREFIX:-} ./hiredis-test -h 127.0.0.1 -p ${REDIS_PORT} -s ${SOCK_FILE} ${SSL_TEST_ARGS}
diff --git a/deps/hiredis/win32.h b/deps/hiredis/win32.h
deleted file mode 100644
index 04289c696..000000000
--- a/deps/hiredis/win32.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef _WIN32_HELPER_INCLUDE
-#define _WIN32_HELPER_INCLUDE
-#ifdef _MSC_VER
-
-#include <winsock2.h> /* for struct timeval */
-
-#ifndef inline
-#define inline __inline
-#endif
-
-#ifndef strcasecmp
-#define strcasecmp stricmp
-#endif
-
-#ifndef strncasecmp
-#define strncasecmp strnicmp
-#endif
-
-#ifndef va_copy
-#define va_copy(d,s) ((d) = (s))
-#endif
-
-#ifndef snprintf
-#define snprintf c99_snprintf
-
-__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
-{
- int count = -1;
-
- if (size != 0)
- count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
- if (count == -1)
- count = _vscprintf(format, ap);
-
- return count;
-}
-
-__inline int c99_snprintf(char* str, size_t size, const char* format, ...)
-{
- int count;
- va_list ap;
-
- va_start(ap, format);
- count = c99_vsnprintf(str, size, format, ap);
- va_end(ap);
-
- return count;
-}
-#endif
-#endif /* _MSC_VER */
-
-#ifdef _WIN32
-#define strerror_r(errno,buf,len) strerror_s(buf,len,errno)
-#endif /* _WIN32 */
-
-#endif /* _WIN32_HELPER_INCLUDE */