errors_darwin.odin 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. package net
  2. // +build darwin
  3. /*
  4. Package net implements cross-platform Berkeley Sockets, DNS resolution and associated procedures.
  5. For other protocols and their features, see subdirectories of this package.
  6. */
  7. /*
  8. Copyright 2022 Tetralux <[email protected]>
  9. Copyright 2022 Colin Davidson <[email protected]>
  10. Copyright 2022 Jeroen van Rijn <[email protected]>.
  11. Made available under Odin's BSD-3 license.
  12. List of contributors:
  13. Tetralux: Initial implementation
  14. Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver
  15. Jeroen van Rijn: Cross platform unification, code style, documentation
  16. */
  17. import "core:c"
  18. import "core:os"
  19. Create_Socket_Error :: enum c.int {
  20. None = 0,
  21. Family_Not_Supported_For_This_Socket = c.int(os.EAFNOSUPPORT),
  22. No_Socket_Descriptors_Available = c.int(os.EMFILE),
  23. No_Buffer_Space_Available = c.int(os.ENOBUFS),
  24. No_Memory_Available_Available = c.int(os.ENOMEM),
  25. Protocol_Unsupported_By_System = c.int(os.EPROTONOSUPPORT),
  26. Wrong_Protocol_For_Socket = c.int(os.EPROTONOSUPPORT),
  27. Family_And_Socket_Type_Mismatch = c.int(os.EPROTONOSUPPORT),
  28. }
  29. Dial_Error :: enum c.int {
  30. None = 0,
  31. Port_Required = -1, // Attempted to dial an endpointing without a port being set.
  32. Address_In_Use = c.int(os.EADDRINUSE),
  33. In_Progress = c.int(os.EINPROGRESS),
  34. Cannot_Use_Any_Address = c.int(os.EADDRNOTAVAIL),
  35. Wrong_Family_For_Socket = c.int(os.EAFNOSUPPORT),
  36. Refused = c.int(os.ECONNREFUSED),
  37. Is_Listening_Socket = c.int(os.EACCES),
  38. Already_Connected = c.int(os.EISCONN),
  39. Network_Unreachable = c.int(os.ENETUNREACH), // Device is offline
  40. Host_Unreachable = c.int(os.EHOSTUNREACH), // Remote host cannot be reached
  41. No_Buffer_Space_Available = c.int(os.ENOBUFS),
  42. Not_Socket = c.int(os.ENOTSOCK),
  43. Timeout = c.int(os.ETIMEDOUT),
  44. // TODO: we may need special handling for this; maybe make a socket a struct with metadata?
  45. Would_Block = c.int(os.EWOULDBLOCK),
  46. }
  47. Bind_Error :: enum c.int {
  48. None = 0,
  49. Privileged_Port_Without_Root = -1, // Attempted to bind to a port less than 1024 without root access.
  50. Address_In_Use = c.int(os.EADDRINUSE), // Another application is currently bound to this endpoint.
  51. Given_Nonlocal_Address = c.int(os.EADDRNOTAVAIL), // The address is not a local address on this machine.
  52. Broadcast_Disabled = c.int(os.EACCES), // To bind a UDP socket to the broadcast address, the appropriate socket option must be set.
  53. Address_Family_Mismatch = c.int(os.EFAULT), // The address family of the address does not match that of the socket.
  54. Already_Bound = c.int(os.EINVAL), // The socket is already bound to an address.
  55. No_Ports_Available = c.int(os.ENOBUFS), // There are not enough ephemeral ports available.
  56. }
  57. Listen_Error :: enum c.int {
  58. None = 0,
  59. Address_In_Use = c.int(os.EADDRINUSE),
  60. Already_Connected = c.int(os.EISCONN),
  61. No_Socket_Descriptors_Available = c.int(os.EMFILE),
  62. No_Buffer_Space_Available = c.int(os.ENOBUFS),
  63. Nonlocal_Address = c.int(os.EADDRNOTAVAIL),
  64. Not_Socket = c.int(os.ENOTSOCK),
  65. Listening_Not_Supported_For_This_Socket = c.int(os.EOPNOTSUPP),
  66. }
  67. Accept_Error :: enum c.int {
  68. None = 0,
  69. // TODO(tetra): Is this error actually possible here? Or is like Linux, in which case we can remove it.
  70. Reset = c.int(os.ECONNRESET),
  71. Not_Listening = c.int(os.EINVAL),
  72. No_Socket_Descriptors_Available_For_Client_Socket = c.int(os.EMFILE),
  73. No_Buffer_Space_Available = c.int(os.ENOBUFS),
  74. Not_Socket = c.int(os.ENOTSOCK),
  75. Not_Connection_Oriented_Socket = c.int(os.EOPNOTSUPP),
  76. // TODO: we may need special handling for this; maybe make a socket a struct with metadata?
  77. Would_Block = c.int(os.EWOULDBLOCK),
  78. }
  79. TCP_Recv_Error :: enum c.int {
  80. None = 0,
  81. Shutdown = c.int(os.ESHUTDOWN),
  82. Not_Connected = c.int(os.ENOTCONN),
  83. // TODO(tetra): Is this error actually possible here?
  84. Connection_Broken = c.int(os.ENETRESET),
  85. Not_Socket = c.int(os.ENOTSOCK),
  86. Aborted = c.int(os.ECONNABORTED),
  87. // TODO(tetra): Determine when this is different from the syscall returning n=0 and maybe normalize them?
  88. Connection_Closed = c.int(os.ECONNRESET),
  89. Offline = c.int(os.ENETDOWN),
  90. Host_Unreachable = c.int(os.EHOSTUNREACH),
  91. Interrupted = c.int(os.EINTR),
  92. // NOTE: No, really. Presumably this means something different for nonblocking sockets...
  93. Timeout = c.int(os.EWOULDBLOCK),
  94. }
  95. UDP_Recv_Error :: enum c.int {
  96. None = 0,
  97. Buffer_Too_Small = c.int(os.EMSGSIZE), // The buffer is too small to fit the entire message, and the message was truncated. When this happens, the rest of message is lost.
  98. Not_Socket = c.int(os.ENOTSOCK), // The so-called socket is not an open socket.
  99. Not_Descriptor = c.int(os.EBADF), // The so-called socket is, in fact, not even a valid descriptor.
  100. Bad_Buffer = c.int(os.EFAULT), // The buffer did not point to a valid location in memory.
  101. Interrupted = c.int(os.EINTR), // A signal occurred before any data was transmitted. See signal(7).
  102. // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout.
  103. // NOTE: No, really. Presumably this means something different for nonblocking sockets...
  104. Timeout = c.int(os.EWOULDBLOCK),
  105. Socket_Not_Bound = c.int(os.EINVAL), // The socket must be bound for this operation, but isn't.
  106. }
  107. TCP_Send_Error :: enum c.int {
  108. None = 0,
  109. Aborted = c.int(os.ECONNABORTED),
  110. Connection_Closed = c.int(os.ECONNRESET),
  111. Not_Connected = c.int(os.ENOTCONN),
  112. Shutdown = c.int(os.ESHUTDOWN),
  113. // The send queue was full.
  114. // This is usually a transient issue.
  115. //
  116. // This also shouldn't normally happen on Linux, as data is dropped if it
  117. // doesn't fit in the send queue.
  118. No_Buffer_Space_Available = c.int(os.ENOBUFS),
  119. Offline = c.int(os.ENETDOWN),
  120. Host_Unreachable = c.int(os.EHOSTUNREACH),
  121. Interrupted = c.int(os.EINTR), // A signal occurred before any data was transmitted. See signal(7).
  122. // NOTE: No, really. Presumably this means something different for nonblocking sockets...
  123. // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout.
  124. Timeout = c.int(os.EWOULDBLOCK),
  125. Not_Socket = c.int(os.ENOTSOCK), // The so-called socket is not an open socket.
  126. }
  127. // TODO
  128. UDP_Send_Error :: enum c.int {
  129. None = 0,
  130. Message_Too_Long = c.int(os.EMSGSIZE), // The message is larger than the maximum UDP packet size. No data was sent.
  131. // TODO: not sure what the exact circumstances for this is yet
  132. Network_Unreachable = c.int(os.ENETUNREACH),
  133. No_Outbound_Ports_Available = c.int(os.EAGAIN), // There are no more emphemeral outbound ports available to bind the socket to, in order to send.
  134. // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout.
  135. // NOTE: No, really. Presumably this means something different for nonblocking sockets...
  136. Timeout = c.int(os.EWOULDBLOCK),
  137. Not_Socket = c.int(os.ENOTSOCK), // The so-called socket is not an open socket.
  138. Not_Descriptor = c.int(os.EBADF), // The so-called socket is, in fact, not even a valid descriptor.
  139. Bad_Buffer = c.int(os.EFAULT), // The buffer did not point to a valid location in memory.
  140. Interrupted = c.int(os.EINTR), // A signal occurred before any data was transmitted. See signal(7).
  141. // The send queue was full.
  142. // This is usually a transient issue.
  143. //
  144. // This also shouldn't normally happen on Linux, as data is dropped if it
  145. // doesn't fit in the send queue.
  146. No_Buffer_Space_Available = c.int(os.ENOBUFS),
  147. No_Memory_Available = c.int(os.ENOMEM), // No memory was available to properly manage the send queue.
  148. }
  149. Shutdown_Manner :: enum c.int {
  150. Receive = c.int(os.SHUT_RD),
  151. Send = c.int(os.SHUT_WR),
  152. Both = c.int(os.SHUT_RDWR),
  153. }
  154. Shutdown_Error :: enum c.int {
  155. None = 0,
  156. Aborted = c.int(os.ECONNABORTED),
  157. Reset = c.int(os.ECONNRESET),
  158. Offline = c.int(os.ENETDOWN),
  159. Not_Connected = c.int(os.ENOTCONN),
  160. Not_Socket = c.int(os.ENOTSOCK),
  161. Invalid_Manner = c.int(os.EINVAL),
  162. }
  163. Socket_Option_Error :: enum c.int {
  164. None = 0,
  165. Offline = c.int(os.ENETDOWN),
  166. Timeout_When_Keepalive_Set = c.int(os.ENETRESET),
  167. Invalid_Option_For_Socket = c.int(os.ENOPROTOOPT),
  168. Reset_When_Keepalive_Set = c.int(os.ENOTCONN),
  169. Not_Socket = c.int(os.ENOTSOCK),
  170. }
  171. Set_Blocking_Error :: enum c.int {
  172. None = 0,
  173. // TODO: Add errors for `set_blocking`
  174. }