lib/libc/sys-minix/recvmsg.c

http://www.minix3.org/ · C · 135 lines · 105 code · 28 blank · 2 comment · 36 complexity · 7d1eca7e7f198d4a6bb112a3e4456838 MD5 · raw file

  1. #include <sys/cdefs.h>
  2. #include "namespace.h"
  3. #undef NDEBUG
  4. #include <errno.h>
  5. #include <sys/ioctl.h>
  6. #include <sys/ioc_net.h>
  7. #include <sys/socket.h>
  8. #include <sys/types.h>
  9. #include <sys/un.h>
  10. #define DEBUG 0
  11. static ssize_t _uds_recvmsg_conn(int sock, struct msghdr *msg, int flags);
  12. static ssize_t _uds_recvmsg_dgram(int sock, struct msghdr *msg, int flags);
  13. ssize_t recvmsg(int sock, struct msghdr *msg, int flags)
  14. {
  15. int r;
  16. int uds_sotype;
  17. if (msg == NULL) {
  18. errno= EFAULT;
  19. return -1;
  20. }
  21. r= ioctl(sock, NWIOGUDSSOTYPE, &uds_sotype);
  22. if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL)) {
  23. if (r == -1) {
  24. return r;
  25. }
  26. if (uds_sotype == SOCK_DGRAM) {
  27. return _uds_recvmsg_dgram(sock, msg, flags);
  28. } else {
  29. return _uds_recvmsg_conn(sock, msg, flags);
  30. }
  31. }
  32. #if DEBUG
  33. fprintf(stderr, "recvmsg: not implemented for fd %d\n", sock);
  34. #endif
  35. errno= ENOSYS;
  36. return -1;
  37. }
  38. static ssize_t _uds_recvmsg_conn(int sock, struct msghdr *msg, int flags)
  39. {
  40. int r, rc;
  41. if (flags != 0) {
  42. #if DEBUG
  43. fprintf(stderr, "recvmsg(uds): flags not implemented\n");
  44. #endif
  45. errno= ENOSYS;
  46. return -1;
  47. }
  48. r= readv(sock, msg->msg_iov, msg->msg_iovlen);
  49. if (r >= 0 && msg->msg_name && msg->msg_namelen > 0) {
  50. getpeername(sock, msg->msg_name, &msg->msg_namelen);
  51. }
  52. /* get control data */
  53. if (r >= 0 && msg->msg_control && msg->msg_controllen > 0) {
  54. struct msg_control msg_ctrl;
  55. memset(&msg_ctrl, '\0', sizeof(struct msg_control));
  56. msg_ctrl.msg_controllen = msg->msg_controllen;
  57. rc = ioctl(sock, NWIOGUDSCTRL, &msg_ctrl);
  58. if (rc == -1) {
  59. return rc;
  60. }
  61. if (msg_ctrl.msg_controllen <= msg->msg_controllen) {
  62. memcpy(msg->msg_control, msg_ctrl.msg_control,
  63. msg_ctrl.msg_controllen);
  64. msg->msg_controllen = msg_ctrl.msg_controllen;
  65. }
  66. }
  67. msg->msg_flags = 0;
  68. return r;
  69. }
  70. static ssize_t _uds_recvmsg_dgram(int sock, struct msghdr *msg, int flags)
  71. {
  72. int r, rc;
  73. if (flags != 0) {
  74. #if DEBUG
  75. fprintf(stderr, "recvmsg(uds): flags not implemented\n");
  76. #endif
  77. errno= ENOSYS;
  78. return -1;
  79. }
  80. r= readv(sock, msg->msg_iov, msg->msg_iovlen);
  81. if (r >= 0 && msg->msg_name &&
  82. msg->msg_namelen >= sizeof(struct sockaddr_un))
  83. {
  84. rc= ioctl(sock, NWIOGUDSFADDR, msg->msg_name);
  85. if (rc == -1) {
  86. return rc;
  87. }
  88. msg->msg_namelen= sizeof(struct sockaddr_un);
  89. }
  90. /* get control data */
  91. if (r >= 0 && msg->msg_control && msg->msg_controllen > 0) {
  92. struct msg_control msg_ctrl;
  93. memset(&msg_ctrl, '\0', sizeof(struct msg_control));
  94. msg_ctrl.msg_controllen = msg->msg_controllen;
  95. rc = ioctl(sock, NWIOGUDSCTRL, &msg_ctrl);
  96. if (rc == -1) {
  97. return rc;
  98. }
  99. if (msg_ctrl.msg_controllen <= msg->msg_controllen) {
  100. memcpy(msg->msg_control, msg_ctrl.msg_control,
  101. msg_ctrl.msg_controllen);
  102. msg->msg_controllen = msg_ctrl.msg_controllen;
  103. }
  104. }
  105. msg->msg_flags = 0;
  106. return r;
  107. }