lib/libc/sys-minix/socketpair.c

http://www.minix3.org/ · C · 143 lines · 93 code · 30 blank · 20 comment · 22 complexity · c65390271cd50a9a985a35c6b6f441f4 MD5 · raw file

  1. #include <sys/cdefs.h>
  2. #include "namespace.h"
  3. #include <errno.h>
  4. #include <stdio.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <net/netlib.h>
  8. #include <sys/ioc_net.h>
  9. #include <sys/socket.h>
  10. #include <sys/stat.h>
  11. #include <sys/un.h>
  12. #ifdef __weak_alias
  13. __weak_alias(socketpair, _socketpair)
  14. #endif
  15. #define DEBUG 0
  16. static int _uds_socketpair(int type, int protocol, int sv[2]);
  17. /*
  18. * Create a pair of connected sockets
  19. */
  20. int socketpair(int domain, int type, int protocol, int sv[2]) {
  21. #if DEBUG
  22. fprintf(stderr, "socketpair: domain %d, type %d, protocol %d\n",
  23. domain, type, protocol);
  24. #endif
  25. if (domain != AF_UNIX)
  26. {
  27. errno = EAFNOSUPPORT;
  28. return -1;
  29. }
  30. if (domain == AF_UNIX &&
  31. (type == SOCK_STREAM || type == SOCK_SEQPACKET))
  32. return _uds_socketpair(type, protocol, sv);
  33. #if DEBUG
  34. fprintf(stderr,
  35. "socketpair: nothing for domain %d, type %d, protocol %d\n",
  36. domain, type, protocol);
  37. #endif
  38. errno= EPROTOTYPE;
  39. return -1;
  40. }
  41. static int _uds_socketpair(int type, int protocol, int sv[2])
  42. {
  43. dev_t dev;
  44. int r, i;
  45. struct stat sbuf;
  46. if (protocol != 0)
  47. {
  48. #if DEBUG
  49. fprintf(stderr, "socketpair(uds): bad protocol %d\n", protocol);
  50. #endif
  51. errno= EPROTONOSUPPORT;
  52. return -1;
  53. }
  54. /* in this 'for' loop two unconnected sockets are created */
  55. for (i = 0; i < 2; i++) {
  56. sv[i]= open(UDS_DEVICE, O_RDWR);
  57. if (sv[i] == -1) {
  58. int open_errno = errno;
  59. if (i == 1) {
  60. /* if we failed to open() the 2nd
  61. * socket, we need to close the 1st
  62. */
  63. close(sv[0]);
  64. errno = open_errno;
  65. }
  66. return -1;
  67. }
  68. /* set the type for the socket via ioctl
  69. * (SOCK_STREAM, SOCK_SEQPACKET, etc)
  70. */
  71. r= ioctl(sv[i], NWIOSUDSTYPE, &type);
  72. if (r == -1) {
  73. int ioctl_errno;
  74. /* if that failed rollback socket creation */
  75. ioctl_errno= errno;
  76. close(sv[i]);
  77. if (i == 1) {
  78. /* if we just closed the 2nd socket, we
  79. * need to close the 1st
  80. */
  81. close(sv[0]);
  82. }
  83. /* return the error thrown by the call to ioctl */
  84. errno= ioctl_errno;
  85. return -1;
  86. }
  87. }
  88. r= fstat(sv[1], &sbuf);
  89. if (r == -1) {
  90. int fstat_errno;
  91. /* if that failed rollback socket creation */
  92. fstat_errno= errno;
  93. close(sv[0]);
  94. close(sv[1]);
  95. /* return the error thrown by the call to fstat */
  96. errno= fstat_errno;
  97. return -1;
  98. }
  99. dev = sbuf.st_dev;
  100. /* connect the sockets sv[0] and sv[1] */
  101. r= ioctl(sv[0], NWIOSUDSPAIR, &dev);
  102. if (r == -1) {
  103. int ioctl_errno;
  104. /* if that failed rollback socket creation */
  105. ioctl_errno= errno;
  106. close(sv[0]);
  107. close(sv[1]);
  108. /* return the error thrown by the call to ioctl */
  109. errno= ioctl_errno;
  110. return -1;
  111. }
  112. return 0;
  113. }