From e254581a1bbcab4aff1c83956ee94db85c09024a Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 4 Mar 2023 10:39:20 +0100 Subject: [PATCH] Apply #shared_nil to Network_Error --- core/net/addr.odin | 8 +------ core/net/common.odin | 38 +++++++++++++++---------------- core/net/errors_windows.odin | 11 +++++++++ tests/core/net/test_core_net.odin | 17 ++++++++------ 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/core/net/addr.odin b/core/net/addr.odin index 7f7b5b683..e6b503aaf 100644 --- a/core/net/addr.odin +++ b/core/net/addr.odin @@ -404,16 +404,10 @@ Host_Or_Endpoint :: union { Host, Endpoint, } -Parse_Endpoint_Error :: enum { - None = 0, - Bad_Port = 1, - Bad_Address, - Bad_Hostname, -} // Takes a string consisting of a hostname or IP address, and an optional port, // and return the component parts in a useful form. -parse_hostname_or_endpoint :: proc(endpoint_str: string) -> (target: Host_Or_Endpoint, err: Network_Error) { +parse_hostname_or_endpoint :: proc(endpoint_str: string) -> (target: Host_Or_Endpoint, err: Parse_Endpoint_Error) { host, port, port_ok := split_port(endpoint_str) if !port_ok { return nil, .Bad_Port diff --git a/core/net/common.odin b/core/net/common.odin index 62854415e..a9f2ba9bb 100644 --- a/core/net/common.odin +++ b/core/net/common.odin @@ -50,23 +50,7 @@ ODIN_NET_TCP_NODELAY_DEFAULT :: #config(ODIN_NET_TCP_NODELAY_DEFAULT, true) // COMMON DEFINITIONS Maybe :: runtime.Maybe -General_Error :: enum { - Unable_To_Enumerate_Network_Interfaces = 1, -} - -// `Platform_Error` is used to wrap errors returned by the different platforms that don't fit a common error. -Platform_Error :: enum u32 {} - -/* - NOTE(tetra): Enums in Network_Error should not have a named zero value. - If you have a proc that returns an enum with an Ok=0 value, using or_return from the callsite, when the caller returns a union, works as expected. - However, if that proc returns the union directly, returning the Ok value will NOT work with the caller's or_return, as it will treat Error{.Ok} as != nil, and early-return with it. - - The approach currently taken to avoid this is: - - Remove the named zero values for the enums - - Use the union everywhere -*/ -Network_Error :: union { +Network_Error :: union #shared_nil { General_Error, Platform_Error, Create_Socket_Error, @@ -85,11 +69,27 @@ Network_Error :: union { DNS_Error, } -Resolve_Error :: enum { +General_Error :: enum u32 { + None = 0, + Unable_To_Enumerate_Network_Interfaces = 1, +} + +// `Platform_Error` is used to wrap errors returned by the different platforms that don't fit a common error. +Platform_Error :: enum u32 {} + +Parse_Endpoint_Error :: enum { + None = 0, + Bad_Port = 1, + Bad_Address, + Bad_Hostname, +} + +Resolve_Error :: enum u32 { + None = 0, Unable_To_Resolve = 1, } -DNS_Error :: enum { +DNS_Error :: enum u32 { Invalid_Hostname_Error = 1, Invalid_Hosts_Config_Error, Invalid_Resolv_Config_Error, diff --git a/core/net/errors_windows.odin b/core/net/errors_windows.odin index c45ebbabf..154f6c2d8 100644 --- a/core/net/errors_windows.odin +++ b/core/net/errors_windows.odin @@ -22,6 +22,7 @@ import "core:c" import win "core:sys/windows" Create_Socket_Error :: enum c.int { + None = 0, Network_Subsystem_Failure = win.WSAENETDOWN, Family_Not_Supported_For_This_Socket = win.WSAEAFNOSUPPORT, No_Socket_Descriptors_Available = win.WSAEMFILE, @@ -32,6 +33,7 @@ Create_Socket_Error :: enum c.int { } Dial_Error :: enum c.int { + None = 0, Port_Required = -1, Address_In_Use = win.WSAEADDRINUSE, In_Progress = win.WSAEALREADY, @@ -49,6 +51,7 @@ Dial_Error :: enum c.int { } Bind_Error :: enum c.int { + None = 0, Address_In_Use = win.WSAEADDRINUSE, // Another application is currently bound to this endpoint. Given_Nonlocal_Address = win.WSAEADDRNOTAVAIL, // The address is not a local address on this machine. Broadcast_Disabled = win.WSAEACCES, // To bind a UDP socket to the broadcast address, the appropriate socket option must be set. @@ -58,6 +61,7 @@ Bind_Error :: enum c.int { } Listen_Error :: enum c.int { + None = 0, Address_In_Use = win.WSAEADDRINUSE, Already_Connected = win.WSAEISCONN, No_Socket_Descriptors_Available = win.WSAEMFILE, @@ -68,6 +72,7 @@ Listen_Error :: enum c.int { } Accept_Error :: enum c.int { + None = 0, Not_Listening = win.WSAEINVAL, No_Socket_Descriptors_Available_For_Client_Socket = win.WSAEMFILE, No_Buffer_Space_Available = win.WSAENOBUFS, @@ -79,6 +84,7 @@ Accept_Error :: enum c.int { } TCP_Recv_Error :: enum c.int { + None = 0, Network_Subsystem_Failure = win.WSAENETDOWN, Not_Connected = win.WSAENOTCONN, Bad_Buffer = win.WSAEFAULT, @@ -99,6 +105,7 @@ TCP_Recv_Error :: enum c.int { } UDP_Recv_Error :: enum c.int { + None = 0, Network_Subsystem_Failure = win.WSAENETDOWN, // TODO: not functionally different from Reset; merge? @@ -124,6 +131,7 @@ UDP_Recv_Error :: enum c.int { // TODO: consider merging some errors to make handling them easier // TODO: verify once more what errors to actually expose TCP_Send_Error :: enum c.int { + None = 0, // TODO: not functionally different from Reset; merge? Aborted = win.WSAECONNABORTED, @@ -148,6 +156,7 @@ TCP_Send_Error :: enum c.int { } UDP_Send_Error :: enum c.int { + None = 0, Network_Subsystem_Failure = win.WSAENETDOWN, // TODO: not functionally different from Reset; merge? @@ -181,6 +190,7 @@ Shutdown_Manner :: enum c.int { } Shutdown_Error :: enum c.int { + None = 0, Aborted = win.WSAECONNABORTED, Reset = win.WSAECONNRESET, Offline = win.WSAENETDOWN, @@ -237,6 +247,7 @@ Socket_Option :: enum c.int { } Socket_Option_Error :: enum c.int { + None = 0, Linger_Only_Supports_Whole_Seconds = 1, // The given value is too big or small to be given to the OS. diff --git a/tests/core/net/test_core_net.odin b/tests/core/net/test_core_net.odin index 528cd89c4..00c29db95 100644 --- a/tests/core/net/test_core_net.odin +++ b/tests/core/net/test_core_net.odin @@ -374,17 +374,19 @@ tcp_tests :: proc(t: ^testing.T) { } tcp_client :: proc(retval: rawptr) { - r := transmute(^Thread_Data)retval + send :: proc(content: []u8) -> (err: net.Network_Error) { + skt := net.dial_tcp(ENDPOINT) or_return + defer net.close(skt) - if r.skt, r.err = net.dial_tcp(ENDPOINT); r.err != nil { + net.set_option(skt, .Send_Timeout, SEND_TIMEOUT) + net.set_option(skt, .Receive_Timeout, RECV_TIMEOUT) + + _, err = net.send(skt, content) return } - defer net.close(r.skt) - net.set_option(r.skt, .Send_Timeout, SEND_TIMEOUT) - net.set_option(r.skt, .Receive_Timeout, RECV_TIMEOUT) - - _, r.err = net.send(r.skt.(net.TCP_Socket), transmute([]u8)CONTENT) + r := transmute(^Thread_Data)retval + r.err = send(transmute([]u8)CONTENT) return } @@ -407,6 +409,7 @@ tcp_server :: proc(retval: rawptr) { } defer net.close(client) + r.length, r.err = net.recv_tcp(client, r.data[:]) return }