net.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /** @file net.c
  2. * @brief Class for comfortable send and receive data to and from socket.
  3. * Class supports timeout for all receive, send functions. It supports signal
  4. * mask to specify signals that can interrupt send/receive operation. It
  5. * supports isbreak_func() callback function for consistent working with
  6. * signals and remove race conditions. It's hard to specify all necessary
  7. * parameter as a function argument so class hides long functions from user.
  8. * Parameters of sending or receving can be specified using class methods.
  9. */
  10. #include <stdlib.h>
  11. #include <stdint.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <assert.h>
  15. #include <unistd.h>
  16. #include <errno.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <fcntl.h>
  20. #include <sys/socket.h>
  21. #include <sys/un.h>
  22. #include <arpa/inet.h>
  23. #include <time.h>
  24. #include <signal.h>
  25. #include "faux/faux.h"
  26. #include "faux/str.h"
  27. #include "faux/net.h"
  28. #include "private.h"
  29. /** @brief Allocates memory for faux_net_t object.
  30. *
  31. * @return Allocated faux_net_t object or NULL on error.
  32. */
  33. faux_net_t *faux_net_new(void)
  34. {
  35. faux_net_t *faux_net = NULL;
  36. faux_net = faux_zmalloc(sizeof(*faux_net));
  37. assert(faux_net);
  38. if (!faux_net)
  39. return NULL;
  40. faux_net->fd = -1;
  41. faux_net->isbreak_func = NULL;
  42. faux_net_sigmask_fill(faux_net);
  43. faux_net_set_timeout(faux_net, NULL);
  44. return faux_net;
  45. }
  46. /** @brief Frees previously allocated faux_net_t object.
  47. *
  48. * @param [in] faux_net Allocated faux_net_t object.
  49. */
  50. void faux_net_free(faux_net_t *faux_net)
  51. {
  52. if (!faux_net)
  53. return;
  54. faux_free(faux_net);
  55. }
  56. /** @brief Sets system descriptor to work with.
  57. *
  58. * It's a socket descriptor. Object will operate over this descriptor.
  59. *
  60. * @param [in] faux_net The faux_net_t object.
  61. * @param [in] fd The descriptor to link object to it.
  62. */
  63. void faux_net_set_fd(faux_net_t *faux_net, int fd)
  64. {
  65. if (!faux_net)
  66. return;
  67. faux_net->fd = fd;
  68. }
  69. /** @brief Gets file descriptor from object.
  70. *
  71. * @param [in] faux_net The faux_net_t object.
  72. * @return File descriptor from object.
  73. */
  74. int faux_net_get_fd(faux_net_t *faux_net)
  75. {
  76. if (!faux_net)
  77. return -1;
  78. return faux_net->fd;
  79. }
  80. /** @brief Sets timeout for send operation.
  81. *
  82. * @param [in] faux_net The faux_net_t object.
  83. * @param [in] send_timeout Timeout to set.
  84. */
  85. void faux_net_set_send_timeout(faux_net_t *faux_net, struct timespec *send_timeout)
  86. {
  87. assert(faux_net);
  88. if (!faux_net)
  89. return;
  90. if (!send_timeout) {
  91. faux_net->send_timeout = NULL;
  92. } else {
  93. faux_net->send_timeout_val = *send_timeout;
  94. faux_net->send_timeout = &faux_net->send_timeout_val;
  95. }
  96. }
  97. /** @brief Sets timeout for receive operation.
  98. *
  99. * @param [in] faux_net The faux_net_t object.
  100. * @param [in] send_timeout Timeout to set.
  101. */
  102. void faux_net_set_recv_timeout(faux_net_t *faux_net, struct timespec *recv_timeout)
  103. {
  104. assert(faux_net);
  105. if (!faux_net)
  106. return;
  107. if (!recv_timeout) {
  108. faux_net->recv_timeout = NULL;
  109. } else {
  110. faux_net->recv_timeout_val = *recv_timeout;
  111. faux_net->recv_timeout = &faux_net->recv_timeout_val;
  112. }
  113. }
  114. /** @brief Sets timeout both for send and receive operation.
  115. *
  116. * @param [in] faux_net The faux_net_t object.
  117. * @param [in] send_timeout Timeout to set.
  118. */
  119. void faux_net_set_timeout(faux_net_t *faux_net, struct timespec *timeout)
  120. {
  121. assert(faux_net);
  122. if (!faux_net)
  123. return;
  124. faux_net_set_send_timeout(faux_net, timeout);
  125. faux_net_set_recv_timeout(faux_net, timeout);
  126. }
  127. /** @brief Sets isbreak_func() funtion for network operation.
  128. *
  129. * Callback function informs network functions to interrupt actions.
  130. * See faux_send_block() function for explanation.
  131. *
  132. * @sa faux_send_block()
  133. * @param [in] faux_net The faux_net_t object.
  134. * @param [in] isbreak_func Callback function.
  135. */
  136. void faux_net_set_isbreak_func(faux_net_t *faux_net, int (*isbreak_func)(void))
  137. {
  138. assert(faux_net);
  139. if (!faux_net)
  140. return;
  141. faux_net->isbreak_func = isbreak_func;
  142. }
  143. /** @brief Emptyes signal mask using while network operations.
  144. *
  145. * @param [in] faux_net The faux_net_t object.
  146. */
  147. void faux_net_sigmask_empty(faux_net_t *faux_net)
  148. {
  149. assert(faux_net);
  150. if (!faux_net)
  151. return;
  152. sigemptyset(&faux_net->sigmask);
  153. }
  154. /** @brief Fills signal mask using while network operations.
  155. *
  156. * @param [in] faux_net The faux_net_t object.
  157. */
  158. void faux_net_sigmask_fill(faux_net_t *faux_net)
  159. {
  160. assert(faux_net);
  161. if (!faux_net)
  162. return;
  163. sigfillset(&faux_net->sigmask);
  164. }
  165. /** @brief Adds signal to signal mask using while network operations.
  166. *
  167. * @param [in] faux_net The faux_net_t object.
  168. * @param [in] signum Signal number to add.
  169. */
  170. void faux_net_sigmask_add(faux_net_t *faux_net, int signum)
  171. {
  172. assert(faux_net);
  173. if (!faux_net)
  174. return;
  175. sigaddset(&faux_net->sigmask, signum);
  176. }
  177. /** @brief Removes signal to signal mask using while network operations.
  178. *
  179. * @param [in] faux_net The faux_net_t object.
  180. * @param [in] signum Signal number to remove.
  181. */
  182. void faux_net_sigmask_del(faux_net_t *faux_net, int signum)
  183. {
  184. assert(faux_net);
  185. if (!faux_net)
  186. return;
  187. sigdelset(&faux_net->sigmask, signum);
  188. }
  189. /** @brief Sends data to socket associated with given objects.
  190. *
  191. * Function uses previously set parameters such as descriptor, timeout,
  192. * signal mask, callback function.
  193. *
  194. * @param [in] faux_net The faux_net_t object.
  195. * @param [in] buf Data buffer to send
  196. * @param [in] n Number of bytes to send.
  197. * @return Number of bytes was succesfully sent or < 0 on error.
  198. */
  199. ssize_t faux_net_send(faux_net_t *faux_net, const void *buf, size_t n)
  200. {
  201. return faux_send_block(faux_net->fd, buf, n, faux_net->send_timeout,
  202. &faux_net->sigmask, faux_net->isbreak_func);
  203. }
  204. /** @brief Sends data vector to socket associated with given objects.
  205. *
  206. * Function uses previously set parameters such as descriptor, timeout,
  207. * signal mask, callback function.
  208. *
  209. * @param [in] faux_net The faux_net_t object.
  210. * @param [in] iov Array of struct iovec structures.
  211. * @param [in] iovcnt Number of iov array members.
  212. * @return Number of bytes was succesfully sent or < 0 on error.
  213. */
  214. ssize_t faux_net_sendv(faux_net_t *faux_net,
  215. const struct iovec *iov, int iovcnt)
  216. {
  217. return faux_sendv_block(faux_net->fd, iov, iovcnt, faux_net->send_timeout,
  218. &faux_net->sigmask, faux_net->isbreak_func);
  219. }
  220. /** @brief Receives data from socket associated with given objects.
  221. *
  222. * Function uses previously set parameters such as descriptor, timeout,
  223. * signal mask, callback function.
  224. *
  225. * @param [in] faux_net The faux_net_t object.
  226. * @param [in] buf Data buffer for receiving.
  227. * @param [in] n Number of bytes to receive.
  228. * @return Number of bytes was succesfully received or < 0 on error.
  229. */
  230. ssize_t faux_net_recv(faux_net_t *faux_net, void *buf, size_t n)
  231. {
  232. return faux_recv_block(faux_net->fd, buf, n, faux_net->recv_timeout,
  233. &faux_net->sigmask, faux_net->isbreak_func);
  234. }
  235. /** @brief Receives data vector from socket associated with given objects.
  236. *
  237. * Function uses previously set parameters such as descriptor, timeout,
  238. * signal mask, callback function.
  239. *
  240. * @param [in] faux_net The faux_net_t object.
  241. * @param [in] iov Array of struct iovec structures.
  242. * @param [in] iovcnt Number of iov array members.
  243. * @return Number of bytes was succesfully received or < 0 on error.
  244. */
  245. ssize_t faux_net_recvv(faux_net_t *faux_net, struct iovec *iov, int iovcnt)
  246. {
  247. return faux_recvv_block(faux_net->fd, iov, iovcnt, faux_net->recv_timeout,
  248. &faux_net->sigmask, faux_net->isbreak_func);
  249. }