Hi,
I had a bit of trouble compiling memcached for windows using mingw32
(and some issues remain) but I want to share the results in case
somebody else struggles with this. I used the following toolchain
gnuwin32 diff 2.8.7-1
gnuwin32 patch 2.5.9-7
mingw32 w32api 3.13
mingw32 mingwrt 3.15.2
mingw32 gcc-core 3.4.5-20060117-3
mingw32 binutils 2.19-2
Host operating system was Windows Server 2003.
I used memcached 1.2.1 with libevent 1.4.9 and the following patches
from [1] to get basic Windows support. To get it compiling with
mingw32 I had to add the following patch
--( memcached-03-mingw.diff )--
diff -ruN mc1/Win32-Code/win32.c mc2/Win32-Code/win32.c
--- mc1/Win32-Code/win32.c 2009-03-07 20:29:08.065250000 +0100
+++ mc2/Win32-Code/win32.c 2009-03-07 20:30:48.330875000 +0100
@@ -174,3 +174,88 @@
addr->s_addr = htonl(val);
return (1);
}
+
+int inet_pton(int af, register const char *cp, struct in_addr *addr)
+{
+ if(af != AF_INET) {
+ WSASetLastError(WSAEPFNOSUPPORT);
+ return -1;
+ }
+ return inet_aton(cp, addr);
+}
+
+size_t write(int s, void *buf, size_t len)
+{
+ DWORD dwBufferCount = 0;
+ WSABUF wsabuf = { len, (char *)buf} ;
+ if(WSASend(s, &wsabuf, 1, &dwBufferCount, 0, NULL, NULL) == 0) {
+ return dwBufferCount;
+ }
+ if(WSAGetLastError() == WSAECONNRESET) return 0;
+ return -1;
+}
+
+size_t read(int s, void *buf, size_t len)
+{
+ DWORD flags = 0;
+ DWORD dwBufferCount;
+ WSABUF wsabuf = { len, (char *)buf };
+ if(WSARecv((SOCKET)s,
+ &wsabuf,
+ 1,
+ &dwBufferCount,
+ &flags,
+ NULL,
+ NULL
+ ) == 0) {
+ return dwBufferCount;
+ }
+ if(WSAGetLastError() == WSAECONNRESET) return 0;
+ return -1;
+}
+
+int sendmsg(int s, const struct msghdr *msg, int flags)
+{
+ DWORD dwBufferCount;
+ if(WSASendTo((SOCKET) s,
+ (LPWSABUF)msg->msg_iov,
+ (DWORD)msg->msg_iovlen,
+ &dwBufferCount,
+ flags,
+ msg->msg_name,
+ msg->msg_namelen,
+ NULL,
+ NULL
+ ) == 0) {
+ return dwBufferCount;
+ }
+ if(WSAGetLastError() == WSAECONNRESET) return 0;
+ return -1;
+}
+
+int werrno()
+{
+ int error = WSAGetLastError();
+ if(error == 0) error = *_errno();
+
+ switch(error) {
+ default:
+ return error;
+ case WSAEPFNOSUPPORT:
+ //_set_errno(EAFNOSUPPORT);
+ return EAFNOSUPPORT;
+ case WSA_IO_PENDING:
+ case WSATRY_AGAIN:
+ //_set_errno(EAGAIN);
+ return EAGAIN;
+ case WSAEWOULDBLOCK:
+ //_set_errno(EWOULDBLOCK);
+ return EWOULDBLOCK;
+ case WSAEMSGSIZE:
+ //_set_errno(E2BIG);
+ return E2BIG;
+ case WSAECONNRESET:
+ //_set_errno(0);
+ return 0;
+ }
+}
diff -ruN mc1/Win32-Code/win32.h mc2/Win32-Code/win32.h
--- mc1/Win32-Code/win32.h 2009-03-07 20:29:08.065250000 +0100
+++ mc2/Win32-Code/win32.h 2009-03-07 20:31:39.252750000 +0100
@@ -18,7 +18,7 @@
typedef unsigned int uint32_t;
typedef short int16_t;
typedef unsigned short uint16_t;
-typedef char int8_t;
+//typedef char int8_t;
typedef unsigned char uint8_t;
#define inline __inline
#endif // _WIN32 && _MSC_VER
@@ -53,91 +53,13 @@
#define close(s) closesocket(s)
-inline int inet_pton(int af, register const char *cp, struct in_addr
*addr)
-{
- if(af != AF_INET) {
- WSASetLastError(WSAEPFNOSUPPORT);
- return -1;
- }
- return inet_aton(cp, addr);
-}
-
-inline size_t write(int s, void *buf, size_t len)
-{
- DWORD dwBufferCount = 0;
- WSABUF wsabuf = { len, (char *)buf} ;
- if(WSASend(s, &wsabuf, 1, &dwBufferCount, 0, NULL, NULL) == 0) {
- return dwBufferCount;
- }
- if(WSAGetLastError() == WSAECONNRESET) return 0;
- return -1;
-}
-
-inline size_t read(int s, void *buf, size_t len)
-{
- DWORD flags = 0;
- DWORD dwBufferCount;
- WSABUF wsabuf = { len, (char *)buf };
- if(WSARecv((SOCKET)s,
- &wsabuf,
- 1,
- &dwBufferCount,
- &flags,
- NULL,
- NULL
- ) == 0) {
- return dwBufferCount;
- }
- if(WSAGetLastError() == WSAECONNRESET) return 0;
- return -1;
-}
-
-inline int sendmsg(int s, const struct msghdr *msg, int flags)
-{
- DWORD dwBufferCount;
- if(WSASendTo((SOCKET) s,
- (LPWSABUF)msg->msg_iov,
- (DWORD)msg->msg_iovlen,
- &dwBufferCount,
- flags,
- msg->msg_name,
- msg->msg_namelen,
- NULL,
- NULL
- ) == 0) {
- return dwBufferCount;
- }
- if(WSAGetLastError() == WSAECONNRESET) return 0;
- return -1;
-}
-
#undef errno
#define errno werrno()
-inline int werrno()
-{
- int error = WSAGetLastError();
- if(error == 0) error = *_errno();
- switch(error) {
- default:
- return error;
- case WSAEPFNOSUPPORT:
- _set_errno(EAFNOSUPPORT);
- return EAFNOSUPPORT;
- case WSA_IO_PENDING:
- case WSATRY_AGAIN:
- _set_errno(EAGAIN);
- return EAGAIN;
- case WSAEWOULDBLOCK:
- _set_errno(EWOULDBLOCK);
- return EWOULDBLOCK;
- case WSAEMSGSIZE:
- _set_errno(E2BIG);
- return E2BIG;
- case WSAECONNRESET:
- _set_errno(0);
- return 0;
- }
-}
+int inet_pton(int af, register const char *cp, struct in_addr *addr);
+size_t write(int s, void *buf, size_t len);
+size_t read(int s, void *buf, size_t len);
+int sendmsg(int s, const struct msghdr *msg, int flags);
+int werrno();
#endif
--
As I said some issues remain and I hope you can help me resolve them:
--( slabs.c )--
memcached\slabs.c: In function `slabs_alloc':
memcached\slabs.c:218: warning: use of cast expressions as lvalues is
deprecated
--
The warning above should be easy to fix but i have no idea how to get
_set_errno working with mingw32. I read a couple of threads on the
internets about it (with solutions consisting mainly of magic like
[2]) but I hope there's an easier way of doing it
--( _set_errno )--
memcached\Win32-Code\win32.c-object:win32.c:(.text+0x583): undefined
reference to `_set_errno'
memcached\Win32-Code\win32.c-object:win32.c:(.text+0x598): undefined
reference to `_set_errno'
memcached\Win32-Code\win32.c-object:win32.c:(.text+0x5ad): undefined
reference to `_set_errno'
memcached\Win32-Code\win32.c-object:win32.c:(.text+0x5c2): undefined
reference to `_set_errno'
memcached\Win32-Code\win32.c-object:win32.c:(.text+0x5d7): undefined
reference to `_set_errno'
collect2: ld returned 1 exit status
--
Hope somebody of you has an idea :-)
PeterM
[1] http://jehiah.cz/projects/memcached-win32/
[2]
http://lists-archives.org/mingw-users/09521-_get_errno-and-_set_errno-missing-but-how-do-i-add-them.html