Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/curl/lib/select.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /*************************************************************************** | |
| 2 * _ _ ____ _ | |
| 3 * Project ___| | | | _ \| | | |
| 4 * / __| | | | |_) | | | |
| 5 * | (__| |_| | _ <| |___ | |
| 6 * \___|\___/|_| \_\_____| | |
| 7 * | |
| 8 * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. | |
| 9 * | |
| 10 * This software is licensed as described in the file COPYING, which | |
| 11 * you should have received as part of this distribution. The terms | |
| 12 * are also available at https://curl.haxx.se/docs/copyright.html. | |
| 13 * | |
| 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell | |
| 15 * copies of the Software, and permit persons to whom the Software is | |
| 16 * furnished to do so, under the terms of the COPYING file. | |
| 17 * | |
| 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | |
| 19 * KIND, either express or implied. | |
| 20 * | |
| 21 ***************************************************************************/ | |
| 22 | |
| 23 #include "curl_setup.h" | |
| 24 | |
| 25 #ifdef HAVE_SYS_SELECT_H | |
| 26 #include <sys/select.h> | |
| 27 #endif | |
| 28 | |
| 29 #if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE) | |
| 30 #error "We can't compile without select() or poll() support." | |
| 31 #endif | |
| 32 | |
| 33 #if defined(__BEOS__) && !defined(__HAIKU__) | |
| 34 /* BeOS has FD_SET defined in socket.h */ | |
| 35 #include <socket.h> | |
| 36 #endif | |
| 37 | |
| 38 #ifdef MSDOS | |
| 39 #include <dos.h> /* delay() */ | |
| 40 #endif | |
| 41 | |
| 42 #ifdef __VXWORKS__ | |
| 43 #include <strings.h> /* bzero() in FD_SET */ | |
| 44 #endif | |
| 45 | |
| 46 #include <curl/curl.h> | |
| 47 | |
| 48 #include "urldata.h" | |
| 49 #include "connect.h" | |
| 50 #include "select.h" | |
| 51 #include "warnless.h" | |
| 52 | |
| 53 /* Convenience local macros */ | |
| 54 #define ELAPSED_MS() (int)Curl_timediff(Curl_now(), initial_tv) | |
| 55 | |
| 56 int Curl_ack_eintr = 0; | |
| 57 #define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR) | |
| 58 | |
| 59 /* | |
| 60 * Internal function used for waiting a specific amount of ms | |
| 61 * in Curl_socket_check() and Curl_poll() when no file descriptor | |
| 62 * is provided to wait on, just being used to delay execution. | |
| 63 * WinSock select() and poll() timeout mechanisms need a valid | |
| 64 * socket descriptor in a not null file descriptor set to work. | |
| 65 * Waiting indefinitely with this function is not allowed, a | |
| 66 * zero or negative timeout value will return immediately. | |
| 67 * Timeout resolution, accuracy, as well as maximum supported | |
| 68 * value is system dependent, neither factor is a citical issue | |
| 69 * for the intended use of this function in the library. | |
| 70 * | |
| 71 * Return values: | |
| 72 * -1 = system call error, invalid timeout value, or interrupted | |
| 73 * 0 = specified timeout has elapsed | |
| 74 */ | |
| 75 int Curl_wait_ms(int timeout_ms) | |
| 76 { | |
| 77 #if !defined(MSDOS) && !defined(USE_WINSOCK) | |
| 78 #ifndef HAVE_POLL_FINE | |
| 79 struct timeval pending_tv; | |
| 80 #endif | |
| 81 struct curltime initial_tv; | |
| 82 int pending_ms; | |
| 83 #endif | |
| 84 int r = 0; | |
| 85 | |
| 86 if(!timeout_ms) | |
| 87 return 0; | |
| 88 if(timeout_ms < 0) { | |
| 89 SET_SOCKERRNO(EINVAL); | |
| 90 return -1; | |
| 91 } | |
| 92 #if defined(MSDOS) | |
| 93 delay(timeout_ms); | |
| 94 #elif defined(USE_WINSOCK) | |
| 95 Sleep(timeout_ms); | |
| 96 #else | |
| 97 pending_ms = timeout_ms; | |
| 98 initial_tv = Curl_now(); | |
| 99 do { | |
| 100 int error; | |
| 101 #if defined(HAVE_POLL_FINE) | |
| 102 r = poll(NULL, 0, pending_ms); | |
| 103 #else | |
| 104 pending_tv.tv_sec = pending_ms / 1000; | |
| 105 pending_tv.tv_usec = (pending_ms % 1000) * 1000; | |
| 106 r = select(0, NULL, NULL, NULL, &pending_tv); | |
| 107 #endif /* HAVE_POLL_FINE */ | |
| 108 if(r != -1) | |
| 109 break; | |
| 110 error = SOCKERRNO; | |
| 111 if(error && ERROR_NOT_EINTR(error)) | |
| 112 break; | |
| 113 pending_ms = timeout_ms - ELAPSED_MS(); | |
| 114 if(pending_ms <= 0) { | |
| 115 r = 0; /* Simulate a "call timed out" case */ | |
| 116 break; | |
| 117 } | |
| 118 } while(r == -1); | |
| 119 #endif /* USE_WINSOCK */ | |
| 120 if(r) | |
| 121 r = -1; | |
| 122 return r; | |
| 123 } | |
| 124 | |
| 125 /* | |
| 126 * Wait for read or write events on a set of file descriptors. It uses poll() | |
| 127 * when a fine poll() is available, in order to avoid limits with FD_SETSIZE, | |
| 128 * otherwise select() is used. An error is returned if select() is being used | |
| 129 * and a file descriptor is too large for FD_SETSIZE. | |
| 130 * | |
| 131 * A negative timeout value makes this function wait indefinitely, | |
| 132 * unless no valid file descriptor is given, when this happens the | |
| 133 * negative timeout is ignored and the function times out immediately. | |
| 134 * | |
| 135 * Return values: | |
| 136 * -1 = system call error or fd >= FD_SETSIZE | |
| 137 * 0 = timeout | |
| 138 * [bitmask] = action as described below | |
| 139 * | |
| 140 * CURL_CSELECT_IN - first socket is readable | |
| 141 * CURL_CSELECT_IN2 - second socket is readable | |
| 142 * CURL_CSELECT_OUT - write socket is writable | |
| 143 * CURL_CSELECT_ERR - an error condition occurred | |
| 144 */ | |
| 145 int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */ | |
| 146 curl_socket_t readfd1, | |
| 147 curl_socket_t writefd, /* socket to write to */ | |
| 148 time_t timeout_ms) /* milliseconds to wait */ | |
| 149 { | |
| 150 #ifdef HAVE_POLL_FINE | |
| 151 struct pollfd pfd[3]; | |
| 152 int num; | |
| 153 #else | |
| 154 struct timeval pending_tv; | |
| 155 struct timeval *ptimeout; | |
| 156 fd_set fds_read; | |
| 157 fd_set fds_write; | |
| 158 fd_set fds_err; | |
| 159 curl_socket_t maxfd; | |
| 160 #endif | |
| 161 struct curltime initial_tv = {0, 0}; | |
| 162 int pending_ms = 0; | |
| 163 int r; | |
| 164 int ret; | |
| 165 | |
| 166 #if SIZEOF_TIME_T != SIZEOF_INT | |
| 167 /* wrap-around precaution */ | |
| 168 if(timeout_ms >= INT_MAX) | |
| 169 timeout_ms = INT_MAX; | |
| 170 #endif | |
| 171 | |
| 172 if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) && | |
| 173 (writefd == CURL_SOCKET_BAD)) { | |
| 174 /* no sockets, just wait */ | |
| 175 r = Curl_wait_ms((int)timeout_ms); | |
| 176 return r; | |
| 177 } | |
| 178 | |
| 179 /* Avoid initial timestamp, avoid Curl_now() call, when elapsed | |
| 180 time in this function does not need to be measured. This happens | |
| 181 when function is called with a zero timeout or a negative timeout | |
| 182 value indicating a blocking call should be performed. */ | |
| 183 | |
| 184 if(timeout_ms > 0) { | |
| 185 pending_ms = (int)timeout_ms; | |
| 186 initial_tv = Curl_now(); | |
| 187 } | |
| 188 | |
| 189 #ifdef HAVE_POLL_FINE | |
| 190 | |
| 191 num = 0; | |
| 192 if(readfd0 != CURL_SOCKET_BAD) { | |
| 193 pfd[num].fd = readfd0; | |
| 194 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI; | |
| 195 pfd[num].revents = 0; | |
| 196 num++; | |
| 197 } | |
| 198 if(readfd1 != CURL_SOCKET_BAD) { | |
| 199 pfd[num].fd = readfd1; | |
| 200 pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI; | |
| 201 pfd[num].revents = 0; | |
| 202 num++; | |
| 203 } | |
| 204 if(writefd != CURL_SOCKET_BAD) { | |
| 205 pfd[num].fd = writefd; | |
| 206 pfd[num].events = POLLWRNORM|POLLOUT; | |
| 207 pfd[num].revents = 0; | |
| 208 num++; | |
| 209 } | |
| 210 | |
| 211 do { | |
| 212 int error; | |
| 213 if(timeout_ms < 0) | |
| 214 pending_ms = -1; | |
| 215 else if(!timeout_ms) | |
| 216 pending_ms = 0; | |
| 217 r = poll(pfd, num, pending_ms); | |
| 218 if(r != -1) | |
| 219 break; | |
| 220 error = SOCKERRNO; | |
| 221 if(error && ERROR_NOT_EINTR(error)) | |
| 222 break; | |
| 223 if(timeout_ms > 0) { | |
| 224 pending_ms = (int)(timeout_ms - ELAPSED_MS()); | |
| 225 if(pending_ms <= 0) { | |
| 226 r = 0; /* Simulate a "call timed out" case */ | |
| 227 break; | |
| 228 } | |
| 229 } | |
| 230 } while(r == -1); | |
| 231 | |
| 232 if(r < 0) | |
| 233 return -1; | |
| 234 if(r == 0) | |
| 235 return 0; | |
| 236 | |
| 237 ret = 0; | |
| 238 num = 0; | |
| 239 if(readfd0 != CURL_SOCKET_BAD) { | |
| 240 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP)) | |
| 241 ret |= CURL_CSELECT_IN; | |
| 242 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL)) | |
| 243 ret |= CURL_CSELECT_ERR; | |
| 244 num++; | |
| 245 } | |
| 246 if(readfd1 != CURL_SOCKET_BAD) { | |
| 247 if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP)) | |
| 248 ret |= CURL_CSELECT_IN2; | |
| 249 if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL)) | |
| 250 ret |= CURL_CSELECT_ERR; | |
| 251 num++; | |
| 252 } | |
| 253 if(writefd != CURL_SOCKET_BAD) { | |
| 254 if(pfd[num].revents & (POLLWRNORM|POLLOUT)) | |
| 255 ret |= CURL_CSELECT_OUT; | |
| 256 if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL)) | |
| 257 ret |= CURL_CSELECT_ERR; | |
| 258 } | |
| 259 | |
| 260 return ret; | |
| 261 | |
| 262 #else /* HAVE_POLL_FINE */ | |
| 263 | |
| 264 FD_ZERO(&fds_err); | |
| 265 maxfd = (curl_socket_t)-1; | |
| 266 | |
| 267 FD_ZERO(&fds_read); | |
| 268 if(readfd0 != CURL_SOCKET_BAD) { | |
| 269 VERIFY_SOCK(readfd0); | |
| 270 FD_SET(readfd0, &fds_read); | |
| 271 FD_SET(readfd0, &fds_err); | |
| 272 maxfd = readfd0; | |
| 273 } | |
| 274 if(readfd1 != CURL_SOCKET_BAD) { | |
| 275 VERIFY_SOCK(readfd1); | |
| 276 FD_SET(readfd1, &fds_read); | |
| 277 FD_SET(readfd1, &fds_err); | |
| 278 if(readfd1 > maxfd) | |
| 279 maxfd = readfd1; | |
| 280 } | |
| 281 | |
| 282 FD_ZERO(&fds_write); | |
| 283 if(writefd != CURL_SOCKET_BAD) { | |
| 284 VERIFY_SOCK(writefd); | |
| 285 FD_SET(writefd, &fds_write); | |
| 286 FD_SET(writefd, &fds_err); | |
| 287 if(writefd > maxfd) | |
| 288 maxfd = writefd; | |
| 289 } | |
| 290 | |
| 291 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; | |
| 292 | |
| 293 do { | |
| 294 int error; | |
| 295 if(timeout_ms > 0) { | |
| 296 pending_tv.tv_sec = pending_ms / 1000; | |
| 297 pending_tv.tv_usec = (pending_ms % 1000) * 1000; | |
| 298 } | |
| 299 else if(!timeout_ms) { | |
| 300 pending_tv.tv_sec = 0; | |
| 301 pending_tv.tv_usec = 0; | |
| 302 } | |
| 303 | |
| 304 /* WinSock select() must not be called with an fd_set that contains zero | |
| 305 fd flags, or it will return WSAEINVAL. But, it also can't be called | |
| 306 with no fd_sets at all! From the documentation: | |
| 307 | |
| 308 Any two of the parameters, readfds, writefds, or exceptfds, can be | |
| 309 given as null. At least one must be non-null, and any non-null | |
| 310 descriptor set must contain at least one handle to a socket. | |
| 311 | |
| 312 We know that we have at least one bit set in at least two fd_sets in | |
| 313 this case, but we may have no bits set in either fds_read or fd_write, | |
| 314 so check for that and handle it. Luckily, with WinSock, we can _also_ | |
| 315 ask how many bits are set on an fd_set. | |
| 316 | |
| 317 It is unclear why WinSock doesn't just handle this for us instead of | |
| 318 calling this an error. | |
| 319 | |
| 320 Note also that WinSock ignores the first argument, so we don't worry | |
| 321 about the fact that maxfd is computed incorrectly with WinSock (since | |
| 322 curl_socket_t is unsigned in such cases and thus -1 is the largest | |
| 323 value). | |
| 324 */ | |
| 325 #ifdef USE_WINSOCK | |
| 326 r = select((int)maxfd + 1, | |
| 327 fds_read.fd_count ? &fds_read : NULL, | |
| 328 fds_write.fd_count ? &fds_write : NULL, | |
| 329 &fds_err, ptimeout); | |
| 330 #else | |
| 331 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); | |
| 332 #endif | |
| 333 | |
| 334 if(r != -1) | |
| 335 break; | |
| 336 error = SOCKERRNO; | |
| 337 if(error && ERROR_NOT_EINTR(error)) | |
| 338 break; | |
| 339 if(timeout_ms > 0) { | |
| 340 pending_ms = (int)(timeout_ms - ELAPSED_MS()); | |
| 341 if(pending_ms <= 0) { | |
| 342 r = 0; /* Simulate a "call timed out" case */ | |
| 343 break; | |
| 344 } | |
| 345 } | |
| 346 } while(r == -1); | |
| 347 | |
| 348 if(r < 0) | |
| 349 return -1; | |
| 350 if(r == 0) | |
| 351 return 0; | |
| 352 | |
| 353 ret = 0; | |
| 354 if(readfd0 != CURL_SOCKET_BAD) { | |
| 355 if(FD_ISSET(readfd0, &fds_read)) | |
| 356 ret |= CURL_CSELECT_IN; | |
| 357 if(FD_ISSET(readfd0, &fds_err)) | |
| 358 ret |= CURL_CSELECT_ERR; | |
| 359 } | |
| 360 if(readfd1 != CURL_SOCKET_BAD) { | |
| 361 if(FD_ISSET(readfd1, &fds_read)) | |
| 362 ret |= CURL_CSELECT_IN2; | |
| 363 if(FD_ISSET(readfd1, &fds_err)) | |
| 364 ret |= CURL_CSELECT_ERR; | |
| 365 } | |
| 366 if(writefd != CURL_SOCKET_BAD) { | |
| 367 if(FD_ISSET(writefd, &fds_write)) | |
| 368 ret |= CURL_CSELECT_OUT; | |
| 369 if(FD_ISSET(writefd, &fds_err)) | |
| 370 ret |= CURL_CSELECT_ERR; | |
| 371 } | |
| 372 | |
| 373 return ret; | |
| 374 | |
| 375 #endif /* HAVE_POLL_FINE */ | |
| 376 | |
| 377 } | |
| 378 | |
| 379 /* | |
| 380 * This is a wrapper around poll(). If poll() does not exist, then | |
| 381 * select() is used instead. An error is returned if select() is | |
| 382 * being used and a file descriptor is too large for FD_SETSIZE. | |
| 383 * A negative timeout value makes this function wait indefinitely, | |
| 384 * unless no valid file descriptor is given, when this happens the | |
| 385 * negative timeout is ignored and the function times out immediately. | |
| 386 * | |
| 387 * Return values: | |
| 388 * -1 = system call error or fd >= FD_SETSIZE | |
| 389 * 0 = timeout | |
| 390 * N = number of structures with non zero revent fields | |
| 391 */ | |
| 392 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms) | |
| 393 { | |
| 394 #ifndef HAVE_POLL_FINE | |
| 395 struct timeval pending_tv; | |
| 396 struct timeval *ptimeout; | |
| 397 fd_set fds_read; | |
| 398 fd_set fds_write; | |
| 399 fd_set fds_err; | |
| 400 curl_socket_t maxfd; | |
| 401 #endif | |
| 402 struct curltime initial_tv = {0, 0}; | |
| 403 bool fds_none = TRUE; | |
| 404 unsigned int i; | |
| 405 int pending_ms = 0; | |
| 406 int r; | |
| 407 | |
| 408 if(ufds) { | |
| 409 for(i = 0; i < nfds; i++) { | |
| 410 if(ufds[i].fd != CURL_SOCKET_BAD) { | |
| 411 fds_none = FALSE; | |
| 412 break; | |
| 413 } | |
| 414 } | |
| 415 } | |
| 416 if(fds_none) { | |
| 417 r = Curl_wait_ms(timeout_ms); | |
| 418 return r; | |
| 419 } | |
| 420 | |
| 421 /* Avoid initial timestamp, avoid Curl_now() call, when elapsed | |
| 422 time in this function does not need to be measured. This happens | |
| 423 when function is called with a zero timeout or a negative timeout | |
| 424 value indicating a blocking call should be performed. */ | |
| 425 | |
| 426 if(timeout_ms > 0) { | |
| 427 pending_ms = timeout_ms; | |
| 428 initial_tv = Curl_now(); | |
| 429 } | |
| 430 | |
| 431 #ifdef HAVE_POLL_FINE | |
| 432 | |
| 433 do { | |
| 434 int error; | |
| 435 if(timeout_ms < 0) | |
| 436 pending_ms = -1; | |
| 437 else if(!timeout_ms) | |
| 438 pending_ms = 0; | |
| 439 r = poll(ufds, nfds, pending_ms); | |
| 440 if(r != -1) | |
| 441 break; | |
| 442 error = SOCKERRNO; | |
| 443 if(error && ERROR_NOT_EINTR(error)) | |
| 444 break; | |
| 445 if(timeout_ms > 0) { | |
| 446 pending_ms = (int)(timeout_ms - ELAPSED_MS()); | |
| 447 if(pending_ms <= 0) { | |
| 448 r = 0; /* Simulate a "call timed out" case */ | |
| 449 break; | |
| 450 } | |
| 451 } | |
| 452 } while(r == -1); | |
| 453 | |
| 454 if(r < 0) | |
| 455 return -1; | |
| 456 if(r == 0) | |
| 457 return 0; | |
| 458 | |
| 459 for(i = 0; i < nfds; i++) { | |
| 460 if(ufds[i].fd == CURL_SOCKET_BAD) | |
| 461 continue; | |
| 462 if(ufds[i].revents & POLLHUP) | |
| 463 ufds[i].revents |= POLLIN; | |
| 464 if(ufds[i].revents & POLLERR) | |
| 465 ufds[i].revents |= (POLLIN|POLLOUT); | |
| 466 } | |
| 467 | |
| 468 #else /* HAVE_POLL_FINE */ | |
| 469 | |
| 470 FD_ZERO(&fds_read); | |
| 471 FD_ZERO(&fds_write); | |
| 472 FD_ZERO(&fds_err); | |
| 473 maxfd = (curl_socket_t)-1; | |
| 474 | |
| 475 for(i = 0; i < nfds; i++) { | |
| 476 ufds[i].revents = 0; | |
| 477 if(ufds[i].fd == CURL_SOCKET_BAD) | |
| 478 continue; | |
| 479 VERIFY_SOCK(ufds[i].fd); | |
| 480 if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI| | |
| 481 POLLRDNORM|POLLWRNORM|POLLRDBAND)) { | |
| 482 if(ufds[i].fd > maxfd) | |
| 483 maxfd = ufds[i].fd; | |
| 484 if(ufds[i].events & (POLLRDNORM|POLLIN)) | |
| 485 FD_SET(ufds[i].fd, &fds_read); | |
| 486 if(ufds[i].events & (POLLWRNORM|POLLOUT)) | |
| 487 FD_SET(ufds[i].fd, &fds_write); | |
| 488 if(ufds[i].events & (POLLRDBAND|POLLPRI)) | |
| 489 FD_SET(ufds[i].fd, &fds_err); | |
| 490 } | |
| 491 } | |
| 492 | |
| 493 #ifdef USE_WINSOCK | |
| 494 /* WinSock select() can't handle zero events. See the comment about this in | |
| 495 Curl_check_socket(). */ | |
| 496 if(fds_read.fd_count == 0 && fds_write.fd_count == 0 | |
| 497 && fds_err.fd_count == 0) { | |
| 498 r = Curl_wait_ms(timeout_ms); | |
| 499 return r; | |
| 500 } | |
| 501 #endif | |
| 502 | |
| 503 ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; | |
| 504 | |
| 505 do { | |
| 506 int error; | |
| 507 if(timeout_ms > 0) { | |
| 508 pending_tv.tv_sec = pending_ms / 1000; | |
| 509 pending_tv.tv_usec = (pending_ms % 1000) * 1000; | |
| 510 } | |
| 511 else if(!timeout_ms) { | |
| 512 pending_tv.tv_sec = 0; | |
| 513 pending_tv.tv_usec = 0; | |
| 514 } | |
| 515 | |
| 516 #ifdef USE_WINSOCK | |
| 517 r = select((int)maxfd + 1, | |
| 518 /* WinSock select() can't handle fd_sets with zero bits set, so | |
| 519 don't give it such arguments. See the comment about this in | |
| 520 Curl_check_socket(). | |
| 521 */ | |
| 522 fds_read.fd_count ? &fds_read : NULL, | |
| 523 fds_write.fd_count ? &fds_write : NULL, | |
| 524 fds_err.fd_count ? &fds_err : NULL, ptimeout); | |
| 525 #else | |
| 526 r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); | |
| 527 #endif | |
| 528 if(r != -1) | |
| 529 break; | |
| 530 error = SOCKERRNO; | |
| 531 if(error && ERROR_NOT_EINTR(error)) | |
| 532 break; | |
| 533 if(timeout_ms > 0) { | |
| 534 pending_ms = timeout_ms - ELAPSED_MS(); | |
| 535 if(pending_ms <= 0) { | |
| 536 r = 0; /* Simulate a "call timed out" case */ | |
| 537 break; | |
| 538 } | |
| 539 } | |
| 540 } while(r == -1); | |
| 541 | |
| 542 if(r < 0) | |
| 543 return -1; | |
| 544 if(r == 0) | |
| 545 return 0; | |
| 546 | |
| 547 r = 0; | |
| 548 for(i = 0; i < nfds; i++) { | |
| 549 ufds[i].revents = 0; | |
| 550 if(ufds[i].fd == CURL_SOCKET_BAD) | |
| 551 continue; | |
| 552 if(FD_ISSET(ufds[i].fd, &fds_read)) | |
| 553 ufds[i].revents |= POLLIN; | |
| 554 if(FD_ISSET(ufds[i].fd, &fds_write)) | |
| 555 ufds[i].revents |= POLLOUT; | |
| 556 if(FD_ISSET(ufds[i].fd, &fds_err)) | |
| 557 ufds[i].revents |= POLLPRI; | |
| 558 if(ufds[i].revents != 0) | |
| 559 r++; | |
| 560 } | |
| 561 | |
| 562 #endif /* HAVE_POLL_FINE */ | |
| 563 | |
| 564 return r; | |
| 565 } | |
| 566 | |
| 567 #ifdef TPF | |
| 568 /* | |
| 569 * This is a replacement for select() on the TPF platform. | |
| 570 * It is used whenever libcurl calls select(). | |
| 571 * The call below to tpf_process_signals() is required because | |
| 572 * TPF's select calls are not signal interruptible. | |
| 573 * | |
| 574 * Return values are the same as select's. | |
| 575 */ | |
| 576 int tpf_select_libcurl(int maxfds, fd_set *reads, fd_set *writes, | |
| 577 fd_set *excepts, struct timeval *tv) | |
| 578 { | |
| 579 int rc; | |
| 580 | |
| 581 rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv); | |
| 582 tpf_process_signals(); | |
| 583 return rc; | |
| 584 } | |
| 585 #endif /* TPF */ |
