PageRenderTime 26ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/libc/sys-minix/accept.c

http://www.minix3.org/
C | 133 lines | 107 code | 21 blank | 5 comment | 35 complexity | 8f53f89f0f7536cc13e32ada36f638da MD5 | raw file
Possible License(s): MIT, WTFPL, AGPL-1.0, BSD-3-Clause, GPL-3.0, LGPL-2.0, JSON, 0BSD
  1. #include <sys/cdefs.h>
  2. #include "namespace.h"
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <sys/ioctl.h>
  10. #include <sys/socket.h>
  11. #include <sys/un.h>
  12. #include <net/netlib.h>
  13. #include <net/gen/in.h>
  14. #include <net/gen/tcp.h>
  15. #include <net/gen/tcp_io.h>
  16. #include <net/gen/udp.h>
  17. #include <net/gen/udp_io.h>
  18. #define DEBUG 0
  19. static int _tcp_accept(int sock, struct sockaddr *__restrict address,
  20. socklen_t *__restrict address_len);
  21. static int _uds_accept(int sock, struct sockaddr *__restrict address,
  22. socklen_t *__restrict address_len);
  23. int accept(int sock, struct sockaddr *__restrict address,
  24. socklen_t *__restrict address_len)
  25. {
  26. int r;
  27. nwio_udpopt_t udpopt;
  28. r= _tcp_accept(sock, address, address_len);
  29. if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
  30. return r;
  31. r= _uds_accept(sock, address, address_len);
  32. if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
  33. return r;
  34. /* Unfortunately, we have to return EOPNOTSUPP for a socket that
  35. * does not support accept (such as a UDP socket) and ENOTSOCK for
  36. * filedescriptors that do not refer to a socket.
  37. */
  38. r= ioctl(sock, NWIOGUDPOPT, &udpopt);
  39. if (r == 0)
  40. {
  41. /* UDP socket */
  42. errno= EOPNOTSUPP;
  43. return -1;
  44. }
  45. if ((errno == ENOTTY || errno == EBADIOCTL))
  46. {
  47. errno= ENOTSOCK;
  48. return -1;
  49. }
  50. return r;
  51. }
  52. static int _tcp_accept(int sock, struct sockaddr *__restrict address,
  53. socklen_t *__restrict address_len)
  54. {
  55. int r, s1, t_errno;
  56. tcp_cookie_t cookie;
  57. s1= open(TCP_DEVICE, O_RDWR);
  58. if (s1 == -1)
  59. return s1;
  60. r= ioctl(s1, NWIOGTCPCOOKIE, &cookie);
  61. if (r == -1)
  62. {
  63. t_errno= errno;
  64. close(s1);
  65. errno= t_errno;
  66. return -1;
  67. }
  68. r= ioctl(sock, NWIOTCPACCEPTTO, &cookie);
  69. if (r == -1)
  70. {
  71. t_errno= errno;
  72. close(s1);
  73. errno= t_errno;
  74. return -1;
  75. }
  76. if (address != NULL)
  77. getpeername(s1, address, address_len);
  78. return s1;
  79. }
  80. static int _uds_accept(int sock, struct sockaddr *__restrict address,
  81. socklen_t *__restrict address_len)
  82. {
  83. int s1;
  84. int r;
  85. struct sockaddr_un uds_addr;
  86. socklen_t len;
  87. memset(&uds_addr, '\0', sizeof(struct sockaddr_un));
  88. r= ioctl(sock, NWIOGUDSADDR, &uds_addr);
  89. if (r == -1) {
  90. return r;
  91. }
  92. if (uds_addr.sun_family != AF_UNIX) {
  93. errno= EINVAL;
  94. return -1;
  95. }
  96. len= *address_len;
  97. if (len > sizeof(struct sockaddr_un))
  98. len = sizeof(struct sockaddr_un);
  99. memcpy(address, &uds_addr, len);
  100. *address_len= len;
  101. s1= open(UDS_DEVICE, O_RDWR);
  102. if (s1 == -1)
  103. return s1;
  104. r= ioctl(s1, NWIOSUDSACCEPT, address);
  105. if (r == -1) {
  106. int ioctl_errno = errno;
  107. close(s1);
  108. errno = ioctl_errno;
  109. return r;
  110. }
  111. return s1;
  112. }