]>
Commit | Line | Data |
---|---|---|
f65779dd MW |
1 | /* |
2 | * Copyright (C) 2014 Martin Willi | |
19ef2aec TB |
3 | * |
4 | * Copyright (C) secunet Security Networks AG | |
f65779dd MW |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the | |
8 | * Free Software Foundation; either version 2 of the License, or (at your | |
9 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 | * for more details. | |
15 | */ | |
16 | ||
17 | /** | |
18 | * @defgroup apple apple | |
19 | * @{ @ingroup compat | |
20 | */ | |
21 | ||
22 | #ifndef APPLE_H_ | |
23 | #define APPLE_H_ | |
24 | ||
25 | #include <poll.h> | |
26 | #include <sys/socket.h> | |
27 | #include <sys/select.h> | |
28 | ||
29 | /* thread_create is a syscall used to create Mach kernel threads and although | |
30 | * there are no errors or warnings during compilation or linkage the dynamic | |
31 | * linker does not use our implementation, therefore we rename it here | |
32 | */ | |
33 | #define thread_create(main, arg) strongswan_thread_create(main, arg) | |
34 | ||
35 | /* Mach uses a semaphore_create() call, use a different name for ours */ | |
36 | #define semaphore_create(x) strongswan_semaphore_create(x) | |
37 | ||
04337fed MW |
38 | /* Since OS X 10.10 XPC includes some additional conflicting Mach types */ |
39 | #define host_t strongswan_host_t | |
40 | #define processor_t strongswan_processor_t | |
41 | #define task_t strongswan_task_t | |
42 | #define thread_t strongswan_thread_t | |
43 | ||
6e4620ad MW |
44 | /* forward declaration, see below */ |
45 | static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds, | |
46 | int timeout); | |
47 | ||
f65779dd MW |
48 | /* on Mac OS X 10.5 several system calls we use are no cancellation points. |
49 | * fortunately, select isn't one of them, so we wrap some of the others with | |
50 | * calls to select(2). | |
51 | */ | |
52 | ||
aec3d5fb MW |
53 | #define WRAP_WITH_POLL(func, socket, ...) \ |
54 | struct pollfd pfd = { \ | |
55 | .fd = socket, \ | |
56 | .events = POLLIN, \ | |
57 | }; \ | |
6e4620ad | 58 | if (precancellable_poll(&pfd, 1, -1) <= 0) \ |
aec3d5fb MW |
59 | {\ |
60 | return -1; \ | |
61 | }\ | |
f65779dd MW |
62 | return func(socket, __VA_ARGS__) |
63 | ||
64 | static inline int cancellable_accept(int socket, struct sockaddr *address, | |
65 | socklen_t *address_len) | |
66 | { | |
aec3d5fb | 67 | WRAP_WITH_POLL(accept, socket, address, address_len); |
f65779dd MW |
68 | } |
69 | #define accept cancellable_accept | |
70 | static inline int cancellable_recvfrom(int socket, void *buffer, size_t length, | |
71 | int flags, struct sockaddr *address, socklen_t *address_len) | |
72 | { | |
aec3d5fb | 73 | WRAP_WITH_POLL(recvfrom, socket, buffer, length, flags, address, address_len); |
f65779dd MW |
74 | } |
75 | #define recvfrom cancellable_recvfrom | |
76 | ||
77 | #include <threading/thread.h> | |
78 | ||
79 | /* | |
80 | * While select() is a cancellation point, it seems that OS X does not honor | |
81 | * pending cancellation points when entering the function. We manually test for | |
82 | * and honor pending cancellation requests, but this obviously can't prevent | |
83 | * some race conditions where the the cancellation happens after the check, | |
84 | * but before the select. | |
85 | */ | |
86 | static inline int precancellable_select(int nfds, fd_set *restrict readfds, | |
87 | fd_set *restrict writefds, fd_set *restrict errorfds, | |
88 | struct timeval *restrict timeout) | |
89 | { | |
90 | if (thread_cancelability(TRUE)) | |
91 | { | |
92 | thread_cancellation_point(); | |
93 | } | |
94 | else | |
95 | { | |
96 | thread_cancelability(FALSE); | |
97 | } | |
98 | return select(nfds, readfds, writefds, errorfds, timeout); | |
99 | } | |
100 | #define select precancellable_select | |
101 | ||
102 | /* | |
103 | * The same as to select(2) applies to poll(2) | |
104 | */ | |
105 | static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds, | |
106 | int timeout) | |
107 | { | |
108 | if (thread_cancelability(TRUE)) | |
109 | { | |
110 | thread_cancellation_point(); | |
111 | } | |
112 | else | |
113 | { | |
114 | thread_cancelability(FALSE); | |
115 | } | |
116 | return poll(fds, nfds, timeout); | |
117 | } | |
118 | #define poll precancellable_poll | |
119 | ||
120 | #endif /** APPLE_H_ @}*/ |