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