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