lib/libc/sys-minix/socket.c

http://www.minix3.org/ · C · 139 lines · 113 code · 20 blank · 6 comment · 37 complexity · 765addbec3743538023beda30187e554 MD5 · raw file

  1. #include <sys/cdefs.h>
  2. #include "namespace.h"
  3. #ifdef __weak_alias
  4. __weak_alias(socket, _socket)
  5. #endif
  6. #include <errno.h>
  7. #include <fcntl.h>
  8. #include <signal.h>
  9. #include <stdio.h>
  10. #include <unistd.h>
  11. #include <sys/socket.h>
  12. #include <sys/ioc_net.h>
  13. #include <net/netlib.h>
  14. #include <netinet/in.h>
  15. #define DEBUG 0
  16. static int _tcp_socket(int protocol);
  17. static int _udp_socket(int protocol);
  18. static int _uds_socket(int type, int protocol);
  19. int socket(int domain, int type, int protocol)
  20. {
  21. #if DEBUG
  22. fprintf(stderr, "socket: domain %d, type %d, protocol %d\n",
  23. domain, type, protocol);
  24. #endif
  25. if (domain != AF_INET && domain != AF_UNIX)
  26. {
  27. #if DEBUG
  28. fprintf(stderr, "socket: bad domain %d\n", domain);
  29. #endif
  30. errno= EAFNOSUPPORT;
  31. return -1;
  32. }
  33. if (domain == AF_UNIX && (type == SOCK_STREAM ||
  34. type == SOCK_DGRAM || type == SOCK_SEQPACKET))
  35. return _uds_socket(type, protocol);
  36. if (domain == AF_INET && type == SOCK_STREAM)
  37. return _tcp_socket(protocol);
  38. if (domain == AF_INET && type == SOCK_DGRAM)
  39. return _udp_socket(protocol);
  40. #if DEBUG
  41. fprintf(stderr, "socket: nothing for domain %d, type %d, protocol %d\n",
  42. domain, type, protocol);
  43. #endif
  44. errno= EPROTOTYPE;
  45. return -1;
  46. }
  47. static int _tcp_socket(int protocol)
  48. {
  49. int fd;
  50. if (protocol != 0 && protocol != IPPROTO_TCP)
  51. {
  52. #if DEBUG
  53. fprintf(stderr, "socket(tcp): bad protocol %d\n", protocol);
  54. #endif
  55. errno= EPROTONOSUPPORT;
  56. return -1;
  57. }
  58. fd= open(TCP_DEVICE, O_RDWR);
  59. return fd;
  60. }
  61. static int _udp_socket(int protocol)
  62. {
  63. int r, fd, t_errno;
  64. struct sockaddr_in sin;
  65. if (protocol != 0 && protocol != IPPROTO_UDP)
  66. {
  67. #if DEBUG
  68. fprintf(stderr, "socket(udp): bad protocol %d\n", protocol);
  69. #endif
  70. errno= EPROTONOSUPPORT;
  71. return -1;
  72. }
  73. fd= open(UDP_DEVICE, O_RDWR);
  74. if (fd == -1)
  75. return fd;
  76. /* Bind is implict for UDP sockets? */
  77. sin.sin_family= AF_INET;
  78. sin.sin_addr.s_addr= INADDR_ANY;
  79. sin.sin_port= 0;
  80. r= bind(fd, (struct sockaddr *)&sin, sizeof(sin));
  81. if (r != 0)
  82. {
  83. t_errno= errno;
  84. close(fd);
  85. errno= t_errno;
  86. return -1;
  87. }
  88. return fd;
  89. }
  90. static int _uds_socket(int type, int protocol)
  91. {
  92. int fd, r;
  93. if (protocol != 0)
  94. {
  95. #if DEBUG
  96. fprintf(stderr, "socket(uds): bad protocol %d\n", protocol);
  97. #endif
  98. errno= EPROTONOSUPPORT;
  99. return -1;
  100. }
  101. fd= open(UDS_DEVICE, O_RDWR);
  102. if (fd == -1) {
  103. return fd;
  104. }
  105. /* set the type for the socket via ioctl (SOCK_DGRAM,
  106. * SOCK_STREAM, SOCK_SEQPACKET, etc)
  107. */
  108. r= ioctl(fd, NWIOSUDSTYPE, &type);
  109. if (r == -1) {
  110. int ioctl_errno;
  111. /* if that failed rollback socket creation */
  112. ioctl_errno= errno;
  113. close(fd);
  114. /* return the error thrown by the call to ioctl */
  115. errno= ioctl_errno;
  116. return -1;
  117. }
  118. return fd;
  119. }