diff options
Diffstat (limited to 'crypto/compat/posix_win.c')
-rw-r--r-- | crypto/compat/posix_win.c | 85 |
1 files changed, 33 insertions, 52 deletions
diff --git a/crypto/compat/posix_win.c b/crypto/compat/posix_win.c index 1fbfce1..572e527 100644 --- a/crypto/compat/posix_win.c +++ b/crypto/compat/posix_win.c | |||
@@ -22,6 +22,25 @@ | |||
22 | #include <string.h> | 22 | #include <string.h> |
23 | #include <unistd.h> | 23 | #include <unistd.h> |
24 | 24 | ||
25 | #include <sys/stat.h> | ||
26 | |||
27 | static int | ||
28 | is_socket(int fd) | ||
29 | { | ||
30 | // Border case: Don't break std* file descriptors | ||
31 | if (fd < 3) | ||
32 | return 0; | ||
33 | |||
34 | // All locally-allocated file descriptors will have the high bit set | ||
35 | return (fd & 0x80000000) == 0; | ||
36 | } | ||
37 | |||
38 | static int | ||
39 | get_real_fd(int fd) | ||
40 | { | ||
41 | return (fd & 0x7fffffff); | ||
42 | } | ||
43 | |||
25 | void | 44 | void |
26 | posix_perror(const char *s) | 45 | posix_perror(const char *s) |
27 | { | 46 | { |
@@ -44,6 +63,12 @@ posix_fopen(const char *path, const char *mode) | |||
44 | } | 63 | } |
45 | 64 | ||
46 | int | 65 | int |
66 | libressl_fstat(int fd, struct stat *statbuf) | ||
67 | { | ||
68 | return fstat(get_real_fd(fd), statbuf); | ||
69 | } | ||
70 | |||
71 | int | ||
47 | posix_open(const char *path, ...) | 72 | posix_open(const char *path, ...) |
48 | { | 73 | { |
49 | va_list ap; | 74 | va_list ap; |
@@ -62,7 +87,11 @@ posix_open(const char *path, ...) | |||
62 | flags |= O_NOINHERIT; | 87 | flags |= O_NOINHERIT; |
63 | } | 88 | } |
64 | flags &= ~O_NONBLOCK; | 89 | flags &= ~O_NONBLOCK; |
65 | return open(path, flags, mode); | 90 | |
91 | const int fh = open(path, flags, mode); | ||
92 | |||
93 | // Set high bit to mark file descriptor as a file handle | ||
94 | return fh + 0x80000000; | ||
66 | } | 95 | } |
67 | 96 | ||
68 | char * | 97 | char * |
@@ -150,52 +179,6 @@ wsa_errno(int err) | |||
150 | return -1; | 179 | return -1; |
151 | } | 180 | } |
152 | 181 | ||
153 | /* | ||
154 | * Employ a similar trick to cpython (pycore_fileutils.h) where the CRT report | ||
155 | * handler is disabled while checking if a descriptor is a socket or a file | ||
156 | */ | ||
157 | #if defined _MSC_VER && _MSC_VER >= 1900 | ||
158 | |||
159 | #include <crtdbg.h> | ||
160 | #include <stdlib.h> | ||
161 | |||
162 | static void noop_handler(const wchar_t *expression, const wchar_t *function, | ||
163 | const wchar_t *file, unsigned int line, uintptr_t pReserved) | ||
164 | { | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | #define BEGIN_SUPPRESS_IPH \ | ||
169 | const int old_report_mode = _CrtSetReportMode(_CRT_ASSERT, 0); \ | ||
170 | const _invalid_parameter_handler old_handler = _set_thread_local_invalid_parameter_handler(noop_handler) | ||
171 | #define END_SUPPRESS_IPH \ | ||
172 | (void)old_report_mode; /* Silence warning in release mode when _CrtSetReportMode compiles to void. */ \ | ||
173 | _CrtSetReportMode(_CRT_ASSERT, old_report_mode); \ | ||
174 | _set_thread_local_invalid_parameter_handler(old_handler) | ||
175 | |||
176 | #else | ||
177 | |||
178 | #define BEGIN_SUPPRESS_IPH | ||
179 | #define END_SUPPRESS_IPH | ||
180 | |||
181 | #endif | ||
182 | |||
183 | static int | ||
184 | is_socket(int fd) | ||
185 | { | ||
186 | intptr_t hd; | ||
187 | |||
188 | BEGIN_SUPPRESS_IPH; | ||
189 | hd = _get_osfhandle(fd); | ||
190 | END_SUPPRESS_IPH; | ||
191 | |||
192 | if (hd == (intptr_t)INVALID_HANDLE_VALUE) { | ||
193 | return 1; /* fd is not file descriptor */ | ||
194 | } | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | int | 182 | int |
200 | posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) | 183 | posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
201 | { | 184 | { |
@@ -209,14 +192,13 @@ int | |||
209 | posix_close(int fd) | 192 | posix_close(int fd) |
210 | { | 193 | { |
211 | int rc; | 194 | int rc; |
212 | |||
213 | if (is_socket(fd)) { | 195 | if (is_socket(fd)) { |
214 | if ((rc = closesocket(fd)) == SOCKET_ERROR) { | 196 | if ((rc = closesocket(fd)) == SOCKET_ERROR) { |
215 | int err = WSAGetLastError(); | 197 | int err = WSAGetLastError(); |
216 | rc = wsa_errno(err); | 198 | rc = wsa_errno(err); |
217 | } | 199 | } |
218 | } else { | 200 | } else { |
219 | rc = close(fd); | 201 | rc = close(get_real_fd(fd)); |
220 | } | 202 | } |
221 | return rc; | 203 | return rc; |
222 | } | 204 | } |
@@ -225,14 +207,13 @@ ssize_t | |||
225 | posix_read(int fd, void *buf, size_t count) | 207 | posix_read(int fd, void *buf, size_t count) |
226 | { | 208 | { |
227 | ssize_t rc; | 209 | ssize_t rc; |
228 | |||
229 | if (is_socket(fd)) { | 210 | if (is_socket(fd)) { |
230 | if ((rc = recv(fd, buf, count, 0)) == SOCKET_ERROR) { | 211 | if ((rc = recv(fd, buf, count, 0)) == SOCKET_ERROR) { |
231 | int err = WSAGetLastError(); | 212 | int err = WSAGetLastError(); |
232 | rc = wsa_errno(err); | 213 | rc = wsa_errno(err); |
233 | } | 214 | } |
234 | } else { | 215 | } else { |
235 | rc = read(fd, buf, count); | 216 | rc = read(get_real_fd(fd), buf, count); |
236 | } | 217 | } |
237 | return rc; | 218 | return rc; |
238 | } | 219 | } |
@@ -246,7 +227,7 @@ posix_write(int fd, const void *buf, size_t count) | |||
246 | rc = wsa_errno(WSAGetLastError()); | 227 | rc = wsa_errno(WSAGetLastError()); |
247 | } | 228 | } |
248 | } else { | 229 | } else { |
249 | rc = write(fd, buf, count); | 230 | rc = write(get_real_fd(fd), buf, count); |
250 | } | 231 | } |
251 | return rc; | 232 | return rc; |
252 | } | 233 | } |