apple: Introduce a central compatibility header with all __APPLE__ quirks

This commit is contained in:
Martin Willi 2014-11-06 14:27:07 +01:00
parent 6e1d3f3615
commit f65779dd0f
6 changed files with 113 additions and 87 deletions

View File

@ -102,7 +102,7 @@ utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \
utils/leak_detective.h utils/printf_hook/printf_hook.h \
utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \
utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/windows.h \
utils/process.h utils/utils/strerror.h
utils/process.h utils/utils/strerror.h utils/compat/apple.h
endif
library.lo : $(top_builddir)/config.status

View File

@ -79,6 +79,9 @@
*
* @defgroup utils utils
* @ingroup libstrongswan
*
* @defgroup compat compat
* @ingroup utils
*/
/**

View File

@ -21,10 +21,7 @@
#ifndef THREADING_SEMAPHORE_H_
#define THREADING_SEMAPHORE_H_
#ifdef __APPLE__
/* Mach uses a semaphore_create() call, use a different name for ours */
#define semaphore_create(x) strongswan_semaphore_create(x)
#endif /* __APPLE__ */
#include <utils/utils.h>
typedef struct semaphore_t semaphore_t;
@ -87,4 +84,3 @@ struct semaphore_t {
semaphore_t *semaphore_create(u_int value);
#endif /** THREADING_SEMAPHORE_H_ @} */

View File

@ -21,41 +21,10 @@
#ifndef THREADING_THREAD_H_
#define THREADING_THREAD_H_
#include <utils/utils.h>
typedef struct thread_t thread_t;
#ifdef __APPLE__
/* 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)
/* 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).
*/
#include <sys/socket.h>
#include <sys/select.h>
#define WRAP_WITH_SELECT(func, socket, ...)\
fd_set rfds; FD_ZERO(&rfds); FD_SET(socket, &rfds);\
if (select(socket + 1, &rfds, NULL, NULL, NULL) <= 0) { return -1; }\
return func(socket, __VA_ARGS__)
static inline int cancellable_accept(int socket, struct sockaddr *address,
socklen_t *address_len)
{
WRAP_WITH_SELECT(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_SELECT(recvfrom, socket, buffer, length, flags, address, address_len);
}
#define recvfrom cancellable_recvfrom
#endif /* __APPLE__ */
/**
* Main function of a thread.
*
@ -189,52 +158,4 @@ void threads_init();
*/
void threads_deinit();
#ifdef __APPLE__
/*
* 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
#include <poll.h>
/*
* 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__ */
#endif /** THREADING_THREAD_H_ @} */

View File

@ -0,0 +1,103 @@
/*
* 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_SELECT(func, socket, ...)\
fd_set rfds; FD_ZERO(&rfds); FD_SET(socket, &rfds);\
if (select(socket + 1, &rfds, NULL, NULL, NULL) <= 0) { return -1; }\
return func(socket, __VA_ARGS__)
static inline int cancellable_accept(int socket, struct sockaddr *address,
socklen_t *address_len)
{
WRAP_WITH_SELECT(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_SELECT(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_ @}*/

View File

@ -97,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