diff options
author | David Wragg <dpw@lshift.net> | 2010-05-30 23:31:40 +0100 |
---|---|---|
committer | David Wragg <dpw@lshift.net> | 2010-05-30 23:31:40 +0100 |
commit | 1c198e88d1a0c74676f8d6fade99b2531ba815b8 (patch) | |
tree | 133f008278e7badb652e94535ef29b58d383fea6 /librabbitmq | |
parent | bf06e86975f474da30e9c74faff7a99b0734e00e (diff) | |
download | rabbitmq-c-github-ask-1c198e88d1a0c74676f8d6fade99b2531ba815b8.tar.gz |
A Windows port, using MinGW/MSYS
Diffstat (limited to 'librabbitmq')
-rw-r--r-- | librabbitmq/Makefile.am | 8 | ||||
-rw-r--r-- | librabbitmq/amqp_api.c | 6 | ||||
-rw-r--r-- | librabbitmq/amqp_connection.c | 20 | ||||
-rw-r--r-- | librabbitmq/amqp_mem.c | 1 | ||||
-rw-r--r-- | librabbitmq/amqp_private.h | 5 | ||||
-rw-r--r-- | librabbitmq/amqp_socket.c | 36 | ||||
-rw-r--r-- | librabbitmq/amqp_table.c | 2 | ||||
-rw-r--r-- | librabbitmq/codegen.py | 1 | ||||
-rw-r--r-- | librabbitmq/unix/socket.c | 85 | ||||
-rw-r--r-- | librabbitmq/unix/socket.h | 80 | ||||
-rw-r--r-- | librabbitmq/windows/socket.c | 88 | ||||
-rw-r--r-- | librabbitmq/windows/socket.h | 92 |
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 |