Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
ca153fa4
Unverified
Commit
ca153fa4
authored
Apr 02, 2019
by
Mark Nunberg
Committed by
GitHub
Apr 02, 2019
Browse files
Merge pull request #652 from mbitsnbites/mingw-support
Add MinGW support
parents
1c43a382
e38cd755
Changes
9
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
ca153fa4
CMAKE_MINIMUM_REQUIRED
(
VERSION 3.
0
.0
)
CMAKE_MINIMUM_REQUIRED
(
VERSION 3.
4
.0
)
INCLUDE
(
GNUInstallDirs
)
INCLUDE
(
GNUInstallDirs
)
PROJECT
(
hiredis
)
PROJECT
(
hiredis
)
...
@@ -22,8 +22,6 @@ PROJECT(hiredis VERSION "${VERSION}")
...
@@ -22,8 +22,6 @@ PROJECT(hiredis VERSION "${VERSION}")
SET
(
ENABLE_EXAMPLES OFF CACHE BOOL
"Enable building hiredis examples"
)
SET
(
ENABLE_EXAMPLES OFF CACHE BOOL
"Enable building hiredis examples"
)
INCLUDE_DIRECTORIES
(
${
PROJECT_SOURCE_DIR
}
)
ADD_LIBRARY
(
hiredis SHARED
ADD_LIBRARY
(
hiredis SHARED
async.c
async.c
dict.c
dict.c
...
@@ -31,11 +29,16 @@ ADD_LIBRARY(hiredis SHARED
...
@@ -31,11 +29,16 @@ ADD_LIBRARY(hiredis SHARED
net.c
net.c
read.c
read.c
sds.c
sds.c
sockcompat.c
sslio.c
)
sslio.c
)
SET_TARGET_PROPERTIES
(
hiredis
SET_TARGET_PROPERTIES
(
hiredis
PROPERTIES
PROPERTIES
VERSION
"
${
HIREDIS_SONAME
}
"
)
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
)
CONFIGURE_FILE
(
hiredis.pc.in hiredis.pc @ONLY
)
...
@@ -55,18 +58,18 @@ IF(HIREDIS_SSL)
...
@@ -55,18 +58,18 @@ IF(HIREDIS_SSL)
ENDIF
()
ENDIF
()
ENDIF
()
ENDIF
()
FIND_PACKAGE
(
OpenSSL REQUIRED
)
FIND_PACKAGE
(
OpenSSL REQUIRED
)
ADD_DEFINITIONS
(
-D
HIREDIS_SSL
)
TARGET_COMPILE_DEFINITIONS
(
hiredis PRIVATE
HIREDIS_SSL
)
INCLUDE_DIRECTORIES
(
"
${
OPENSSL_INCLUDE_DIR
}
"
)
TARGET_
INCLUDE_DIRECTORIES
(
hiredis PRIVATE
"
${
OPENSSL_INCLUDE_DIR
}
"
)
TARGET_LINK_LIBRARIES
(
hiredis
${
OPENSSL_LIBRARIES
}
)
TARGET_LINK_LIBRARIES
(
hiredis
PRIVATE
${
OPENSSL_LIBRARIES
}
)
ENDIF
()
ENDIF
()
ENABLE_TEST
ING
(
)
IF
(
NOT
(
WIN32 OR M
ING
W
)
)
ADD_EXECUTABLE
(
hiredis-test test.c
)
ENABLE_TESTING
(
)
ADD_EXECUTABLE
(
hiredis-test test.c
)
TARGET_LINK_LIBRARIES
(
hiredis-test hiredis
)
TARGET_LINK_LIBRARIES
(
hiredis-test
hiredis
)
ADD_TEST
(
NAME
hiredis-test
ADD_TEST
(
NAME hiredis-test
COMMAND
${
CMAKE_CURRENT_SOURCE_DIR
}
/test.sh
)
COMMAND
${
CMAKE_CURRENT_SOURCE_DIR
}
/test.sh
)
ENDIF
(
)
# Add examples
# Add examples
IF
(
ENABLE_EXAMPLES
)
IF
(
ENABLE_EXAMPLES
)
...
...
Makefile
View file @
ca153fa4
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
# Copyright (C) 2010-2011 Pieter Noordhuis <pcnoordhuis 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
# This file is released under the BSD license, see the COPYING file
OBJ
=
net.o hiredis.o sds.o async.o read.o sslio.o
OBJ
=
net.o hiredis.o sds.o async.o read.o
sockcompat.o
sslio.o
EXAMPLES
=
hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
\
EXAMPLES
=
hiredis-example hiredis-example-libevent hiredis-example-libev hiredis-example-glib
\
hiredis-example-ssl hiredis-example-libevent-ssl
hiredis-example-ssl hiredis-example-libevent-ssl
TESTS
=
hiredis-test
TESTS
=
hiredis-test
...
@@ -87,10 +87,11 @@ all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME)
...
@@ -87,10 +87,11 @@ all: $(DYLIBNAME) $(STLIBNAME) hiredis-test $(PKGCONFNAME)
# Deps (use make dep to generate this)
# 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
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
dict.o
:
dict.c fmacros.h dict.h
hiredis.o
:
hiredis.c fmacros.h hiredis.h read.h sds.h net.h sslio.h
hiredis.o
:
hiredis.c fmacros.h hiredis.h read.h sds.h net.h sslio.h
win32.h
net.o
:
net.c fmacros.h net.h hiredis.h read.h sds.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
read.o
:
read.c fmacros.h read.h sds.h
sds.o
:
sds.c sds.h
sds.o
:
sds.c sds.h
sockcompat.o
:
sockcompat.c sockcompat.h
sslio.o
:
sslio.c sslio.h hiredis.h
sslio.o
:
sslio.c sslio.h hiredis.h
test.o
:
test.c fmacros.h hiredis.h read.h sds.h
test.o
:
test.c fmacros.h hiredis.h read.h sds.h
...
...
hiredis.c
View file @
ca153fa4
...
@@ -34,7 +34,6 @@
...
@@ -34,7 +34,6 @@
#include "fmacros.h"
#include "fmacros.h"
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <assert.h>
#include <errno.h>
#include <errno.h>
#include <ctype.h>
#include <ctype.h>
...
@@ -43,6 +42,7 @@
...
@@ -43,6 +42,7 @@
#include "net.h"
#include "net.h"
#include "sds.h"
#include "sds.h"
#include "sslio.h"
#include "sslio.h"
#include "win32.h"
static
redisReply
*
createReplyObject
(
int
type
);
static
redisReply
*
createReplyObject
(
int
type
);
static
void
*
createStringObject
(
const
redisReadTask
*
task
,
char
*
str
,
size_t
len
);
static
void
*
createStringObject
(
const
redisReadTask
*
task
,
char
*
str
,
size_t
len
);
...
@@ -605,8 +605,7 @@ static redisContext *redisContextInit(const redisOptions *options) {
...
@@ -605,8 +605,7 @@ static redisContext *redisContextInit(const redisOptions *options) {
void
redisFree
(
redisContext
*
c
)
{
void
redisFree
(
redisContext
*
c
)
{
if
(
c
==
NULL
)
if
(
c
==
NULL
)
return
;
return
;
if
(
c
->
fd
>
0
)
redisNetClose
(
c
);
close
(
c
->
fd
);
sdsfree
(
c
->
obuf
);
sdsfree
(
c
->
obuf
);
redisReaderFree
(
c
->
reader
);
redisReaderFree
(
c
->
reader
);
...
@@ -622,9 +621,9 @@ void redisFree(redisContext *c) {
...
@@ -622,9 +621,9 @@ void redisFree(redisContext *c) {
free
(
c
);
free
(
c
);
}
}
int
redisFreeKeepFd
(
redisContext
*
c
)
{
redisFD
redisFreeKeepFd
(
redisContext
*
c
)
{
int
fd
=
c
->
fd
;
redisFD
fd
=
c
->
fd
;
c
->
fd
=
-
1
;
c
->
fd
=
REDIS_INVALID_FD
;
redisFree
(
c
);
redisFree
(
c
);
return
fd
;
return
fd
;
}
}
...
@@ -633,9 +632,7 @@ int redisReconnect(redisContext *c) {
...
@@ -633,9 +632,7 @@ int redisReconnect(redisContext *c) {
c
->
err
=
0
;
c
->
err
=
0
;
memset
(
c
->
errstr
,
'\0'
,
strlen
(
c
->
errstr
));
memset
(
c
->
errstr
,
'\0'
,
strlen
(
c
->
errstr
));
if
(
c
->
fd
>
0
)
{
redisNetClose
(
c
);
close
(
c
->
fd
);
}
sdsfree
(
c
->
obuf
);
sdsfree
(
c
->
obuf
);
redisReaderFree
(
c
->
reader
);
redisReaderFree
(
c
->
reader
);
...
@@ -750,7 +747,7 @@ redisContext *redisConnectUnixNonBlock(const char *path) {
...
@@ -750,7 +747,7 @@ redisContext *redisConnectUnixNonBlock(const char *path) {
return
redisConnectWithOptions
(
&
options
);
return
redisConnectWithOptions
(
&
options
);
}
}
redisContext
*
redisConnectFd
(
int
fd
)
{
redisContext
*
redisConnectFd
(
redisFD
fd
)
{
redisOptions
options
=
{
0
};
redisOptions
options
=
{
0
};
options
.
type
=
REDIS_CONN_USERFD
;
options
.
type
=
REDIS_CONN_USERFD
;
options
.
endpoint
.
fd
=
fd
;
options
.
endpoint
.
fd
=
fd
;
...
@@ -776,24 +773,6 @@ int redisEnableKeepAlive(redisContext *c) {
...
@@ -776,24 +773,6 @@ int redisEnableKeepAlive(redisContext *c) {
return
REDIS_OK
;
return
REDIS_OK
;
}
}
static
int
rawRead
(
redisContext
*
c
,
char
*
buf
,
size_t
bufcap
)
{
int
nread
=
read
(
c
->
fd
,
buf
,
bufcap
);
if
(
nread
==
-
1
)
{
if
((
errno
==
EAGAIN
&&
!
(
c
->
flags
&
REDIS_BLOCK
))
||
(
errno
==
EINTR
))
{
/* Try again later */
return
0
;
}
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
;
}
}
/* Use this function to handle a read event on the descriptor. It will try
/* 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.
* and read some bytes from the socket and feed them to the reply parser.
*
*
...
@@ -808,7 +787,7 @@ int redisBufferRead(redisContext *c) {
...
@@ -808,7 +787,7 @@ int redisBufferRead(redisContext *c) {
return
REDIS_ERR
;
return
REDIS_ERR
;
nread
=
c
->
flags
&
REDIS_SSL
?
nread
=
c
->
flags
&
REDIS_SSL
?
redisSslRead
(
c
,
buf
,
sizeof
(
buf
))
:
r
aw
Read
(
c
,
buf
,
sizeof
(
buf
));
redisSslRead
(
c
,
buf
,
sizeof
(
buf
))
:
r
edisNet
Read
(
c
,
buf
,
sizeof
(
buf
));
if
(
nread
>
0
)
{
if
(
nread
>
0
)
{
if
(
redisReaderFeed
(
c
->
reader
,
buf
,
nread
)
!=
REDIS_OK
)
{
if
(
redisReaderFeed
(
c
->
reader
,
buf
,
nread
)
!=
REDIS_OK
)
{
__redisSetError
(
c
,
c
->
reader
->
err
,
c
->
reader
->
errstr
);
__redisSetError
(
c
,
c
->
reader
->
err
,
c
->
reader
->
errstr
);
...
@@ -821,19 +800,6 @@ int redisBufferRead(redisContext *c) {
...
@@ -821,19 +800,6 @@ int redisBufferRead(redisContext *c) {
return
REDIS_OK
;
return
REDIS_OK
;
}
}
static
int
rawWrite
(
redisContext
*
c
)
{
int
nwritten
=
write
(
c
->
fd
,
c
->
obuf
,
sdslen
(
c
->
obuf
));
if
(
nwritten
<
0
)
{
if
((
errno
==
EAGAIN
&&
!
(
c
->
flags
&
REDIS_BLOCK
))
||
(
errno
==
EINTR
))
{
/* Try again later */
}
else
{
__redisSetError
(
c
,
REDIS_ERR_IO
,
NULL
);
return
-
1
;
}
}
return
nwritten
;
}
/* Write the output buffer to the socket.
/* Write the output buffer to the socket.
*
*
* Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
* Returns REDIS_OK when the buffer is empty, or (a part of) the buffer was
...
@@ -850,7 +816,7 @@ int redisBufferWrite(redisContext *c, int *done) {
...
@@ -850,7 +816,7 @@ int redisBufferWrite(redisContext *c, int *done) {
return
REDIS_ERR
;
return
REDIS_ERR
;
if
(
sdslen
(
c
->
obuf
)
>
0
)
{
if
(
sdslen
(
c
->
obuf
)
>
0
)
{
int
nwritten
=
(
c
->
flags
&
REDIS_SSL
)
?
redisSslWrite
(
c
)
:
r
aw
Write
(
c
);
int
nwritten
=
(
c
->
flags
&
REDIS_SSL
)
?
redisSslWrite
(
c
)
:
r
edisNet
Write
(
c
);
if
(
nwritten
<
0
)
{
if
(
nwritten
<
0
)
{
return
REDIS_ERR
;
return
REDIS_ERR
;
}
else
if
(
nwritten
>
0
)
{
}
else
if
(
nwritten
>
0
)
{
...
...
hiredis.h
View file @
ca153fa4
...
@@ -133,6 +133,22 @@ struct redisSsl;
...
@@ -133,6 +133,22 @@ struct redisSsl;
*/
*/
#define REDIS_OPT_NOAUTOFREE 0x04
#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
{
typedef
struct
{
/*
/*
* the type of connection to use. This also indicates which
* the type of connection to use. This also indicates which
...
@@ -155,7 +171,7 @@ typedef struct {
...
@@ -155,7 +171,7 @@ typedef struct {
/**
/**
* use this field to have hiredis operate an already-open
* use this field to have hiredis operate an already-open
* file descriptor */
* file descriptor */
int
fd
;
redisFD
fd
;
}
endpoint
;
}
endpoint
;
}
redisOptions
;
}
redisOptions
;
...
@@ -175,7 +191,7 @@ typedef struct {
...
@@ -175,7 +191,7 @@ typedef struct {
typedef
struct
redisContext
{
typedef
struct
redisContext
{
int
err
;
/* Error flags, 0 when there is no error */
int
err
;
/* Error flags, 0 when there is no error */
char
errstr
[
128
];
/* String representation of error when applicable */
char
errstr
[
128
];
/* String representation of error when applicable */
int
fd
;
redisFD
fd
;
int
flags
;
int
flags
;
char
*
obuf
;
/* Write buffer */
char
*
obuf
;
/* Write buffer */
redisReader
*
reader
;
/* Protocol reader */
redisReader
*
reader
;
/* Protocol reader */
...
@@ -212,7 +228,7 @@ redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
...
@@ -212,7 +228,7 @@ redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
redisContext
*
redisConnectUnix
(
const
char
*
path
);
redisContext
*
redisConnectUnix
(
const
char
*
path
);
redisContext
*
redisConnectUnixWithTimeout
(
const
char
*
path
,
const
struct
timeval
tv
);
redisContext
*
redisConnectUnixWithTimeout
(
const
char
*
path
,
const
struct
timeval
tv
);
redisContext
*
redisConnectUnixNonBlock
(
const
char
*
path
);
redisContext
*
redisConnectUnixNonBlock
(
const
char
*
path
);
redisContext
*
redisConnectFd
(
int
fd
);
redisContext
*
redisConnectFd
(
redisFD
fd
);
/**
/**
* Secure the connection using SSL. This should be done before any command is
* Secure the connection using SSL. This should be done before any command is
...
@@ -235,7 +251,7 @@ int redisReconnect(redisContext *c);
...
@@ -235,7 +251,7 @@ int redisReconnect(redisContext *c);
int
redisSetTimeout
(
redisContext
*
c
,
const
struct
timeval
tv
);
int
redisSetTimeout
(
redisContext
*
c
,
const
struct
timeval
tv
);
int
redisEnableKeepAlive
(
redisContext
*
c
);
int
redisEnableKeepAlive
(
redisContext
*
c
);
void
redisFree
(
redisContext
*
c
);
void
redisFree
(
redisContext
*
c
);
int
redisFreeKeepFd
(
redisContext
*
c
);
redisFD
redisFreeKeepFd
(
redisContext
*
c
);
int
redisBufferRead
(
redisContext
*
c
);
int
redisBufferRead
(
redisContext
*
c
);
int
redisBufferWrite
(
redisContext
*
c
,
int
*
done
);
int
redisBufferWrite
(
redisContext
*
c
,
int
*
done
);
...
...
net.c
View file @
ca153fa4
...
@@ -34,36 +34,60 @@
...
@@ -34,36 +34,60 @@
#include "fmacros.h"
#include "fmacros.h"
#include <sys/types.h>
#include <sys/types.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 <unistd.h>
#include <fcntl.h>
#include <fcntl.h>
#include <string.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <errno.h>
#include <stdarg.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdio.h>
#include <poll.h>
#include <limits.h>
#include <limits.h>
#include <stdlib.h>
#include <stdlib.h>
#include "net.h"
#include "net.h"
#include "sds.h"
#include "sds.h"
#include "sockcompat.h"
#include "win32.h"
/* Defined in hiredis.c */
/* Defined in hiredis.c */
void
__redisSetError
(
redisContext
*
c
,
int
type
,
const
char
*
str
);
void
__redisSetError
(
redisContext
*
c
,
int
type
,
const
char
*
str
);
static
void
redis
Contex
tClose
Fd
(
redisContext
*
c
)
{
void
redis
Ne
tClose
(
redisContext
*
c
)
{
if
(
c
&&
c
->
fd
>
=
0
)
{
if
(
c
&&
c
->
fd
!
=
REDIS_INVALID_FD
)
{
close
(
c
->
fd
);
close
(
c
->
fd
);
c
->
fd
=
-
1
;
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
{
__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
)
{
static
void
__redisSetErrorFromErrno
(
redisContext
*
c
,
int
type
,
const
char
*
prefix
)
{
int
errorno
=
errno
;
/* snprintf() may change errno */
int
errorno
=
errno
;
/* snprintf() may change errno */
char
buf
[
128
]
=
{
0
};
char
buf
[
128
]
=
{
0
};
...
@@ -79,15 +103,15 @@ static int redisSetReuseAddr(redisContext *c) {
...
@@ -79,15 +103,15 @@ static int redisSetReuseAddr(redisContext *c) {
int
on
=
1
;
int
on
=
1
;
if
(
setsockopt
(
c
->
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
on
,
sizeof
(
on
))
==
-
1
)
{
if
(
setsockopt
(
c
->
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
on
,
sizeof
(
on
))
==
-
1
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
NULL
);
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
NULL
);
redis
Contex
tClose
Fd
(
c
);
redis
Ne
tClose
(
c
);
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
return
REDIS_OK
;
return
REDIS_OK
;
}
}
static
int
redisCreateSocket
(
redisContext
*
c
,
int
type
)
{
static
int
redisCreateSocket
(
redisContext
*
c
,
int
type
)
{
int
s
;
redisFD
s
;
if
((
s
=
socket
(
type
,
SOCK_STREAM
,
0
))
==
-
1
)
{
if
((
s
=
socket
(
type
,
SOCK_STREAM
,
0
))
==
REDIS_INVALID_FD
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
NULL
);
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
NULL
);
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
...
@@ -101,6 +125,7 @@ static int redisCreateSocket(redisContext *c, int type) {
...
@@ -101,6 +125,7 @@ static int redisCreateSocket(redisContext *c, int type) {
}
}
static
int
redisSetBlocking
(
redisContext
*
c
,
int
blocking
)
{
static
int
redisSetBlocking
(
redisContext
*
c
,
int
blocking
)
{
#ifndef _WIN32
int
flags
;
int
flags
;
/* Set the socket nonblocking.
/* Set the socket nonblocking.
...
@@ -108,7 +133,7 @@ static int redisSetBlocking(redisContext *c, int blocking) {
...
@@ -108,7 +133,7 @@ static int redisSetBlocking(redisContext *c, int blocking) {
* interrupted by a signal. */
* interrupted by a signal. */
if
((
flags
=
fcntl
(
c
->
fd
,
F_GETFL
))
==
-
1
)
{
if
((
flags
=
fcntl
(
c
->
fd
,
F_GETFL
))
==
-
1
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"fcntl(F_GETFL)"
);
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"fcntl(F_GETFL)"
);
redis
Contex
tClose
Fd
(
c
);
redis
Ne
tClose
(
c
);
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
...
@@ -119,15 +144,23 @@ static int redisSetBlocking(redisContext *c, int blocking) {
...
@@ -119,15 +144,23 @@ static int redisSetBlocking(redisContext *c, int blocking) {
if
(
fcntl
(
c
->
fd
,
F_SETFL
,
flags
)
==
-
1
)
{
if
(
fcntl
(
c
->
fd
,
F_SETFL
,
flags
)
==
-
1
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"fcntl(F_SETFL)"
);
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"fcntl(F_SETFL)"
);
redisContextCloseFd
(
c
);
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
;
return
REDIS_ERR
;
}
}
#endif
/* _WIN32 */
return
REDIS_OK
;
return
REDIS_OK
;
}
}
int
redisKeepAlive
(
redisContext
*
c
,
int
interval
)
{
int
redisKeepAlive
(
redisContext
*
c
,
int
interval
)
{
int
val
=
1
;
int
val
=
1
;
int
fd
=
c
->
fd
;
redisFD
fd
=
c
->
fd
;
if
(
setsockopt
(
fd
,
SOL_SOCKET
,
SO_KEEPALIVE
,
&
val
,
sizeof
(
val
))
==
-
1
){
if
(
setsockopt
(
fd
,
SOL_SOCKET
,
SO_KEEPALIVE
,
&
val
,
sizeof
(
val
))
==
-
1
){
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
strerror
(
errno
));
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
strerror
(
errno
));
...
@@ -170,7 +203,7 @@ static int redisSetTcpNoDelay(redisContext *c) {
...
@@ -170,7 +203,7 @@ static int redisSetTcpNoDelay(redisContext *c) {
int
yes
=
1
;
int
yes
=
1
;
if
(
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_NODELAY
,
&
yes
,
sizeof
(
yes
))
==
-
1
)
{
if
(
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_NODELAY
,
&
yes
,
sizeof
(
yes
))
==
-
1
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"setsockopt(TCP_NODELAY)"
);
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"setsockopt(TCP_NODELAY)"
);
redis
Contex
tClose
Fd
(
c
);
redis
Ne
tClose
(
c
);
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
return
REDIS_OK
;
return
REDIS_OK
;
...
@@ -212,12 +245,12 @@ static int redisContextWaitReady(redisContext *c, long msec) {
...
@@ -212,12 +245,12 @@ static int redisContextWaitReady(redisContext *c, long msec) {
if
((
res
=
poll
(
wfd
,
1
,
msec
))
==
-
1
)
{
if
((
res
=
poll
(
wfd
,
1
,
msec
))
==
-
1
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"poll(2)"
);
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"poll(2)"
);
redis
Contex
tClose
Fd
(
c
);
redis
Ne
tClose
(
c
);
return
REDIS_ERR
;
return
REDIS_ERR
;
}
else
if
(
res
==
0
)
{
}
else
if
(
res
==
0
)
{
errno
=
ETIMEDOUT
;
errno
=
ETIMEDOUT
;
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
NULL
);
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
NULL
);
redis
Contex
tClose
Fd
(
c
);
redis
Ne
tClose
(
c
);
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
...
@@ -230,7 +263,7 @@ static int redisContextWaitReady(redisContext *c, long msec) {
...
@@ -230,7 +263,7 @@ static int redisContextWaitReady(redisContext *c, long msec) {
}
}
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
NULL
);
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
NULL
);
redis
Contex
tClose
Fd
(
c
);
redis
Ne
tClose
(
c
);
return
REDIS_ERR
;
return
REDIS_ERR
;
}
}
...
@@ -291,7 +324,8 @@ int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
...
@@ -291,7 +324,8 @@ int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
static
int
_redisContextConnectTcp
(
redisContext
*
c
,
const
char
*
addr
,
int
port
,
static
int
_redisContextConnectTcp
(
redisContext
*
c
,
const
char
*
addr
,
int
port
,
const
struct
timeval
*
timeout
,
const
struct
timeval
*
timeout
,
const
char
*
source_addr
)
{
const
char
*
source_addr
)
{
int
s
,
rv
,
n
;
redisFD
s
;
int
rv
,
n
;
char
_port
[
6
];
/* strlen("65535"); */
char
_port
[
6
];
/* strlen("65535"); */
struct
addrinfo
hints
,
*
servinfo
,
*
bservinfo
,
*
p
,
*
b
;
struct
addrinfo
hints
,
*
servinfo
,
*
bservinfo
,
*
p
,
*
b
;
int
blocking
=
(
c
->
flags
&
REDIS_BLOCK
);
int
blocking
=
(
c
->
flags
&
REDIS_BLOCK
);
...
@@ -360,7 +394,7 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
...
@@ -360,7 +394,7 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
}
}
for
(
p
=
servinfo
;
p
!=
NULL
;
p
=
p
->
ai_next
)
{
for
(
p
=
servinfo
;
p
!=
NULL
;
p
=
p
->
ai_next
)
{
addrretry:
addrretry:
if
((
s
=
socket
(
p
->
ai_family
,
p
->
ai_socktype
,
p
->
ai_protocol
))
==
-
1
)
if
((
s
=
socket
(
p
->
ai_family
,
p
->
ai_socktype
,
p
->
ai_protocol
))
==
REDIS_INVALID_FD
)
continue
;
continue
;
c
->
fd
=
s
;
c
->
fd
=
s
;
...
@@ -410,7 +444,7 @@ addrretry:
...
@@ -410,7 +444,7 @@ addrretry:
if
(
connect
(
s
,
p
->
ai_addr
,
p
->
ai_addrlen
)
==
-
1
)
{
if
(
connect
(
s
,
p
->
ai_addr
,
p
->
ai_addrlen
)
==
-
1
)
{
if
(
errno
==
EHOSTUNREACH
)
{
if
(
errno
==
EHOSTUNREACH
)
{
redis
Contex
tClose
Fd
(
c
);
redis
Ne
tClose
(
c
);
continue
;
continue
;
}
else
if
(
errno
==
EINPROGRESS
)
{
}
else
if
(
errno
==
EINPROGRESS
)
{
if
(
blocking
)
{
if
(
blocking
)
{
...
@@ -424,7 +458,7 @@ addrretry:
...
@@ -424,7 +458,7 @@ addrretry:
if
(
++
reuses
>=
REDIS_CONNECT_RETRIES
)
{
if
(
++
reuses
>=
REDIS_CONNECT_RETRIES
)
{
goto
error
;
goto
error
;
}
else
{
}
else
{
redis
Contex
tClose
Fd
(
c
);
redis
Ne
tClose
(
c
);
goto
addrretry
;
goto
addrretry
;
}
}
}
else
{
}
else
{
...
@@ -471,6 +505,7 @@ int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
...
@@ -471,6 +505,7 @@ int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
}
}
int
redisContextConnectUnix
(
redisContext
*
c
,
const
char
*
path
,
const
struct
timeval
*
timeout
)
{
int
redisContextConnectUnix
(
redisContext
*
c
,
const
char
*
path
,
const
struct
timeval
*
timeout
)
{
#ifndef _WIN32
int
blocking
=
(
c
->
flags
&
REDIS_BLOCK
);
int
blocking
=
(
c
->
flags
&
REDIS_BLOCK
);
struct
sockaddr_un
*
sa
;
struct
sockaddr_un
*
sa
;
long
timeout_msec
=
-
1
;
long
timeout_msec
=
-
1
;
...
@@ -518,4 +553,10 @@ int redisContextConnectUnix(redisContext *c, const char *path, const struct time
...
@@ -518,4 +553,10 @@ int redisContextConnectUnix(redisContext *c, const char *path, const struct time
c
->
flags
|=
REDIS_CONNECTED
;
c
->
flags
|=
REDIS_CONNECTED
;
return
REDIS_OK
;
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 */
}
}
net.h
View file @
ca153fa4
...
@@ -37,6 +37,10 @@
...
@@ -37,6 +37,10 @@
#include "hiredis.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
redisCheckSocketError
(
redisContext
*
c
);
int
redisContextSetTimeout
(
redisContext
*
c
,
const
struct
timeval
tv
);
int
redisContextSetTimeout
(
redisContext
*
c
,
const
struct
timeval
tv
);
int
redisContextConnectTcp
(
redisContext
*
c
,
const
char
*
addr
,
int
port
,
const
struct
timeval
*
timeout
);
int
redisContextConnectTcp
(
redisContext
*
c
,
const
char
*
addr
,
int
port
,
const
struct
timeval
*
timeout
);
...
...
sockcompat.c
0 → 100644
View file @
ca153fa4
/*
* 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
=
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
=
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 */
sockcompat.h
0 → 100644
View file @
ca153fa4
/*
* 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>
/* 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 */
win32.h
View file @
ca153fa4
...
@@ -37,6 +37,10 @@ __inline int c99_snprintf(char* str, size_t size, const char* format, ...)
...
@@ -37,6 +37,10 @@ __inline int c99_snprintf(char* str, size_t size, const char* format, ...)
return
count
;
return
count
;
}
}
#endif
#endif
#endif
/* _MSC_VER */
#endif
#ifdef _WIN32
#endif
#define strerror_r(errno,buf,len) strerror_s(buf,len,errno)
\ No newline at end of file
#endif
/* _WIN32 */
#endif
/* _WIN32_HELPER_INCLUDE */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment