fakepoll.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /* Copyright 2002,2003 Nick Mathewson, Roger Dingledine */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. /**
  5. * \file fakepoll.c
  6. *
  7. * \brief On systems where poll() doesn't exist, fake it with select().
  8. **/
  9. #include "orconfig.h"
  10. #include "fakepoll.h"
  11. #ifdef HAVE_SYS_TYPES_H
  12. #include <sys/types.h>
  13. #endif
  14. #ifdef HAVE_UNISTD_H
  15. #include <unistd.h>
  16. #endif
  17. #ifdef HAVE_STRING_H
  18. #include <string.h>
  19. #endif
  20. #ifdef HAVE_SYS_TIME_H
  21. #include <sys/time.h>
  22. #endif
  23. #if _MSC_VER > 1300
  24. #include <winsock2.h>
  25. #include <ws2tcpip.h>
  26. #elif defined(_MSC_VER)
  27. #include <winsock.h>
  28. #endif
  29. #include <assert.h>
  30. #include <stdlib.h>
  31. #include "util.h"
  32. #include "log.h"
  33. #ifndef USE_FAKE_POLL
  34. int
  35. tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout)
  36. {
  37. int i;
  38. for (i=0;i<nfds;++i) {
  39. tor_assert(ufds[i].fd >= 0);
  40. }
  41. return poll(ufds,nfds,timeout);
  42. }
  43. #else
  44. #define FD_SETSIZE MAXCONNECTIONS
  45. int
  46. tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout)
  47. {
  48. unsigned int idx;
  49. int maxfd, fd;
  50. int r;
  51. #ifdef MS_WINDOWS
  52. int any_fds_set = 0;
  53. #endif
  54. fd_set readfds, writefds, exceptfds;
  55. #ifdef USING_FAKE_TIMEVAL
  56. #undef timeval
  57. #undef tv_sec
  58. #undef tv_usec
  59. #endif
  60. struct timeval _timeout;
  61. _timeout.tv_sec = timeout/1000;
  62. _timeout.tv_usec = (timeout%1000)*1000;
  63. FD_ZERO(&readfds);
  64. FD_ZERO(&writefds);
  65. FD_ZERO(&exceptfds);
  66. maxfd = -1;
  67. for (idx = 0; idx < nfds; ++idx) {
  68. ufds[idx].revents = 0;
  69. fd = ufds[idx].fd;
  70. tor_assert(fd >= 0);
  71. if (fd > maxfd) {
  72. maxfd = fd;
  73. #ifdef MS_WINDOWS
  74. any_fds_set = 1;
  75. #endif
  76. }
  77. if (ufds[idx].events & POLLIN)
  78. FD_SET(fd, &readfds);
  79. if (ufds[idx].events & POLLOUT)
  80. FD_SET(fd, &writefds);
  81. FD_SET(fd, &exceptfds);
  82. }
  83. #ifdef MS_WINDOWS
  84. if (!any_fds_set) {
  85. Sleep(timeout);
  86. return 0;
  87. }
  88. #endif
  89. r = select(maxfd+1, &readfds, &writefds, &exceptfds,
  90. timeout == -1 ? NULL : &_timeout);
  91. if (r <= 0)
  92. return r;
  93. r = 0;
  94. for (idx = 0; idx < nfds; ++idx) {
  95. fd = ufds[idx].fd;
  96. if (FD_ISSET(fd, &readfds))
  97. ufds[idx].revents |= POLLIN;
  98. if (FD_ISSET(fd, &writefds))
  99. ufds[idx].revents |= POLLOUT;
  100. if (FD_ISSET(fd, &exceptfds))
  101. ufds[idx].revents |= POLLERR;
  102. if (ufds[idx].revents)
  103. ++r;
  104. }
  105. return r;
  106. }
  107. #endif
  108. /*
  109. Local Variables:
  110. mode:c
  111. indent-tabs-mode:nil
  112. c-basic-offset:2
  113. End:
  114. */