aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrent Cook <busterb@gmail.com>2023-07-07 04:31:00 -0500
committerBrent Cook <busterb@gmail.com>2023-07-07 04:31:00 -0500
commit2354879274cdc24862bcf585815bc76718eb8400 (patch)
tree1c00c837f00c6ed0f9d895a438de4b3fa057134d
parent4070587a029b2b9ae8ec9b98a8b33b718087fa5c (diff)
parentc9b18cb296c0f43d56b9dc9c1e05b57fc780c798 (diff)
downloadportable-2354879274cdc24862bcf585815bc76718eb8400.tar.gz
portable-2354879274cdc24862bcf585815bc76718eb8400.tar.bz2
portable-2354879274cdc24862bcf585815bc76718eb8400.zip
Land #883, improve socket / file descriptor checks on Windows
-rw-r--r--CMakeLists.txt2
-rw-r--r--crypto/compat/posix_win.c113
2 files changed, 90 insertions, 25 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b8863c4..02699d0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -121,7 +121,7 @@ if(WIN32)
121 if(NOT CMAKE_SYSTEM_NAME MATCHES "WindowsStore") 121 if(NOT CMAKE_SYSTEM_NAME MATCHES "WindowsStore")
122 add_definitions(-D_WIN32_WINNT=0x0600) 122 add_definitions(-D_WIN32_WINNT=0x0600)
123 endif() 123 endif()
124 set(PLATFORM_LIBS ${PLATFORM_LIBS} ws2_32 bcrypt) 124 set(PLATFORM_LIBS ${PLATFORM_LIBS} ws2_32 ntdll bcrypt)
125endif() 125endif()
126 126
127if(MSVC) 127if(MSVC)
diff --git a/crypto/compat/posix_win.c b/crypto/compat/posix_win.c
index 30c93cd..b3a4687 100644
--- a/crypto/compat/posix_win.c
+++ b/crypto/compat/posix_win.c
@@ -148,6 +148,49 @@ wsa_errno(int err)
148 return -1; 148 return -1;
149} 149}
150 150
151/*
152 * Employ a similar trick to cpython (pycore_fileutils.h) where the CRT report
153 * handler is disabled while checking if a descriptor is a socket or a file
154 */
155#if defined _MSC_VER && _MSC_VER >= 1900
156
157#include <crtdbg.h>
158#include <stdlib.h>
159
160static void noop_handler(const wchar_t *expression, const wchar_t *function,
161 const wchar_t *file, unsigned int line, uintptr_t pReserved)
162{
163 return;
164}
165
166#define BEGIN_SUPPRESS_IPH \
167 _invalid_parameter_handler old_handler = _set_thread_local_invalid_parameter_handler(noop_handler)
168#define END_SUPPRESS_IPH \
169 _set_thread_local_invalid_parameter_handler(old_handler)
170
171#else
172
173#define BEGIN_SUPPRESS_IPH
174#define END_SUPPRESS_IPH
175
176#endif
177
178static int
179is_socket(int fd)
180{
181 intptr_t hd;
182
183 BEGIN_SUPPRESS_IPH;
184 hd = _get_osfhandle(fd);
185 END_SUPPRESS_IPH;
186
187 if (hd == (intptr_t)INVALID_HANDLE_VALUE) {
188 return 1; /* fd is not file descriptor */
189 }
190
191 return 0;
192}
193
151int 194int
152posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) 195posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
153{ 196{
@@ -160,24 +203,31 @@ posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
160int 203int
161posix_close(int fd) 204posix_close(int fd)
162{ 205{
163 if (closesocket(fd) == SOCKET_ERROR) { 206 int rc;
164 int err = WSAGetLastError(); 207
165 return (err == WSAENOTSOCK || err == WSAEBADF || 208 if (is_socket(fd)) {
166 err == WSANOTINITIALISED) ? 209 if ((rc = closesocket(fd)) == SOCKET_ERROR) {
167 close(fd) : wsa_errno(err); 210 int err = WSAGetLastError();
211 rc = wsa_errno(err);
212 }
213 } else {
214 rc = close(fd);
168 } 215 }
169 return 0; 216 return rc;
170} 217}
171 218
172ssize_t 219ssize_t
173posix_read(int fd, void *buf, size_t count) 220posix_read(int fd, void *buf, size_t count)
174{ 221{
175 ssize_t rc = recv(fd, buf, count, 0); 222 ssize_t rc;
176 if (rc == SOCKET_ERROR) { 223
177 int err = WSAGetLastError(); 224 if (is_socket(fd)) {
178 return (err == WSAENOTSOCK || err == WSAEBADF || 225 if ((rc = recv(fd, buf, count, 0)) == SOCKET_ERROR) {
179 err == WSANOTINITIALISED) ? 226 int err = WSAGetLastError();
180 read(fd, buf, count) : wsa_errno(err); 227 rc = wsa_errno(err);
228 }
229 } else {
230 rc = read(fd, buf, count);
181 } 231 }
182 return rc; 232 return rc;
183} 233}
@@ -185,12 +235,13 @@ posix_read(int fd, void *buf, size_t count)
185ssize_t 235ssize_t
186posix_write(int fd, const void *buf, size_t count) 236posix_write(int fd, const void *buf, size_t count)
187{ 237{
188 ssize_t rc = send(fd, buf, count, 0); 238 ssize_t rc;
189 if (rc == SOCKET_ERROR) { 239 if (is_socket(fd)) {
190 int err = WSAGetLastError(); 240 if ((rc = send(fd, buf, count, 0)) == SOCKET_ERROR) {
191 return (err == WSAENOTSOCK || err == WSAEBADF || 241 rc = wsa_errno(WSAGetLastError());
192 err == WSANOTINITIALISED) ? 242 }
193 write(fd, buf, count) : wsa_errno(err); 243 } else {
244 rc = write(fd, buf, count);
194 } 245 }
195 return rc; 246 return rc;
196} 247}
@@ -199,17 +250,32 @@ int
199posix_getsockopt(int sockfd, int level, int optname, 250posix_getsockopt(int sockfd, int level, int optname,
200 void *optval, socklen_t *optlen) 251 void *optval, socklen_t *optlen)
201{ 252{
202 int rc = getsockopt(sockfd, level, optname, (char *)optval, optlen); 253 int rc;
203 return rc == 0 ? 0 : wsa_errno(WSAGetLastError()); 254 if (is_socket(sockfd)) {
204 255 rc = getsockopt(sockfd, level, optname, (char *)optval, optlen);
256 if (rc != 0) {
257 rc = wsa_errno(WSAGetLastError());
258 }
259 } else {
260 rc = -1;
261 }
262 return rc;
205} 263}
206 264
207int 265int
208posix_setsockopt(int sockfd, int level, int optname, 266posix_setsockopt(int sockfd, int level, int optname,
209 const void *optval, socklen_t optlen) 267 const void *optval, socklen_t optlen)
210{ 268{
211 int rc = setsockopt(sockfd, level, optname, (char *)optval, optlen); 269 int rc;
212 return rc == 0 ? 0 : wsa_errno(WSAGetLastError()); 270 if (is_socket(sockfd)) {
271 rc = setsockopt(sockfd, level, optname, (char *)optval, optlen);
272 if (rc != 0) {
273 rc = wsa_errno(WSAGetLastError());
274 }
275 } else {
276 rc = -1;
277 }
278 return rc;
213} 279}
214 280
215uid_t getuid(void) 281uid_t getuid(void)
@@ -241,5 +307,4 @@ int gettimeofday(struct timeval * tp, struct timezone * tzp)
241 tp->tv_usec = (long)(system_time.wMilliseconds * 1000); 307 tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
242 return 0; 308 return 0;
243} 309}
244
245#endif 310#endif