summaryrefslogtreecommitdiff
path: root/librabbitmq/amqp_socket.c
diff options
context:
space:
mode:
authorAlan Antonuk <alan.antonuk@gmail.com>2013-06-12 16:59:19 -0700
committerAlan Antonuk <alan.antonuk@gmail.com>2013-06-13 16:40:36 -0700
commit0218bb262b9323f431ed84f5c1d1eb1c5bdb1c8b (patch)
tree1fb756c31dda6bc7736fa1650b87d65ff839c382 /librabbitmq/amqp_socket.c
parent22e41b8b52bace283c424d9a125656fcb0a41120 (diff)
downloadrabbitmq-c-0218bb262b9323f431ed84f5c1d1eb1c5bdb1c8b.tar.gz
Move amqp_os_socket* funcs to amqp_socket.h/c
Doing this for code clarity, as its easier to see what the issues are when you have all implementations in one file
Diffstat (limited to 'librabbitmq/amqp_socket.c')
-rw-r--r--librabbitmq/amqp_socket.c119
1 files changed, 109 insertions, 10 deletions
diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c
index 7649c74..3c6a42e 100644
--- a/librabbitmq/amqp_socket.c
+++ b/librabbitmq/amqp_socket.c
@@ -40,8 +40,6 @@
#include "amqp_private.h"
-#include "socket.h"
-
#include <assert.h>
#include <stdarg.h>
#include <stdint.h>
@@ -49,6 +47,111 @@
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
+
+#ifdef _WIN32
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <Winsock2.h>
+# include <ws2tcpip.h>
+#else
+# include <sys/types.h> /* On older BSD this must come before net includes */
+# include <netinet/in.h>
+# include <netinet/tcp.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <sys/uio.h>
+# include <fcntl.h>
+# include <unistd.h>
+#endif
+
+static int
+amqp_os_socket_init(void)
+{
+#ifdef _WIN32
+ static called_wsastartup = 0;
+ if (!called_wsastartup) {
+ WSADATA data;
+ int res = WSAStartup(0x0202, &data);
+ if (res) {
+ return AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR;
+ }
+
+ called_wsastartup = 1;
+ }
+ return AMQP_STATUS_OK;
+
+#else
+ return AMQP_STATUS_OK;
+#endif
+}
+
+static int
+amqp_os_socket_socket(int domain, int type, int protocol)
+{
+#ifdef _WIN32
+ /*
+ This cast is to squash warnings on Win64, see:
+ http://stackoverflow.com/questions/1953639/is-it-safe-to-cast-socket-to-int-under-win64
+ */
+ return (int)socket(domain, type, protocol);
+#else
+ int flags;
+
+ int s = socket(domain, type, protocol);
+ 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;
+
+#endif
+}
+
+static int
+amqp_os_socket_setsockopt(int sock, int level, int optname,
+ const void *optval, size_t optlen)
+{
+#ifdef _WIN32
+ /* the winsock setsockopt function has its 4th argument as a
+ const char * */
+ return setsockopt(sock, level, optname, (const char *)optval, optlen);
+#else
+ return setsockopt(sock, level, optname, optval, optlen);
+#endif
+}
+
+int
+amqp_os_socket_error(void)
+{
+#ifdef _WIN32
+ return WSAGetLastError();
+#else
+ return errno;
+#endif
+}
+
+int
+amqp_os_socket_close(int sockfd)
+{
+#ifdef _WIN32
+ return closesocket(sockfd);
+#else
+ return close(sockfd);
+#endif
+}
+
ssize_t
amqp_socket_writev(amqp_socket_t *self, struct iovec *iov, int iovcnt)
{
@@ -118,7 +221,7 @@ int amqp_open_socket(char const *hostname,
int last_error = AMQP_STATUS_OK;
int one = 1; /* for setsockopt */
- last_error = amqp_socket_init();
+ last_error = amqp_os_socket_init();
if (AMQP_STATUS_OK != last_error) {
return last_error;
}
@@ -137,23 +240,19 @@ int amqp_open_socket(char const *hostname,
}
for (addr = address_list; addr; addr = addr->ai_next) {
- /*
- This cast is to squash warnings on Win64, see:
- http://stackoverflow.com/questions/1953639/is-it-safe-to-cast-socket-to-int-under-win64
- */
- sockfd = (int)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
+ sockfd = amqp_os_socket_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (-1 == sockfd) {
last_error = AMQP_STATUS_SOCKET_ERROR;
continue;
}
#ifdef DISABLE_SIGPIPE_WITH_SETSOCKOPT
- if (0 != amqp_socket_setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) {
+ if (0 != amqp_os_socket_setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) {
last_error = AMQP_STATUS_SOCKET_ERROR;
amqp_os_socket_close(sockfd);
continue;
}
#endif /* DISABLE_SIGPIPE_WITH_SETSOCKOPT */
- if (0 != amqp_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one))
+ if (0 != amqp_os_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one))
|| 0 != connect(sockfd, addr->ai_addr, addr->ai_addrlen)) {
last_error = AMQP_STATUS_SOCKET_ERROR;
amqp_os_socket_close(sockfd);