fakepoll.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * fakepoll.c
  3. *
  4. * On systems where 'poll' doesn't exist, fake it with 'select'.
  5. *
  6. * Nick Mathewson <nickm@freehaven.net>
  7. */
  8. #include "orconfig.h"
  9. #include "fakepoll.h"
  10. #ifdef USE_FAKE_POLL
  11. #include <sys/types.h>
  12. #ifdef HAVE_UNISTD_H
  13. #include <unistd.h>
  14. #endif
  15. #ifdef HAVE_STRING_H
  16. #include <string.h>
  17. #endif
  18. #if _MSC_VER > 1300
  19. #include <winsock2.h>
  20. #include <ws2tcpip.h>
  21. #elif defined(_MSC_VER)
  22. #include <winsock.h>
  23. #endif
  24. /* by default, windows handles only 64 fd's */
  25. #if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
  26. #define FD_SETSIZE MAXCONNECTIONS
  27. #endif
  28. #include "util.h"
  29. int
  30. poll(struct pollfd *ufds, unsigned int nfds, int timeout)
  31. {
  32. int idx, maxfd, fd;
  33. int r;
  34. #ifdef MS_WINDOWS
  35. int any_fds_set = 0;
  36. #endif
  37. fd_set readfds, writefds, exceptfds;
  38. #ifdef USING_FAKE_TIMEVAL
  39. #undef timeval
  40. #undef tv_sec
  41. #undef tv_usec
  42. #endif
  43. struct timeval _timeout;
  44. _timeout.tv_sec = timeout/1000;
  45. _timeout.tv_usec = (timeout%1000)*1000;
  46. FD_ZERO(&readfds);
  47. FD_ZERO(&writefds);
  48. FD_ZERO(&exceptfds);
  49. maxfd = -1;
  50. for (idx = 0; idx < nfds; ++idx) {
  51. ufds[idx].revents = 0;
  52. fd = ufds[idx].fd;
  53. if (fd > maxfd) {
  54. maxfd = fd;
  55. #ifdef MS_WINDOWS
  56. any_fds_set = 1;
  57. #endif
  58. }
  59. if (ufds[idx].events & POLLIN)
  60. FD_SET(fd, &readfds);
  61. if (ufds[idx].events & POLLOUT)
  62. FD_SET(fd, &writefds);
  63. FD_SET(fd, &exceptfds);
  64. }
  65. #ifdef MS_WINDOWS
  66. if (!any_fds_set) {
  67. Sleep(timeout);
  68. return 0;
  69. }
  70. #endif
  71. r = select(maxfd+1, &readfds, &writefds, &exceptfds,
  72. timeout == -1 ? NULL : &_timeout);
  73. if (r <= 0)
  74. return r;
  75. r = 0;
  76. for (idx = 0; idx < nfds; ++idx) {
  77. fd = ufds[idx].fd;
  78. if (FD_ISSET(fd, &readfds))
  79. ufds[idx].revents |= POLLIN;
  80. if (FD_ISSET(fd, &writefds))
  81. ufds[idx].revents |= POLLOUT;
  82. if (FD_ISSET(fd, &exceptfds))
  83. ufds[idx].revents |= POLLERR;
  84. if (ufds[idx].revents)
  85. ++r;
  86. }
  87. return r;
  88. }
  89. #endif