aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/utils')
-rw-r--r--src/libstrongswan/utils/compat/apple.h109
-rw-r--r--src/libstrongswan/utils/compat/windows.c (renamed from src/libstrongswan/utils/windows.c)45
-rw-r--r--src/libstrongswan/utils/compat/windows.h (renamed from src/libstrongswan/utils/windows.h)45
-rw-r--r--src/libstrongswan/utils/utils.h6
4 files changed, 202 insertions, 3 deletions
diff --git a/src/libstrongswan/utils/compat/apple.h b/src/libstrongswan/utils/compat/apple.h
new file mode 100644
index 000000000..06a7887e7
--- /dev/null
+++ b/src/libstrongswan/utils/compat/apple.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup apple apple
+ * @{ @ingroup compat
+ */
+
+#ifndef APPLE_H_
+#define APPLE_H_
+
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+
+/* thread_create is a syscall used to create Mach kernel threads and although
+ * there are no errors or warnings during compilation or linkage the dynamic
+ * linker does not use our implementation, therefore we rename it here
+ */
+#define thread_create(main, arg) strongswan_thread_create(main, arg)
+
+/* Mach uses a semaphore_create() call, use a different name for ours */
+#define semaphore_create(x) strongswan_semaphore_create(x)
+
+/* on Mac OS X 10.5 several system calls we use are no cancellation points.
+ * fortunately, select isn't one of them, so we wrap some of the others with
+ * calls to select(2).
+ */
+
+#define WRAP_WITH_POLL(func, socket, ...) \
+ struct pollfd pfd = { \
+ .fd = socket, \
+ .events = POLLIN, \
+ }; \
+ if (poll(&pfd, 1, -1) <= 0) \
+ {\
+ return -1; \
+ }\
+ return func(socket, __VA_ARGS__)
+
+static inline int cancellable_accept(int socket, struct sockaddr *address,
+ socklen_t *address_len)
+{
+ WRAP_WITH_POLL(accept, socket, address, address_len);
+}
+#define accept cancellable_accept
+static inline int cancellable_recvfrom(int socket, void *buffer, size_t length,
+ int flags, struct sockaddr *address, socklen_t *address_len)
+{
+ WRAP_WITH_POLL(recvfrom, socket, buffer, length, flags, address, address_len);
+}
+#define recvfrom cancellable_recvfrom
+
+#include <threading/thread.h>
+
+/*
+ * While select() is a cancellation point, it seems that OS X does not honor
+ * pending cancellation points when entering the function. We manually test for
+ * and honor pending cancellation requests, but this obviously can't prevent
+ * some race conditions where the the cancellation happens after the check,
+ * but before the select.
+ */
+static inline int precancellable_select(int nfds, fd_set *restrict readfds,
+ fd_set *restrict writefds, fd_set *restrict errorfds,
+ struct timeval *restrict timeout)
+{
+ if (thread_cancelability(TRUE))
+ {
+ thread_cancellation_point();
+ }
+ else
+ {
+ thread_cancelability(FALSE);
+ }
+ return select(nfds, readfds, writefds, errorfds, timeout);
+}
+#define select precancellable_select
+
+/*
+ * The same as to select(2) applies to poll(2)
+ */
+static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds,
+ int timeout)
+{
+ if (thread_cancelability(TRUE))
+ {
+ thread_cancellation_point();
+ }
+ else
+ {
+ thread_cancelability(FALSE);
+ }
+ return poll(fds, nfds, timeout);
+}
+#define poll precancellable_poll
+
+#endif /** APPLE_H_ @}*/
diff --git a/src/libstrongswan/utils/windows.c b/src/libstrongswan/utils/compat/windows.c
index 8820287b1..e2be64d50 100644
--- a/src/libstrongswan/utils/windows.c
+++ b/src/libstrongswan/utils/compat/windows.c
@@ -13,7 +13,10 @@
* for more details.
*/
-#include "utils.h"
+/* WSAPoll() */
+#define _WIN32_WINNT 0x0600
+
+#include <utils/utils.h>
#include <errno.h>
@@ -639,3 +642,43 @@ ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
}
return outlen;
}
+
+/**
+ * See header
+ */
+#undef read
+ssize_t windows_read(int fd, void *buf, size_t count)
+{
+ ssize_t ret;
+
+ ret = recv(fd, buf, count, 0);
+ if (ret == -1 && WSAGetLastError() == WSAENOTSOCK)
+ {
+ ret = read(fd, buf, count);
+ }
+ return ret;
+}
+
+/**
+ * See header
+ */
+#undef write
+ssize_t windows_write(int fd, void *buf, size_t count)
+{
+ ssize_t ret;
+
+ ret = send(fd, buf, count, 0);
+ if (ret == -1 && WSAGetLastError() == WSAENOTSOCK)
+ {
+ ret = write(fd, buf, count);
+ }
+ return ret;
+}
+
+/**
+ * See header
+ */
+int poll(struct pollfd *fds, int nfds, int timeout)
+{
+ return wserr(WSAPoll(fds, nfds, timeout));
+}
diff --git a/src/libstrongswan/utils/windows.h b/src/libstrongswan/utils/compat/windows.h
index 3761e10ab..fd4f1f196 100644
--- a/src/libstrongswan/utils/windows.h
+++ b/src/libstrongswan/utils/compat/windows.h
@@ -15,7 +15,7 @@
/**
* @defgroup windows windows
- * @{ @ingroup utils
+ * @{ @ingroup compat
*/
#ifndef WINDOWS_H_
@@ -363,6 +363,49 @@ ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
/**
+ * read(2) working on files and sockets, cancellable on sockets only
+ *
+ * On Windows, there does not seem to be a way how a cancellable read can
+ * be implemented on Low level I/O functions for files, _pipe()s or stdio.
+ */
+#define read windows_read
+ssize_t windows_read(int fd, void *buf, size_t count);
+
+/**
+ * write(2) working on files and sockets
+ */
+#define write windows_write
+ssize_t windows_write(int fd, void *buf, size_t count);
+
+#if _WIN32_WINNT < 0x0600
+/**
+ * Define pollfd and flags on our own if not specified
+ */
+struct pollfd {
+ SOCKET fd;
+ short events;
+ short revents;
+};
+enum {
+ POLLERR = 0x0001,
+ POLLHUP = 0x0002,
+ POLLNVAL = 0x0004,
+ POLLWRNORM = 0x0010,
+ POLLWRBAND = 0x0020,
+ POLLPRI = 0x0400,
+ POLLRDNORM = 0x0100,
+ POLLRDBAND = 0x0200,
+ POLLIN = POLLRDNORM | POLLRDBAND,
+ POLLOUT = POLLWRNORM,
+};
+#endif /* _WIN32_WINNT < 0x0600 */
+
+/**
+ * poll(2), implemented using Winsock2 WSAPoll()
+ */
+int poll(struct pollfd *fds, int nfds, int timeout);
+
+/**
* Declaration missing on older WinGW
*/
_CRTIMP errno_t strerror_s(char *buf, size_t size, int errnum);
diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h
index da253cc35..7c48d949f 100644
--- a/src/libstrongswan/utils/utils.h
+++ b/src/libstrongswan/utils/utils.h
@@ -29,7 +29,7 @@
#include <string.h>
#ifdef WIN32
-# include "windows.h"
+# include "compat/windows.h"
#else
# define _GNU_SOURCE
# include <arpa/inet.h>
@@ -37,6 +37,7 @@
# include <netdb.h>
# include <netinet/in.h>
# include <sched.h>
+# include <poll.h>
#endif
/**
@@ -96,6 +97,9 @@
#include "enum.h"
#include "utils/strerror.h"
+#ifdef __APPLE__
+# include "compat/apple.h"
+#endif
/**
* Directory separator character in paths on this platform