pollfd.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /** @file pollfd.c
  2. */
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <assert.h>
  8. #include <unistd.h>
  9. #include <errno.h>
  10. #include <sys/types.h>
  11. #include <poll.h>
  12. #include "faux/faux.h"
  13. #include "faux/net.h"
  14. #include "faux/vec.h"
  15. #include "private.h"
  16. /** @brief Callback function to search specified fd within pollfd structures.
  17. */
  18. static int cmp_by_fd(const void *key, const void *item)
  19. {
  20. int k = *(int *)key;
  21. struct pollfd *i = (struct pollfd *)item;
  22. if (k == i->fd)
  23. return 0;
  24. return -1;
  25. }
  26. /** @brief Allocates memory for faux_pollfd_t object.
  27. *
  28. * @return Allocated faux_pollfd_t object or NULL on error.
  29. */
  30. faux_pollfd_t *faux_pollfd_new(void)
  31. {
  32. faux_pollfd_t *faux_pollfd = NULL;
  33. faux_pollfd = faux_zmalloc(sizeof(*faux_pollfd));
  34. assert(faux_pollfd);
  35. if (!faux_pollfd)
  36. return NULL;
  37. faux_pollfd->vec = faux_vec_new(sizeof(struct pollfd), cmp_by_fd);
  38. return faux_pollfd;
  39. }
  40. /** @brief Frees previously allocated faux_pollfd_t object.
  41. *
  42. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  43. */
  44. void faux_pollfd_free(faux_pollfd_t *faux_pollfd)
  45. {
  46. if (!faux_pollfd)
  47. return;
  48. faux_vec_free(faux_pollfd->vec);
  49. faux_free(faux_pollfd);
  50. }
  51. /** @brief Returns whole "struct pollfd" vector.
  52. *
  53. * It can be used while poll() call.
  54. *
  55. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  56. * @return Pointer to "struct pollfd" vector or NULL on error.
  57. */
  58. struct pollfd *faux_pollfd_vector(faux_pollfd_t *faux_pollfd)
  59. {
  60. assert(faux_pollfd);
  61. if (!faux_pollfd)
  62. return NULL;
  63. return faux_vec_data(faux_pollfd->vec);
  64. }
  65. /** @brief Returns number of "struct pollfd" items within object.
  66. *
  67. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  68. * @return Number of items.
  69. */
  70. size_t faux_pollfd_len(faux_pollfd_t *faux_pollfd)
  71. {
  72. assert(faux_pollfd);
  73. if (!faux_pollfd)
  74. return 0;
  75. return faux_vec_len(faux_pollfd->vec);
  76. }
  77. /** @brief Returns "struct pollfd" item by specified index.
  78. *
  79. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  80. * @param [in] index Index of item to get.
  81. * @return Pointer to item or NULL on error.
  82. */
  83. struct pollfd *faux_pollfd_item(faux_pollfd_t *faux_pollfd, unsigned int index)
  84. {
  85. assert(faux_pollfd);
  86. if (!faux_pollfd)
  87. return NULL;
  88. return (struct pollfd *)faux_vec_item(faux_pollfd->vec, index);
  89. }
  90. /** @brief Finds item with specified fd value.
  91. *
  92. * File descriptor is a key for array. Object can contain the only one item
  93. * with the same fd value.
  94. *
  95. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  96. * @param [in] fd File descriptor to search for.
  97. * @return Pointer to found item or NULL on error or in "not found" case.
  98. */
  99. struct pollfd *faux_pollfd_find(faux_pollfd_t *faux_pollfd, int fd)
  100. {
  101. int index = 0;
  102. assert(faux_pollfd);
  103. if (!faux_pollfd)
  104. return NULL;
  105. assert(fd >= 0);
  106. if (fd < 0)
  107. return NULL;
  108. index = faux_vec_find(faux_pollfd->vec, &fd, 0);
  109. if (index < 0)
  110. return NULL;
  111. return (struct pollfd *)faux_vec_item(faux_pollfd->vec, index);
  112. }
  113. /** @brief Adds new item to object.
  114. *
  115. * The file descriptors are unique within array. So function try to find item
  116. * with the specified fd. If it's found the correspondent item will be returned
  117. * but new item will not be created.
  118. *
  119. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  120. * @param [in] fd File descriptor to set to newly created item.
  121. * @param [in] events The events interested in.
  122. * @return Pointer to new item or NULL on error.
  123. */
  124. struct pollfd *faux_pollfd_add(faux_pollfd_t *faux_pollfd, int fd, short events)
  125. {
  126. struct pollfd *pollfd = NULL;
  127. assert(faux_pollfd);
  128. if (!faux_pollfd)
  129. return NULL;
  130. assert(fd >= 0);
  131. if (fd < 0)
  132. return NULL;
  133. // Don't add duplicated fd
  134. pollfd = faux_pollfd_find(faux_pollfd, fd);
  135. if (!pollfd) {
  136. // Create new item
  137. pollfd = faux_vec_add(faux_pollfd->vec);
  138. assert(pollfd);
  139. if (!pollfd)
  140. return NULL;
  141. pollfd->fd = fd;
  142. }
  143. pollfd->events = events;
  144. pollfd->revents = 0;
  145. return pollfd;
  146. }
  147. /** @brief Removes item specified by fd.
  148. *
  149. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  150. * @param [in] fd File descriptor to remove.
  151. * @return BOOL_TRUE - success, BOOL_FALSE on error.
  152. */
  153. bool_t faux_pollfd_del_by_fd(faux_pollfd_t *faux_pollfd, int fd)
  154. {
  155. int index = 0;
  156. assert(faux_pollfd);
  157. if (!faux_pollfd)
  158. return BOOL_FALSE;
  159. assert(fd >= 0);
  160. if (fd < 0)
  161. return BOOL_FALSE;
  162. index = faux_vec_find(faux_pollfd->vec, &fd, 0);
  163. if (index < 0) // Not found
  164. return BOOL_FALSE;
  165. if (faux_vec_del(faux_pollfd->vec, index) < 0)
  166. return BOOL_FALSE;
  167. return BOOL_TRUE;
  168. }
  169. /** @brief Removes item specified by index.
  170. *
  171. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  172. * @param [in] index Index of item to remove.
  173. * @return BOOL_TRUE - success, BOOL_FALSE on error.
  174. */
  175. bool_t faux_pollfd_del_by_index(faux_pollfd_t *faux_pollfd, unsigned int index)
  176. {
  177. assert(faux_pollfd);
  178. if (!faux_pollfd)
  179. return BOOL_FALSE;
  180. if (faux_vec_del(faux_pollfd->vec, index) < 0)
  181. return BOOL_FALSE;
  182. return BOOL_TRUE;
  183. }
  184. /** @brief Initilizes iterator to iterate through all the vector.
  185. *
  186. * @sa faux_pollfd_each()
  187. * @sa faux_pollfd_each_active()
  188. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  189. * @param [out] iterator Iterator to initialize.
  190. */
  191. void faux_pollfd_init_iterator(faux_pollfd_t *faux_pollfd, faux_pollfd_iterator_t *iterator)
  192. {
  193. assert(faux_pollfd);
  194. if (!faux_pollfd)
  195. return;
  196. if (!iterator)
  197. return;
  198. *iterator = 0;
  199. }
  200. /** @brief Iterate through all the vector.
  201. *
  202. * The iterator must be initialized first by faux_pollfd_init_iterator().
  203. *
  204. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  205. * @param [out] iterator Initialized iterator.
  206. * @return Pointer to item or NULL on error or on end of vector.
  207. */
  208. struct pollfd *faux_pollfd_each(faux_pollfd_t *faux_pollfd, faux_pollfd_iterator_t *iterator)
  209. {
  210. unsigned int old_iterator = 0;
  211. assert(faux_pollfd);
  212. if (!faux_pollfd)
  213. return NULL;
  214. if (!iterator)
  215. return NULL;
  216. old_iterator = *iterator;
  217. (*iterator)++;
  218. return faux_pollfd_item(faux_pollfd, old_iterator);
  219. }
  220. /** @brief Iterate through all active items of vector.
  221. *
  222. * The iterator must be initialized first by faux_pollfd_init_iterator().
  223. * Function returns items that has non-null value in "revent" field i.e.
  224. * active items.
  225. *
  226. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  227. * @param [out] iterator Initialized iterator.
  228. * @return Pointer to active item or NULL on error or on end of vector.
  229. */
  230. struct pollfd *faux_pollfd_each_active(faux_pollfd_t *faux_pollfd, faux_pollfd_iterator_t *iterator)
  231. {
  232. struct pollfd *pollfd = NULL;
  233. assert(faux_pollfd);
  234. if (!faux_pollfd)
  235. return NULL;
  236. if (!iterator)
  237. return NULL;
  238. while ((pollfd = faux_pollfd_each(faux_pollfd, iterator))) {
  239. if (pollfd->revents != 0)
  240. return pollfd;
  241. }
  242. return NULL;
  243. }
  244. /** @brief Deletes all items from pollfd object.
  245. *
  246. * @param [in] faux_pollfd Allocated faux_pollfd_t object.
  247. * @return BOOL_TRUE - success, BOOL_FALSE on error.
  248. */
  249. bool_t faux_pollfd_del_all(faux_pollfd_t *faux_pollfd)
  250. {
  251. assert(faux_pollfd);
  252. if (!faux_pollfd)
  253. return BOOL_FALSE;
  254. faux_vec_del_all(faux_pollfd->vec);
  255. return BOOL_TRUE;
  256. }