ipcsocket.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <sys/time.h>
  8. #include <sys/un.h>
  9. #include <errno.h>
  10. #include "ipcsocket.h"
  11. int opensocket(int *sockfd, const char *name, int connecttype)
  12. {
  13. int ret, temp = 1;
  14. if (!name || strlen(name) > MAX_SOCK_NAME_LEN) {
  15. fprintf(stderr, "<%s>: Invalid socket name.\n", __func__);
  16. return -1;
  17. }
  18. ret = socket(PF_LOCAL, SOCK_STREAM, 0);
  19. if (ret < 0) {
  20. fprintf(stderr, "<%s>: Failed socket: <%s>\n",
  21. __func__, strerror(errno));
  22. return ret;
  23. }
  24. *sockfd = ret;
  25. if (setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR,
  26. (char *)&temp, sizeof(int)) < 0) {
  27. fprintf(stderr, "<%s>: Failed setsockopt: <%s>\n",
  28. __func__, strerror(errno));
  29. goto err;
  30. }
  31. sprintf(sock_name, "/tmp/%s", name);
  32. if (connecttype == 1) {
  33. /* This is for Server connection */
  34. struct sockaddr_un skaddr;
  35. int clientfd;
  36. socklen_t sklen;
  37. unlink(sock_name);
  38. memset(&skaddr, 0, sizeof(skaddr));
  39. skaddr.sun_family = AF_LOCAL;
  40. strcpy(skaddr.sun_path, sock_name);
  41. ret = bind(*sockfd, (struct sockaddr *)&skaddr,
  42. SUN_LEN(&skaddr));
  43. if (ret < 0) {
  44. fprintf(stderr, "<%s>: Failed bind: <%s>\n",
  45. __func__, strerror(errno));
  46. goto err;
  47. }
  48. ret = listen(*sockfd, 5);
  49. if (ret < 0) {
  50. fprintf(stderr, "<%s>: Failed listen: <%s>\n",
  51. __func__, strerror(errno));
  52. goto err;
  53. }
  54. memset(&skaddr, 0, sizeof(skaddr));
  55. sklen = sizeof(skaddr);
  56. ret = accept(*sockfd, (struct sockaddr *)&skaddr,
  57. (socklen_t *)&sklen);
  58. if (ret < 0) {
  59. fprintf(stderr, "<%s>: Failed accept: <%s>\n",
  60. __func__, strerror(errno));
  61. goto err;
  62. }
  63. clientfd = ret;
  64. *sockfd = clientfd;
  65. } else {
  66. /* This is for client connection */
  67. struct sockaddr_un skaddr;
  68. memset(&skaddr, 0, sizeof(skaddr));
  69. skaddr.sun_family = AF_LOCAL;
  70. strcpy(skaddr.sun_path, sock_name);
  71. ret = connect(*sockfd, (struct sockaddr *)&skaddr,
  72. SUN_LEN(&skaddr));
  73. if (ret < 0) {
  74. fprintf(stderr, "<%s>: Failed connect: <%s>\n",
  75. __func__, strerror(errno));
  76. goto err;
  77. }
  78. }
  79. return 0;
  80. err:
  81. if (*sockfd)
  82. close(*sockfd);
  83. return ret;
  84. }
  85. int sendtosocket(int sockfd, struct socketdata *skdata)
  86. {
  87. int ret, buffd;
  88. unsigned int len;
  89. char cmsg_b[CMSG_SPACE(sizeof(int))];
  90. struct cmsghdr *cmsg;
  91. struct msghdr msgh;
  92. struct iovec iov;
  93. struct timeval timeout;
  94. fd_set selFDs;
  95. if (!skdata) {
  96. fprintf(stderr, "<%s>: socketdata is NULL\n", __func__);
  97. return -1;
  98. }
  99. FD_ZERO(&selFDs);
  100. FD_SET(0, &selFDs);
  101. FD_SET(sockfd, &selFDs);
  102. timeout.tv_sec = 20;
  103. timeout.tv_usec = 0;
  104. ret = select(sockfd+1, NULL, &selFDs, NULL, &timeout);
  105. if (ret < 0) {
  106. fprintf(stderr, "<%s>: Failed select: <%s>\n",
  107. __func__, strerror(errno));
  108. return -1;
  109. }
  110. if (FD_ISSET(sockfd, &selFDs)) {
  111. buffd = skdata->data;
  112. len = skdata->len;
  113. memset(&msgh, 0, sizeof(msgh));
  114. msgh.msg_control = &cmsg_b;
  115. msgh.msg_controllen = CMSG_LEN(len);
  116. iov.iov_base = "OK";
  117. iov.iov_len = 2;
  118. msgh.msg_iov = &iov;
  119. msgh.msg_iovlen = 1;
  120. cmsg = CMSG_FIRSTHDR(&msgh);
  121. cmsg->cmsg_level = SOL_SOCKET;
  122. cmsg->cmsg_type = SCM_RIGHTS;
  123. cmsg->cmsg_len = CMSG_LEN(len);
  124. memcpy(CMSG_DATA(cmsg), &buffd, len);
  125. ret = sendmsg(sockfd, &msgh, MSG_DONTWAIT);
  126. if (ret < 0) {
  127. fprintf(stderr, "<%s>: Failed sendmsg: <%s>\n",
  128. __func__, strerror(errno));
  129. return -1;
  130. }
  131. }
  132. return 0;
  133. }
  134. int receivefromsocket(int sockfd, struct socketdata *skdata)
  135. {
  136. int ret, buffd;
  137. unsigned int len = 0;
  138. char cmsg_b[CMSG_SPACE(sizeof(int))];
  139. struct cmsghdr *cmsg;
  140. struct msghdr msgh;
  141. struct iovec iov;
  142. fd_set recvFDs;
  143. char data[32];
  144. if (!skdata) {
  145. fprintf(stderr, "<%s>: socketdata is NULL\n", __func__);
  146. return -1;
  147. }
  148. FD_ZERO(&recvFDs);
  149. FD_SET(0, &recvFDs);
  150. FD_SET(sockfd, &recvFDs);
  151. ret = select(sockfd+1, &recvFDs, NULL, NULL, NULL);
  152. if (ret < 0) {
  153. fprintf(stderr, "<%s>: Failed select: <%s>\n",
  154. __func__, strerror(errno));
  155. return -1;
  156. }
  157. if (FD_ISSET(sockfd, &recvFDs)) {
  158. len = sizeof(buffd);
  159. memset(&msgh, 0, sizeof(msgh));
  160. msgh.msg_control = &cmsg_b;
  161. msgh.msg_controllen = CMSG_LEN(len);
  162. iov.iov_base = data;
  163. iov.iov_len = sizeof(data)-1;
  164. msgh.msg_iov = &iov;
  165. msgh.msg_iovlen = 1;
  166. cmsg = CMSG_FIRSTHDR(&msgh);
  167. cmsg->cmsg_level = SOL_SOCKET;
  168. cmsg->cmsg_type = SCM_RIGHTS;
  169. cmsg->cmsg_len = CMSG_LEN(len);
  170. ret = recvmsg(sockfd, &msgh, MSG_DONTWAIT);
  171. if (ret < 0) {
  172. fprintf(stderr, "<%s>: Failed recvmsg: <%s>\n",
  173. __func__, strerror(errno));
  174. return -1;
  175. }
  176. memcpy(&buffd, CMSG_DATA(cmsg), len);
  177. skdata->data = buffd;
  178. skdata->len = len;
  179. }
  180. return 0;
  181. }
  182. int closesocket(int sockfd, char *name)
  183. {
  184. char sockname[MAX_SOCK_NAME_LEN];
  185. if (sockfd)
  186. close(sockfd);
  187. sprintf(sockname, "/tmp/%s", name);
  188. unlink(sockname);
  189. shutdown(sockfd, 2);
  190. return 0;
  191. }