summaryrefslogtreecommitdiff
path: root/librabbitmq
diff options
context:
space:
mode:
authorDavid Wragg <dpw@lshift.net>2010-05-30 23:31:40 +0100
committerDavid Wragg <dpw@lshift.net>2010-05-30 23:31:40 +0100
commit1c198e88d1a0c74676f8d6fade99b2531ba815b8 (patch)
tree133f008278e7badb652e94535ef29b58d383fea6 /librabbitmq
parentbf06e86975f474da30e9c74faff7a99b0734e00e (diff)
downloadrabbitmq-c-github-ask-1c198e88d1a0c74676f8d6fade99b2531ba815b8.tar.gz
A Windows port, using MinGW/MSYS
Diffstat (limited to 'librabbitmq')
-rw-r--r--librabbitmq/Makefile.am8
-rw-r--r--librabbitmq/amqp_api.c6
-rw-r--r--librabbitmq/amqp_connection.c20
-rw-r--r--librabbitmq/amqp_mem.c1
-rw-r--r--librabbitmq/amqp_private.h5
-rw-r--r--librabbitmq/amqp_socket.c36
-rw-r--r--librabbitmq/amqp_table.c2
-rw-r--r--librabbitmq/codegen.py1
-rw-r--r--librabbitmq/unix/socket.c85
-rw-r--r--librabbitmq/unix/socket.h80
-rw-r--r--librabbitmq/windows/socket.c88
-rw-r--r--librabbitmq/windows/socket.h92
12 files changed, 381 insertions, 43 deletions
diff --git a/librabbitmq/Makefile.am b/librabbitmq/Makefile.am
index b4c8843..9211c8f 100644
--- a/librabbitmq/Makefile.am
+++ b/librabbitmq/Makefile.am
@@ -1,15 +1,19 @@
lib_LTLIBRARIES = librabbitmq.la
-librabbitmq_la_SOURCES = amqp_mem.c amqp_table.c amqp_connection.c amqp_socket.c amqp_debug.c amqp_api.c
+AM_CFLAGS = -I$(PLATFORM_DIR)
+librabbitmq_la_SOURCES = amqp_mem.c amqp_table.c amqp_connection.c amqp_socket.c amqp_debug.c amqp_api.c $(PLATFORM_DIR)/socket.c
+librabbitmq_la_LDFLAGS = -no-undefined
nodist_librabbitmq_la_SOURCES = amqp_framing.c
include_HEADERS = amqp_framing.h amqp.h
-noinst_HEADERS = amqp_private.h
+noinst_HEADERS = amqp_private.h $(PLATFORM_DIR)/socket.h
BUILT_SOURCES = amqp_framing.h amqp_framing.c
CLEANFILES = amqp_framing.h amqp_framing.c
EXTRA_DIST = codegen.py
CODEGEN_PY=$(srcdir)/codegen.py
+LDADD=$(EXTRA_LIBS)
+
amqp_framing.h: $(AMQP_SPEC_JSON_PATH) $(CODEGEN_PY)
PYTHONPATH=$(AMQP_CODEGEN_DIR) $(PYTHON) $(CODEGEN_PY) header $< $@
diff --git a/librabbitmq/amqp_api.c b/librabbitmq/amqp_api.c
index 3a4440f..9918819 100644
--- a/librabbitmq/amqp_api.c
+++ b/librabbitmq/amqp_api.c
@@ -52,7 +52,6 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
-#include <errno.h>
#include "amqp.h"
#include "amqp_framing.h"
@@ -85,9 +84,8 @@ const char *amqp_error_string(int err)
break;
case ERROR_CATEGORY_OS:
- str = strerror(err);
- break;
-
+ return amqp_os_error_string(err);
+
default:
str = "(undefined error category)";
}
diff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c
index a264ad3..63af96a 100644
--- a/librabbitmq/amqp_connection.c
+++ b/librabbitmq/amqp_connection.c
@@ -52,17 +52,13 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
-#include <errno.h>
-
-#include <unistd.h>
-#include <sys/uio.h>
-#include <sys/types.h>
+#include <assert.h>
#include "amqp.h"
#include "amqp_framing.h"
#include "amqp_private.h"
-#include <assert.h>
+#include "socket.h"
#define INITIAL_FRAME_POOL_PAGE_SIZE 65536
#define INITIAL_DECODING_POOL_PAGE_SIZE 131072
@@ -173,8 +169,8 @@ void amqp_destroy_connection(amqp_connection_state_t state) {
int amqp_end_connection(amqp_connection_state_t state) {
int s = state->sockfd;
amqp_destroy_connection(state);
- if (close(s) < 0)
- return -encoded_errno();
+ if (socket_close(s) < 0)
+ return -encoded_socket_errno();
else
return 0;
}
@@ -433,8 +429,8 @@ int amqp_send_frame(amqp_connection_state_t state,
res = inner_send_frame(state, frame, &encoded, &payload_len);
switch (res) {
case 0:
- res = write(state->sockfd, state->outbound_buffer.bytes,
- payload_len + (HEADER_SIZE + FOOTER_SIZE));
+ res = socket_write(state->sockfd, state->outbound_buffer.bytes,
+ payload_len + (HEADER_SIZE + FOOTER_SIZE));
break;
case 1: {
@@ -447,7 +443,7 @@ int amqp_send_frame(amqp_connection_state_t state,
iov[2].iov_base = &frame_end_byte;
assert(FOOTER_SIZE == 1);
iov[2].iov_len = FOOTER_SIZE;
- res = writev(state->sockfd, &iov[0], 3);
+ res = socket_writev(state->sockfd, &iov[0], 3);
break;
}
@@ -456,7 +452,7 @@ int amqp_send_frame(amqp_connection_state_t state,
}
if (res < 0)
- return -encoded_errno();
+ return -encoded_socket_errno();
else
return 0;
}
diff --git a/librabbitmq/amqp_mem.c b/librabbitmq/amqp_mem.c
index 7783cbb..021151a 100644
--- a/librabbitmq/amqp_mem.c
+++ b/librabbitmq/amqp_mem.c
@@ -53,7 +53,6 @@
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
-#include <errno.h>
#include <assert.h>
#include "amqp.h"
diff --git a/librabbitmq/amqp_private.h b/librabbitmq/amqp_private.h
index f922933..7206ae5 100644
--- a/librabbitmq/amqp_private.h
+++ b/librabbitmq/amqp_private.h
@@ -55,8 +55,6 @@
extern "C" {
#endif
-#include <arpa/inet.h> /* ntohl, htonl, ntohs, htons */
-
/* Error numbering: Because of differences in error numbering on
* different platforms, we want to keep error numbers opaque for
* client code. Internally, we encode the category of an error
@@ -78,8 +76,7 @@ extern "C" {
#define ERROR_CONNECTION_CLOSED 7
#define ERROR_MAX 7
-/* Get the encoded form of errno */
-#define encoded_errno() (errno | ERROR_CATEGORY_OS)
+extern const char *amqp_os_error_string(int err);
/*
* Connection states:
diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c
index 8f3f05b..6425c34 100644
--- a/librabbitmq/amqp_socket.c
+++ b/librabbitmq/amqp_socket.c
@@ -52,29 +52,27 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
-#include <errno.h>
#include <stdarg.h>
+#include <assert.h>
#include "amqp.h"
#include "amqp_framing.h"
#include "amqp_private.h"
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
+#include "socket.h"
-#include <assert.h>
int amqp_open_socket(char const *hostname,
int portnumber)
{
- int sockfd;
+ int sockfd, res;
struct sockaddr_in addr;
struct hostent *he;
+ res = socket_init();
+ if (res)
+ return res;
+
he = gethostbyname(hostname);
if (he == NULL)
return -ERROR_HOST_NOT_FOUND;
@@ -83,11 +81,11 @@ int amqp_open_socket(char const *hostname,
addr.sin_port = htons(portnumber);
addr.sin_addr.s_addr = * (uint32_t *) he->h_addr_list[0];
- sockfd = socket(PF_INET, SOCK_STREAM, 0);
- if (connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- int result = -encoded_errno();
- close(sockfd);
- return result;
+ sockfd = socket_socket(PF_INET, SOCK_STREAM, 0);
+ if (socket_connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ res = -encoded_socket_errno();
+ socket_close(sockfd);
+ return res;
}
return sockfd;
@@ -107,7 +105,7 @@ static char *header() {
}
int amqp_send_header(amqp_connection_state_t state) {
- return write(state->sockfd, header(), 8);
+ return socket_write(state->sockfd, header(), 8);
}
int amqp_send_header_to(amqp_connection_state_t state,
@@ -190,14 +188,14 @@ static int wait_frame_inner(amqp_connection_state_t state,
assert(result != 0);
}
- result = read(state->sockfd,
- state->sock_inbound_buffer.bytes,
- state->sock_inbound_buffer.len);
+ result = socket_read(state->sockfd,
+ state->sock_inbound_buffer.bytes,
+ state->sock_inbound_buffer.len);
if (result <= 0) {
if (result == 0)
return -ERROR_CONNECTION_CLOSED;
else
- return -encoded_errno();
+ return -encoded_socket_errno();
}
state->sock_inbound_limit = result;
diff --git a/librabbitmq/amqp_table.c b/librabbitmq/amqp_table.c
index db45588..3f5eb61 100644
--- a/librabbitmq/amqp_table.c
+++ b/librabbitmq/amqp_table.c
@@ -52,10 +52,10 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
-#include <errno.h>
#include "amqp.h"
#include "amqp_private.h"
+#include "socket.h"
#include <assert.h>
diff --git a/librabbitmq/codegen.py b/librabbitmq/codegen.py
index 9a82fbe..6b38666 100644
--- a/librabbitmq/codegen.py
+++ b/librabbitmq/codegen.py
@@ -265,6 +265,7 @@ def genErl(spec):
print '#include "amqp.h"'
print '#include "amqp_framing.h"'
print '#include "amqp_private.h"'
+ print '#include "socket.h"'
print """
char const *amqp_constant_name(int constantNumber) {
diff --git a/librabbitmq/unix/socket.c b/librabbitmq/unix/socket.c
new file mode 100644
index 0000000..51db413
--- /dev/null
+++ b/librabbitmq/unix/socket.c
@@ -0,0 +1,85 @@
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is librabbitmq.
+ *
+ * The Initial Developers of the Original Code are LShift Ltd, Cohesive
+ * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions
+ * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive
+ * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright
+ * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and
+ * Rabbit Technologies Ltd.
+ *
+ * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
+ * Ltd. Portions created by Cohesive Financial Technologies LLC are
+ * Copyright (C) 2007-2010 Cohesive Financial Technologies
+ * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C)
+ * 2007-2010 Rabbit Technologies Ltd.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010
+ * LShift Ltd and Tony Garnock-Jones.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): ______________________________________.
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of the GNU General Public License Version 2 or later (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of those
+ * above. If you wish to allow use of your version of this file only
+ * under the terms of the GPL, and not to allow others to use your
+ * version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the
+ * notice and other provisions required by the GPL. If you do not
+ * delete the provisions above, a recipient may use your version of
+ * this file under the terms of any one of the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "amqp.h"
+#include "amqp_private.h"
+#include "socket.h"
+
+int socket_socket(int domain, int type, int proto)
+{
+ int flags;
+
+ int s = socket(domain, type, proto);
+ if (s < 0)
+ return s;
+
+ /* Always enable CLOEXEC on the socket */
+ flags = fcntl(s, F_GETFD);
+ if (flags == -1
+ || fcntl(s, F_SETFD, (long)(flags | FD_CLOEXEC)) == -1) {
+ int e = errno;
+ close(s);
+ errno = e;
+ return -1;
+ }
+
+ return s;
+}
+
+const char *amqp_os_error_string(int err)
+{
+ return strdup(strerror(err));
+}
diff --git a/librabbitmq/unix/socket.h b/librabbitmq/unix/socket.h
new file mode 100644
index 0000000..d7295c3
--- /dev/null
+++ b/librabbitmq/unix/socket.h
@@ -0,0 +1,80 @@
+#ifndef librabbitmq_unix_socket_h
+#define librabbitmq_unix_socket_h
+
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is librabbitmq.
+ *
+ * The Initial Developers of the Original Code are LShift Ltd, Cohesive
+ * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions
+ * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive
+ * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright
+ * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and
+ * Rabbit Technologies Ltd.
+ *
+ * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
+ * Ltd. Portions created by Cohesive Financial Technologies LLC are
+ * Copyright (C) 2007-2010 Cohesive Financial Technologies
+ * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C)
+ * 2007-2010 Rabbit Technologies Ltd.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010
+ * LShift Ltd and Tony Garnock-Jones.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): ______________________________________.
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of the GNU General Public License Version 2 or later (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of those
+ * above. If you wish to allow use of your version of this file only
+ * under the terms of the GPL, and not to allow others to use your
+ * version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the
+ * notice and other provisions required by the GPL. If you do not
+ * delete the provisions above, a recipient may use your version of
+ * this file under the terms of any one of the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+static inline int socket_init(void)
+{
+ return 0;
+}
+
+extern int socket_socket(int domain, int type, int proto);
+
+#define socket_connect connect
+#define socket_close close
+#define socket_read read
+#define socket_write write
+#define socket_writev writev
+
+static inline int encoded_socket_errno()
+{
+ return errno | ERROR_CATEGORY_OS;
+}
+
+#endif
diff --git a/librabbitmq/windows/socket.c b/librabbitmq/windows/socket.c
new file mode 100644
index 0000000..f809f62
--- /dev/null
+++ b/librabbitmq/windows/socket.c
@@ -0,0 +1,88 @@
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is librabbitmq.
+ *
+ * The Initial Developers of the Original Code are LShift Ltd, Cohesive
+ * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions
+ * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive
+ * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright
+ * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and
+ * Rabbit Technologies Ltd.
+ *
+ * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
+ * Ltd. Portions created by Cohesive Financial Technologies LLC are
+ * Copyright (C) 2007-2010 Cohesive Financial Technologies
+ * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C)
+ * 2007-2010 Rabbit Technologies Ltd.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010
+ * LShift Ltd and Tony Garnock-Jones.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): ______________________________________.
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of the GNU General Public License Version 2 or later (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of those
+ * above. If you wish to allow use of your version of this file only
+ * under the terms of the GPL, and not to allow others to use your
+ * version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the
+ * notice and other provisions required by the GPL. If you do not
+ * delete the provisions above, a recipient may use your version of
+ * this file under the terms of any one of the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+#include <windows.h>
+#include <stdint.h>
+
+#include "amqp.h"
+#include "amqp_private.h"
+#include "socket.h"
+
+static int called_wsastartup;
+
+int socket_init(void)
+{
+ if (!called_wsastartup) {
+ WSADATA data;
+ int res = WSAStartup(0x0202, &data);
+ if (res)
+ return -res;
+
+ called_wsastartup = 1;
+ }
+
+ return 0;
+}
+
+const char *amqp_os_error_string(int err)
+{
+ char *msg, *copy;
+
+ if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL, err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&msg, 0, NULL))
+ return strdup("(error retrieving Windows error message)");
+
+ copy = strdup(msg);
+ LocalFree(msg);
+ return copy;
+}
diff --git a/librabbitmq/windows/socket.h b/librabbitmq/windows/socket.h
new file mode 100644
index 0000000..bff6efc
--- /dev/null
+++ b/librabbitmq/windows/socket.h
@@ -0,0 +1,92 @@
+#ifndef librabbitmq_windows_socket_h
+#define librabbitmq_windows_socket_h
+
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is librabbitmq.
+ *
+ * The Initial Developers of the Original Code are LShift Ltd, Cohesive
+ * Financial Technologies LLC, and Rabbit Technologies Ltd. Portions
+ * created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, Cohesive
+ * Financial Technologies LLC, or Rabbit Technologies Ltd are Copyright
+ * (C) 2007-2008 LShift Ltd, Cohesive Financial Technologies LLC, and
+ * Rabbit Technologies Ltd.
+ *
+ * Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
+ * Ltd. Portions created by Cohesive Financial Technologies LLC are
+ * Copyright (C) 2007-2010 Cohesive Financial Technologies
+ * LLC. Portions created by Rabbit Technologies Ltd are Copyright (C)
+ * 2007-2010 Rabbit Technologies Ltd.
+ *
+ * Portions created by Tony Garnock-Jones are Copyright (C) 2009-2010
+ * LShift Ltd and Tony Garnock-Jones.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): ______________________________________.
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of the GNU General Public License Version 2 or later (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of those
+ * above. If you wish to allow use of your version of this file only
+ * under the terms of the GPL, and not to allow others to use your
+ * version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the
+ * notice and other provisions required by the GPL. If you do not
+ * delete the provisions above, a recipient may use your version of
+ * this file under the terms of any one of the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+#include <winsock2.h>
+
+extern int socket_init(void);
+
+#define socket_socket socket
+#define socket_connect connect
+#define socket_close closesocket
+
+static inline int socket_read(int sock, void *buf, size_t count)
+{
+ return recv(sock, buf, count, 0);
+}
+
+static inline int socket_write(int sock, void *buf, size_t count)
+{
+ return send(sock, buf, count, 0);
+}
+
+/* same as WSABUF */
+struct iovec {
+ u_long iov_len;
+ char *iov_base;
+};
+
+static inline int socket_writev(int sock, struct iovec *iov, int nvecs)
+{
+ DWORD ret;
+ if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0)
+ return ret;
+ else
+ return -1;
+}
+
+static inline int encoded_socket_errno()
+{
+ return WSAGetLastError() | ERROR_CATEGORY_OS;
+}
+
+#endif