诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

517 lines
13 KiB

  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2012, 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. #include "curl_setup.h"
  23. #ifdef HAVE_SYS_SELECT_H
  24. #include <sys/select.h>
  25. #endif
  26. #if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
  27. #error "We can't compile without select() or poll() support."
  28. #endif
  29. #if defined(__BEOS__) && !defined(__HAIKU__)
  30. /* BeOS has FD_SET defined in socket.h */
  31. #include <socket.h>
  32. #endif
  33. #ifdef MSDOS
  34. #include <dos.h> /* delay() */
  35. #endif
  36. #include <curl/curl.h>
  37. #include "urldata.h"
  38. #include "connect.h"
  39. #include "select.h"
  40. #include "warnless.h"
  41. /* Convenience local macros */
  42. #define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
  43. int Curl_ack_eintr = 0;
  44. #define error_not_EINTR (Curl_ack_eintr || error != EINTR)
  45. /*
  46. * Internal function used for waiting a specific amount of ms
  47. * in Curl_socket_ready() and Curl_poll() when no file descriptor
  48. * is provided to wait on, just being used to delay execution.
  49. * WinSock select() and poll() timeout mechanisms need a valid
  50. * socket descriptor in a not null file descriptor set to work.
  51. * Waiting indefinitely with this function is not allowed, a
  52. * zero or negative timeout value will return immediately.
  53. * Timeout resolution, accuracy, as well as maximum supported
  54. * value is system dependent, neither factor is a citical issue
  55. * for the intended use of this function in the library.
  56. *
  57. * Return values:
  58. * -1 = system call error, invalid timeout value, or interrupted
  59. * 0 = specified timeout has elapsed
  60. */
  61. int Curl_wait_ms(int timeout_ms)
  62. {
  63. #if !defined(MSDOS) && !defined(USE_WINSOCK)
  64. #ifndef HAVE_POLL_FINE
  65. struct timeval pending_tv;
  66. #endif
  67. struct timeval initial_tv;
  68. int pending_ms;
  69. int error;
  70. #endif
  71. int r = 0;
  72. if(!timeout_ms)
  73. return 0;
  74. if(timeout_ms < 0) {
  75. SET_SOCKERRNO(EINVAL);
  76. return -1;
  77. }
  78. #if defined(MSDOS)
  79. delay(timeout_ms);
  80. #elif defined(USE_WINSOCK)
  81. Sleep(timeout_ms);
  82. #else
  83. pending_ms = timeout_ms;
  84. initial_tv = curlx_tvnow();
  85. do {
  86. #if defined(HAVE_POLL_FINE)
  87. r = poll(NULL, 0, pending_ms);
  88. #else
  89. pending_tv.tv_sec = pending_ms / 1000;
  90. pending_tv.tv_usec = (pending_ms % 1000) * 1000;
  91. r = select(0, NULL, NULL, NULL, &pending_tv);
  92. #endif /* HAVE_POLL_FINE */
  93. if(r != -1)
  94. break;
  95. error = SOCKERRNO;
  96. if(error && error_not_EINTR)
  97. break;
  98. pending_ms = timeout_ms - elapsed_ms;
  99. if(pending_ms <= 0)
  100. break;
  101. } while(r == -1);
  102. #endif /* USE_WINSOCK */
  103. if(r)
  104. r = -1;
  105. return r;
  106. }
  107. /*
  108. * Wait for read or write events on a set of file descriptors. It uses poll()
  109. * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
  110. * otherwise select() is used. An error is returned if select() is being used
  111. * and a file descriptor is too large for FD_SETSIZE.
  112. *
  113. * A negative timeout value makes this function wait indefinitely,
  114. * unles no valid file descriptor is given, when this happens the
  115. * negative timeout is ignored and the function times out immediately.
  116. *
  117. * Return values:
  118. * -1 = system call error or fd >= FD_SETSIZE
  119. * 0 = timeout
  120. * [bitmask] = action as described below
  121. *
  122. * CURL_CSELECT_IN - first socket is readable
  123. * CURL_CSELECT_IN2 - second socket is readable
  124. * CURL_CSELECT_OUT - write socket is writable
  125. * CURL_CSELECT_ERR - an error condition occurred
  126. */
  127. int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
  128. curl_socket_t readfd1,
  129. curl_socket_t writefd, /* socket to write to */
  130. long timeout_ms) /* milliseconds to wait */
  131. {
  132. #ifdef HAVE_POLL_FINE
  133. struct pollfd pfd[3];
  134. int num;
  135. #else
  136. struct timeval pending_tv;
  137. struct timeval *ptimeout;
  138. fd_set fds_read;
  139. fd_set fds_write;
  140. fd_set fds_err;
  141. curl_socket_t maxfd;
  142. #endif
  143. struct timeval initial_tv = {0,0};
  144. int pending_ms = 0;
  145. int error;
  146. int r;
  147. int ret;
  148. if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
  149. (writefd == CURL_SOCKET_BAD)) {
  150. /* no sockets, just wait */
  151. r = Curl_wait_ms((int)timeout_ms);
  152. return r;
  153. }
  154. /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
  155. time in this function does not need to be measured. This happens
  156. when function is called with a zero timeout or a negative timeout
  157. value indicating a blocking call should be performed. */
  158. if(timeout_ms > 0) {
  159. pending_ms = (int)timeout_ms;
  160. initial_tv = curlx_tvnow();
  161. }
  162. #ifdef HAVE_POLL_FINE
  163. num = 0;
  164. if(readfd0 != CURL_SOCKET_BAD) {
  165. pfd[num].fd = readfd0;
  166. pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
  167. pfd[num].revents = 0;
  168. num++;
  169. }
  170. if(readfd1 != CURL_SOCKET_BAD) {
  171. pfd[num].fd = readfd1;
  172. pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
  173. pfd[num].revents = 0;
  174. num++;
  175. }
  176. if(writefd != CURL_SOCKET_BAD) {
  177. pfd[num].fd = writefd;
  178. pfd[num].events = POLLWRNORM|POLLOUT;
  179. pfd[num].revents = 0;
  180. num++;
  181. }
  182. do {
  183. if(timeout_ms < 0)
  184. pending_ms = -1;
  185. else if(!timeout_ms)
  186. pending_ms = 0;
  187. r = poll(pfd, num, pending_ms);
  188. if(r != -1)
  189. break;
  190. error = SOCKERRNO;
  191. if(error && error_not_EINTR)
  192. break;
  193. if(timeout_ms > 0) {
  194. pending_ms = (int)(timeout_ms - elapsed_ms);
  195. if(pending_ms <= 0) {
  196. r = 0; /* Simulate a "call timed out" case */
  197. break;
  198. }
  199. }
  200. } while(r == -1);
  201. if(r < 0)
  202. return -1;
  203. if(r == 0)
  204. return 0;
  205. ret = 0;
  206. num = 0;
  207. if(readfd0 != CURL_SOCKET_BAD) {
  208. if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
  209. ret |= CURL_CSELECT_IN;
  210. if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
  211. ret |= CURL_CSELECT_ERR;
  212. num++;
  213. }
  214. if(readfd1 != CURL_SOCKET_BAD) {
  215. if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
  216. ret |= CURL_CSELECT_IN2;
  217. if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
  218. ret |= CURL_CSELECT_ERR;
  219. num++;
  220. }
  221. if(writefd != CURL_SOCKET_BAD) {
  222. if(pfd[num].revents & (POLLWRNORM|POLLOUT))
  223. ret |= CURL_CSELECT_OUT;
  224. if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
  225. ret |= CURL_CSELECT_ERR;
  226. }
  227. return ret;
  228. #else /* HAVE_POLL_FINE */
  229. FD_ZERO(&fds_err);
  230. maxfd = (curl_socket_t)-1;
  231. FD_ZERO(&fds_read);
  232. if(readfd0 != CURL_SOCKET_BAD) {
  233. VERIFY_SOCK(readfd0);
  234. FD_SET(readfd0, &fds_read);
  235. FD_SET(readfd0, &fds_err);
  236. maxfd = readfd0;
  237. }
  238. if(readfd1 != CURL_SOCKET_BAD) {
  239. VERIFY_SOCK(readfd1);
  240. FD_SET(readfd1, &fds_read);
  241. FD_SET(readfd1, &fds_err);
  242. if(readfd1 > maxfd)
  243. maxfd = readfd1;
  244. }
  245. FD_ZERO(&fds_write);
  246. if(writefd != CURL_SOCKET_BAD) {
  247. VERIFY_SOCK(writefd);
  248. FD_SET(writefd, &fds_write);
  249. FD_SET(writefd, &fds_err);
  250. if(writefd > maxfd)
  251. maxfd = writefd;
  252. }
  253. ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
  254. do {
  255. if(timeout_ms > 0) {
  256. pending_tv.tv_sec = pending_ms / 1000;
  257. pending_tv.tv_usec = (pending_ms % 1000) * 1000;
  258. }
  259. else if(!timeout_ms) {
  260. pending_tv.tv_sec = 0;
  261. pending_tv.tv_usec = 0;
  262. }
  263. r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
  264. if(r != -1)
  265. break;
  266. error = SOCKERRNO;
  267. if(error && error_not_EINTR)
  268. break;
  269. if(timeout_ms > 0) {
  270. pending_ms = timeout_ms - elapsed_ms;
  271. if(pending_ms <= 0) {
  272. r = 0; /* Simulate a "call timed out" case */
  273. break;
  274. }
  275. }
  276. } while(r == -1);
  277. if(r < 0)
  278. return -1;
  279. if(r == 0)
  280. return 0;
  281. ret = 0;
  282. if(readfd0 != CURL_SOCKET_BAD) {
  283. if(FD_ISSET(readfd0, &fds_read))
  284. ret |= CURL_CSELECT_IN;
  285. if(FD_ISSET(readfd0, &fds_err))
  286. ret |= CURL_CSELECT_ERR;
  287. }
  288. if(readfd1 != CURL_SOCKET_BAD) {
  289. if(FD_ISSET(readfd1, &fds_read))
  290. ret |= CURL_CSELECT_IN2;
  291. if(FD_ISSET(readfd1, &fds_err))
  292. ret |= CURL_CSELECT_ERR;
  293. }
  294. if(writefd != CURL_SOCKET_BAD) {
  295. if(FD_ISSET(writefd, &fds_write))
  296. ret |= CURL_CSELECT_OUT;
  297. if(FD_ISSET(writefd, &fds_err))
  298. ret |= CURL_CSELECT_ERR;
  299. }
  300. return ret;
  301. #endif /* HAVE_POLL_FINE */
  302. }
  303. /*
  304. * This is a wrapper around poll(). If poll() does not exist, then
  305. * select() is used instead. An error is returned if select() is
  306. * being used and a file descriptor is too large for FD_SETSIZE.
  307. * A negative timeout value makes this function wait indefinitely,
  308. * unles no valid file descriptor is given, when this happens the
  309. * negative timeout is ignored and the function times out immediately.
  310. *
  311. * Return values:
  312. * -1 = system call error or fd >= FD_SETSIZE
  313. * 0 = timeout
  314. * N = number of structures with non zero revent fields
  315. */
  316. int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
  317. {
  318. #ifndef HAVE_POLL_FINE
  319. struct timeval pending_tv;
  320. struct timeval *ptimeout;
  321. fd_set fds_read;
  322. fd_set fds_write;
  323. fd_set fds_err;
  324. curl_socket_t maxfd;
  325. #endif
  326. struct timeval initial_tv = {0,0};
  327. bool fds_none = TRUE;
  328. unsigned int i;
  329. int pending_ms = 0;
  330. int error;
  331. int r;
  332. if(ufds) {
  333. for(i = 0; i < nfds; i++) {
  334. if(ufds[i].fd != CURL_SOCKET_BAD) {
  335. fds_none = FALSE;
  336. break;
  337. }
  338. }
  339. }
  340. if(fds_none) {
  341. r = Curl_wait_ms(timeout_ms);
  342. return r;
  343. }
  344. /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
  345. time in this function does not need to be measured. This happens
  346. when function is called with a zero timeout or a negative timeout
  347. value indicating a blocking call should be performed. */
  348. if(timeout_ms > 0) {
  349. pending_ms = timeout_ms;
  350. initial_tv = curlx_tvnow();
  351. }
  352. #ifdef HAVE_POLL_FINE
  353. do {
  354. if(timeout_ms < 0)
  355. pending_ms = -1;
  356. else if(!timeout_ms)
  357. pending_ms = 0;
  358. r = poll(ufds, nfds, pending_ms);
  359. if(r != -1)
  360. break;
  361. error = SOCKERRNO;
  362. if(error && error_not_EINTR)
  363. break;
  364. if(timeout_ms > 0) {
  365. pending_ms = timeout_ms - elapsed_ms;
  366. if(pending_ms <= 0)
  367. break;
  368. }
  369. } while(r == -1);
  370. if(r < 0)
  371. return -1;
  372. if(r == 0)
  373. return 0;
  374. for(i = 0; i < nfds; i++) {
  375. if(ufds[i].fd == CURL_SOCKET_BAD)
  376. continue;
  377. if(ufds[i].revents & POLLHUP)
  378. ufds[i].revents |= POLLIN;
  379. if(ufds[i].revents & POLLERR)
  380. ufds[i].revents |= (POLLIN|POLLOUT);
  381. }
  382. #else /* HAVE_POLL_FINE */
  383. FD_ZERO(&fds_read);
  384. FD_ZERO(&fds_write);
  385. FD_ZERO(&fds_err);
  386. maxfd = (curl_socket_t)-1;
  387. for(i = 0; i < nfds; i++) {
  388. ufds[i].revents = 0;
  389. if(ufds[i].fd == CURL_SOCKET_BAD)
  390. continue;
  391. VERIFY_SOCK(ufds[i].fd);
  392. if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
  393. POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
  394. if(ufds[i].fd > maxfd)
  395. maxfd = ufds[i].fd;
  396. if(ufds[i].events & (POLLRDNORM|POLLIN))
  397. FD_SET(ufds[i].fd, &fds_read);
  398. if(ufds[i].events & (POLLWRNORM|POLLOUT))
  399. FD_SET(ufds[i].fd, &fds_write);
  400. if(ufds[i].events & (POLLRDBAND|POLLPRI))
  401. FD_SET(ufds[i].fd, &fds_err);
  402. }
  403. }
  404. ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
  405. do {
  406. if(timeout_ms > 0) {
  407. pending_tv.tv_sec = pending_ms / 1000;
  408. pending_tv.tv_usec = (pending_ms % 1000) * 1000;
  409. }
  410. else if(!timeout_ms) {
  411. pending_tv.tv_sec = 0;
  412. pending_tv.tv_usec = 0;
  413. }
  414. r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
  415. if(r != -1)
  416. break;
  417. error = SOCKERRNO;
  418. if(error && error_not_EINTR)
  419. break;
  420. if(timeout_ms > 0) {
  421. pending_ms = timeout_ms - elapsed_ms;
  422. if(pending_ms <= 0)
  423. break;
  424. }
  425. } while(r == -1);
  426. if(r < 0)
  427. return -1;
  428. if(r == 0)
  429. return 0;
  430. r = 0;
  431. for(i = 0; i < nfds; i++) {
  432. ufds[i].revents = 0;
  433. if(ufds[i].fd == CURL_SOCKET_BAD)
  434. continue;
  435. if(FD_ISSET(ufds[i].fd, &fds_read))
  436. ufds[i].revents |= POLLIN;
  437. if(FD_ISSET(ufds[i].fd, &fds_write))
  438. ufds[i].revents |= POLLOUT;
  439. if(FD_ISSET(ufds[i].fd, &fds_err))
  440. ufds[i].revents |= POLLPRI;
  441. if(ufds[i].revents != 0)
  442. r++;
  443. }
  444. #endif /* HAVE_POLL_FINE */
  445. return r;
  446. }
  447. #ifdef TPF
  448. /*
  449. * This is a replacement for select() on the TPF platform.
  450. * It is used whenever libcurl calls select().
  451. * The call below to tpf_process_signals() is required because
  452. * TPF's select calls are not signal interruptible.
  453. *
  454. * Return values are the same as select's.
  455. */
  456. int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
  457. fd_set* excepts, struct timeval* tv)
  458. {
  459. int rc;
  460. rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
  461. tpf_process_signals();
  462. return(rc);
  463. }
  464. #endif /* TPF */