From 4d65b1ab9cb86bcbbfb0e5b26e3552f6f3582004 Mon Sep 17 00:00:00 2001 From: flysand7 Date: Wed, 18 Oct 2023 01:57:26 +1100 Subject: Implement new sys/unix package --- core/net/errors_linux.odin | 188 +++++++++++++++++++++++---------------------- 1 file changed, 95 insertions(+), 93 deletions(-) (limited to 'core/net/errors_linux.odin') diff --git a/core/net/errors_linux.odin b/core/net/errors_linux.odin index d76132ad5..2370dd0d8 100644 --- a/core/net/errors_linux.odin +++ b/core/net/errors_linux.odin @@ -16,182 +16,184 @@ package net Tetralux: Initial implementation Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver Jeroen van Rijn: Cross platform unification, code style, documentation + flysand: Move dependency from core:linux.Errno to core:sys/linux */ import "core:c" -import "core:os" +import "core:sys/linux" Create_Socket_Error :: enum c.int { None = 0, - Family_Not_Supported_For_This_Socket = c.int(os.EAFNOSUPPORT), - No_Socket_Descriptors_Available = c.int(os.EMFILE), - No_Buffer_Space_Available = c.int(os.ENOBUFS), - No_Memory_Available_Available = c.int(os.ENOMEM), - Protocol_Unsupported_By_System = c.int(os.EPROTONOSUPPORT), - Wrong_Protocol_For_Socket = c.int(os.EPROTONOSUPPORT), - Family_And_Socket_Type_Mismatch = c.int(os.EPROTONOSUPPORT), + Family_Not_Supported_For_This_Socket = c.int(linux.Errno.EAFNOSUPPORT), + No_Socket_Descriptors_Available = c.int(linux.Errno.EMFILE), + No_Buffer_Space_Available = c.int(linux.Errno.ENOBUFS), + No_Memory_Available_Available = c.int(linux.Errno.ENOMEM), + Protocol_Unsupported_By_System = c.int(linux.Errno.EPROTONOSUPPORT), + Wrong_Protocol_For_Socket = c.int(linux.Errno.EPROTONOSUPPORT), + Family_And_Socket_Type_Mismatch = c.int(linux.Errno.EPROTONOSUPPORT), } Dial_Error :: enum c.int { None = 0, Port_Required = -1, - Address_In_Use = c.int(os.EADDRINUSE), - In_Progress = c.int(os.EINPROGRESS), - Cannot_Use_Any_Address = c.int(os.EADDRNOTAVAIL), - Wrong_Family_For_Socket = c.int(os.EAFNOSUPPORT), - Refused = c.int(os.ECONNREFUSED), - Is_Listening_Socket = c.int(os.EACCES), - Already_Connected = c.int(os.EISCONN), - Network_Unreachable = c.int(os.ENETUNREACH), // Device is offline - Host_Unreachable = c.int(os.EHOSTUNREACH), // Remote host cannot be reached - No_Buffer_Space_Available = c.int(os.ENOBUFS), - Not_Socket = c.int(os.ENOTSOCK), - Timeout = c.int(os.ETIMEDOUT), + Address_In_Use = c.int(linux.Errno.EADDRINUSE), + In_Progress = c.int(linux.Errno.EINPROGRESS), + Cannot_Use_Any_Address = c.int(linux.Errno.EADDRNOTAVAIL), + Wrong_Family_For_Socket = c.int(linux.Errno.EAFNOSUPPORT), + Refused = c.int(linux.Errno.ECONNREFUSED), + Is_Listening_Socket = c.int(linux.Errno.EACCES), + Already_Connected = c.int(linux.Errno.EISCONN), + Network_Unreachable = c.int(linux.Errno.ENETUNREACH), // Device is offline + Host_Unreachable = c.int(linux.Errno.EHOSTUNREACH), // Remote host cannot be reached + No_Buffer_Space_Available = c.int(linux.Errno.ENOBUFS), + Not_Socket = c.int(linux.Errno.ENOTSOCK), + Timeout = c.int(linux.Errno.ETIMEDOUT), // TODO: we may need special handling for this; maybe make a socket a struct with metadata? - Would_Block = c.int(os.EWOULDBLOCK), + Would_Block = c.int(linux.Errno.EWOULDBLOCK), } Bind_Error :: enum c.int { None = 0, - Address_In_Use = c.int(os.EADDRINUSE), // Another application is currently bound to this endpoint. - Given_Nonlocal_Address = c.int(os.EADDRNOTAVAIL), // The address is not a local address on this machine. - Broadcast_Disabled = c.int(os.EACCES), // To bind a UDP socket to the broadcast address, the appropriate socket option must be set. - Address_Family_Mismatch = c.int(os.EFAULT), // The address family of the address does not match that of the socket. - Already_Bound = c.int(os.EINVAL), // The socket is already bound to an address. - No_Ports_Available = c.int(os.ENOBUFS), // There are not enough ephemeral ports available. + Address_In_Use = c.int(linux.Errno.EADDRINUSE), // Another application is currently bound to this endpoint. + Given_Nonlocal_Address = c.int(linux.Errno.EADDRNOTAVAIL), // The address is not a local address on this machine. + Broadcast_Disabled = c.int(linux.Errno.EACCES), // To bind a UDP socket to the broadcast address, the appropriate socket option must be set. + Address_Family_Mismatch = c.int(linux.Errno.EFAULT), // The address family of the address does not match that of the socket. + Already_Bound = c.int(linux.Errno.EINVAL), // The socket is already bound to an address. + No_Ports_Available = c.int(linux.Errno.ENOBUFS), // There are not enough ephemeral ports available. } Listen_Error :: enum c.int { None = 0, - Address_In_Use = c.int(os.EADDRINUSE), - Already_Connected = c.int(os.EISCONN), - No_Socket_Descriptors_Available = c.int(os.EMFILE), - No_Buffer_Space_Available = c.int(os.ENOBUFS), - Nonlocal_Address = c.int(os.EADDRNOTAVAIL), - Not_Socket = c.int(os.ENOTSOCK), - Listening_Not_Supported_For_This_Socket = c.int(os.EOPNOTSUPP), + Address_In_Use = c.int(linux.Errno.EADDRINUSE), + Already_Connected = c.int(linux.Errno.EISCONN), + No_Socket_Descriptors_Available = c.int(linux.Errno.EMFILE), + No_Buffer_Space_Available = c.int(linux.Errno.ENOBUFS), + Nonlocal_Address = c.int(linux.Errno.EADDRNOTAVAIL), + Not_Socket = c.int(linux.Errno.ENOTSOCK), + Listening_Not_Supported_For_This_Socket = c.int(linux.Errno.EOPNOTSUPP), } Accept_Error :: enum c.int { None = 0, - Not_Listening = c.int(os.EINVAL), - No_Socket_Descriptors_Available_For_Client_Socket = c.int(os.EMFILE), - No_Buffer_Space_Available = c.int(os.ENOBUFS), - Not_Socket = c.int(os.ENOTSOCK), - Not_Connection_Oriented_Socket = c.int(os.EOPNOTSUPP), + Not_Listening = c.int(linux.Errno.EINVAL), + No_Socket_Descriptors_Available_For_Client_Socket = c.int(linux.Errno.EMFILE), + No_Buffer_Space_Available = c.int(linux.Errno.ENOBUFS), + Not_Socket = c.int(linux.Errno.ENOTSOCK), + Not_Connection_Oriented_Socket = c.int(linux.Errno.EOPNOTSUPP), // TODO: we may need special handling for this; maybe make a socket a struct with metadata? - Would_Block = c.int(os.EWOULDBLOCK), + Would_Block = c.int(linux.Errno.EWOULDBLOCK), } TCP_Recv_Error :: enum c.int { None = 0, - Shutdown = c.int(os.ESHUTDOWN), - Not_Connected = c.int(os.ENOTCONN), - Connection_Broken = c.int(os.ENETRESET), - Not_Socket = c.int(os.ENOTSOCK), - Aborted = c.int(os.ECONNABORTED), + Shutdown = c.int(linux.Errno.ESHUTDOWN), + Not_Connected = c.int(linux.Errno.ENOTCONN), + Connection_Broken = c.int(linux.Errno.ENETRESET), + Not_Socket = c.int(linux.Errno.ENOTSOCK), + Aborted = c.int(linux.Errno.ECONNABORTED), // TODO(tetra): Determine when this is different from the syscall returning n=0 and maybe normalize them? - Connection_Closed = c.int(os.ECONNRESET), - Offline = c.int(os.ENETDOWN), - Host_Unreachable = c.int(os.EHOSTUNREACH), - Interrupted = c.int(os.EINTR), - Timeout = c.int(os.EWOULDBLOCK), // NOTE: No, really. Presumably this means something different for nonblocking sockets... + Connection_Closed = c.int(linux.Errno.ECONNRESET), + Offline = c.int(linux.Errno.ENETDOWN), + Host_Unreachable = c.int(linux.Errno.EHOSTUNREACH), + Interrupted = c.int(linux.Errno.EINTR), + Timeout = c.int(linux.Errno.EWOULDBLOCK), // NOTE: No, really. Presumably this means something different for nonblocking sockets... } UDP_Recv_Error :: enum c.int { None = 0, - 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. - Not_Socket = c.int(os.ENOTSOCK), // The so-called socket is not an open socket. - Not_Descriptor = c.int(os.EBADF), // The so-called socket is, in fact, not even a valid descriptor. - Bad_Buffer = c.int(os.EFAULT), // The buffer did not point to a valid location in memory. - Interrupted = c.int(os.EINTR), // A signal occurred before any data was transmitted. See signal(7). + Buffer_Too_Small = c.int(linux.Errno.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. + Not_Socket = c.int(linux.Errno.ENOTSOCK), // The so-called socket is not an open socket. + Not_Descriptor = c.int(linux.Errno.EBADF), // The so-called socket is, in fact, not even a valid descriptor. + Bad_Buffer = c.int(linux.Errno.EFAULT), // The buffer did not point to a valid location in memory. + Interrupted = c.int(linux.Errno.EINTR), // A signal occurred before any data was transmitted. See signal(7). // The send timeout duration passed before all data was received. See Socket_Option.Receive_Timeout. // NOTE: No, really. Presumably this means something different for nonblocking sockets... - Timeout = c.int(os.EWOULDBLOCK), - Socket_Not_Bound = c.int(os.EINVAL), // The socket must be bound for this operation, but isn't. + Timeout = c.int(linux.Errno.EWOULDBLOCK), + Socket_Not_Bound = c.int(linux.Errno.EINVAL), // The socket must be bound for this operation, but isn't. } TCP_Send_Error :: enum c.int { None = 0, - Aborted = c.int(os.ECONNABORTED), - Connection_Closed = c.int(os.ECONNRESET), - Not_Connected = c.int(os.ENOTCONN), - Shutdown = c.int(os.ESHUTDOWN), + Aborted = c.int(linux.Errno.ECONNABORTED), + Connection_Closed = c.int(linux.Errno.ECONNRESET), + Not_Connected = c.int(linux.Errno.ENOTCONN), + Shutdown = c.int(linux.Errno.ESHUTDOWN), // The send queue was full. // This is usually a transient issue. // // This also shouldn't normally happen on Linux, as data is dropped if it // doesn't fit in the send queue. - No_Buffer_Space_Available = c.int(os.ENOBUFS), - Offline = c.int(os.ENETDOWN), - Host_Unreachable = c.int(os.EHOSTUNREACH), - Interrupted = c.int(os.EINTR), // A signal occurred before any data was transmitted. See signal(7). - Timeout = c.int(os.EWOULDBLOCK), // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout. - Not_Socket = c.int(os.ENOTSOCK), // The so-called socket is not an open socket. + No_Buffer_Space_Available = c.int(linux.Errno.ENOBUFS), + Offline = c.int(linux.Errno.ENETDOWN), + Host_Unreachable = c.int(linux.Errno.EHOSTUNREACH), + Interrupted = c.int(linux.Errno.EINTR), // A signal occurred before any data was transmitted. See signal(7). + Timeout = c.int(linux.Errno.EWOULDBLOCK), // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout. + Not_Socket = c.int(linux.Errno.ENOTSOCK), // The so-called socket is not an open socket. } // TODO UDP_Send_Error :: enum c.int { None = 0, - Message_Too_Long = c.int(os.EMSGSIZE), // The message is larger than the maximum UDP packet size. No data was sent. + Message_Too_Long = c.int(linux.Errno.EMSGSIZE), // The message is larger than the maximum UDP packet size. No data was sent. // TODO: not sure what the exact circumstances for this is yet - Network_Unreachable = c.int(os.ENETUNREACH), - 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. + Network_Unreachable = c.int(linux.Errno.ENETUNREACH), + No_Outbound_Ports_Available = c.int(linux.Errno.EAGAIN), // There are no more emphemeral outbound ports available to bind the socket to, in order to send. // The send timeout duration passed before all data was sent. See Socket_Option.Send_Timeout. // NOTE: No, really. Presumably this means something different for nonblocking sockets... - Timeout = c.int(os.EWOULDBLOCK), - Not_Socket = c.int(os.ENOTSOCK), // The so-called socket is not an open socket. - Not_Descriptor = c.int(os.EBADF), // The so-called socket is, in fact, not even a valid descriptor. - Bad_Buffer = c.int(os.EFAULT), // The buffer did not point to a valid location in memory. - Interrupted = c.int(os.EINTR), // A signal occurred before any data was transmitted. See signal(7). + Timeout = c.int(linux.Errno.EWOULDBLOCK), + Not_Socket = c.int(linux.Errno.ENOTSOCK), // The so-called socket is not an open socket. + Not_Descriptor = c.int(linux.Errno.EBADF), // The so-called socket is, in fact, not even a valid descriptor. + Bad_Buffer = c.int(linux.Errno.EFAULT), // The buffer did not point to a valid location in memory. + Interrupted = c.int(linux.Errno.EINTR), // A signal occurred before any data was transmitted. See signal(7). // The send queue was full. // This is usually a transient issue. // // This also shouldn't normally happen on Linux, as data is dropped if it // doesn't fit in the send queue. - No_Buffer_Space_Available = c.int(os.ENOBUFS), - No_Memory_Available = c.int(os.ENOMEM), // No memory was available to properly manage the send queue. + No_Buffer_Space_Available = c.int(linux.Errno.ENOBUFS), + No_Memory_Available = c.int(linux.Errno.ENOMEM), // No memory was available to properly manage the send queue. } +// TODO(flysand): slight regression Shutdown_Manner :: enum c.int { - Receive = c.int(os.SHUT_RD), - Send = c.int(os.SHUT_WR), - Both = c.int(os.SHUT_RDWR), + Receive = c.int(linux.Shutdown_How.RD), + Send = c.int(linux.Shutdown_How.WR), + Both = c.int(linux.Shutdown_How.RDWR), } Shutdown_Error :: enum c.int { None = 0, - Aborted = c.int(os.ECONNABORTED), - Reset = c.int(os.ECONNRESET), - Offline = c.int(os.ENETDOWN), - Not_Connected = c.int(os.ENOTCONN), - Not_Socket = c.int(os.ENOTSOCK), - Invalid_Manner = c.int(os.EINVAL), + Aborted = c.int(linux.Errno.ECONNABORTED), + Reset = c.int(linux.Errno.ECONNRESET), + Offline = c.int(linux.Errno.ENETDOWN), + Not_Connected = c.int(linux.Errno.ENOTCONN), + Not_Socket = c.int(linux.Errno.ENOTSOCK), + Invalid_Manner = c.int(linux.Errno.EINVAL), } Socket_Option_Error :: enum c.int { None = 0, - Offline = c.int(os.ENETDOWN), - Timeout_When_Keepalive_Set = c.int(os.ENETRESET), - Invalid_Option_For_Socket = c.int(os.ENOPROTOOPT), - Reset_When_Keepalive_Set = c.int(os.ENOTCONN), - Not_Socket = c.int(os.ENOTSOCK), + Offline = c.int(linux.Errno.ENETDOWN), + Timeout_When_Keepalive_Set = c.int(linux.Errno.ENETRESET), + Invalid_Option_For_Socket = c.int(linux.Errno.ENOPROTOOPT), + Reset_When_Keepalive_Set = c.int(linux.Errno.ENOTCONN), + Not_Socket = c.int(linux.Errno.ENOTSOCK), } Set_Blocking_Error :: enum c.int { None = 0, // TODO: add errors occuring on followig calls: - // flags, _ := os.fcntl(sd, os.F_GETFL, 0) - // os.fcntl(sd, os.F_SETFL, flags | int(os.O_NONBLOCK)) + // flags, _ := linux.Errno.fcntl(sd, linux.Errno.F_GETFL, 0) + // linux.Errno.fcntl(sd, linux.Errno.F_SETFL, flags | int(linux.Errno.O_NONBLOCK)) } \ No newline at end of file -- cgit v1.2.3