aboutsummaryrefslogtreecommitdiff
path: root/core/net
diff options
context:
space:
mode:
authorSokus <soqs687@gmail.com>2023-03-08 13:17:59 +0100
committerSokus <soqs687@gmail.com>2023-03-08 13:30:12 +0100
commit1ecab2fcbc4a52b481f185ccf87bb38c9691c39e (patch)
tree504fdf5d5635246329c3575386342b70263652a8 /core/net
parenta262c0bbf325051891debe1a86866f5c9059ee58 (diff)
Add `set_blocking` for network sockets
Diffstat (limited to 'core/net')
-rw-r--r--core/net/common.odin1
-rw-r--r--core/net/errors_darwin.odin6
-rw-r--r--core/net/errors_linux.odin8
-rw-r--r--core/net/errors_windows.odin12
-rw-r--r--core/net/socket.odin4
-rw-r--r--core/net/socket_darwin.odin6
-rw-r--r--core/net/socket_linux.odin23
-rw-r--r--core/net/socket_windows.odin12
8 files changed, 72 insertions, 0 deletions
diff --git a/core/net/common.odin b/core/net/common.odin
index a9f2ba9bb..70a027138 100644
--- a/core/net/common.odin
+++ b/core/net/common.odin
@@ -64,6 +64,7 @@ Network_Error :: union #shared_nil {
UDP_Recv_Error,
Shutdown_Error,
Socket_Option_Error,
+ Set_Blocking_Error,
Parse_Endpoint_Error,
Resolve_Error,
DNS_Error,
diff --git a/core/net/errors_darwin.odin b/core/net/errors_darwin.odin
index 645bbe555..39cf4c665 100644
--- a/core/net/errors_darwin.odin
+++ b/core/net/errors_darwin.odin
@@ -197,4 +197,10 @@ Socket_Option_Error :: enum c.int {
Invalid_Option_For_Socket = c.int(os.ENOPROTOOPT),
Reset_When_Keepalive_Set = c.int(os.ENOTCONN),
Not_Socket = c.int(os.ENOTSOCK),
+}
+
+Set_Blocking_Error :: enum c.int {
+ None = 0,
+
+ // TODO: Add errors for `set_blocking`
} \ No newline at end of file
diff --git a/core/net/errors_linux.odin b/core/net/errors_linux.odin
index 9575d7c18..9366f4435 100644
--- a/core/net/errors_linux.odin
+++ b/core/net/errors_linux.odin
@@ -190,4 +190,12 @@ Socket_Option_Error :: enum c.int {
Invalid_Option_For_Socket = c.int(os.ENOPROTOOPT),
Reset_When_Keepalive_Set = c.int(os.ENOTCONN),
Not_Socket = c.int(os.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))
} \ No newline at end of file
diff --git a/core/net/errors_windows.odin b/core/net/errors_windows.odin
index 154f6c2d8..272aa0a96 100644
--- a/core/net/errors_windows.odin
+++ b/core/net/errors_windows.odin
@@ -259,3 +259,15 @@ Socket_Option_Error :: enum c.int {
Reset_When_Keepalive_Set = win.WSAENOTCONN,
Not_Socket = win.WSAENOTSOCK,
}
+
+Set_Blocking_Error :: enum c.int {
+ None = 0,
+
+ Network_Subsystem_Failure = win.WSAENETDOWN,
+ Blocking_Call_In_Progress = win.WSAEINPROGRESS,
+ Not_Socket = win.WSAENOTSOCK,
+
+ // TODO: are those errors possible?
+ Network_Subsystem_Not_Initialized = win.WSAENOTINITIALISED,
+ Invalid_Argument_Pointer = win.WSAEFAULT,
+} \ No newline at end of file
diff --git a/core/net/socket.odin b/core/net/socket.odin
index 95eb50496..a24ae8a0b 100644
--- a/core/net/socket.odin
+++ b/core/net/socket.odin
@@ -173,4 +173,8 @@ shutdown :: proc(socket: Any_Socket, manner: Shutdown_Manner) -> (err: Network_E
set_option :: proc(socket: Any_Socket, option: Socket_Option, value: any, loc := #caller_location) -> Network_Error {
return _set_option(socket, option, value, loc)
+}
+
+set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_Error) {
+ return _set_blocking(socket, should_block)
} \ No newline at end of file
diff --git a/core/net/socket_darwin.odin b/core/net/socket_darwin.odin
index a0a5af6ca..0d8503cfd 100644
--- a/core/net/socket_darwin.odin
+++ b/core/net/socket_darwin.odin
@@ -301,6 +301,12 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca
return nil
}
+@(private)
+_set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_Error) {
+ // TODO: Implement
+ unimplemented()
+}
+
@private
_endpoint_to_sockaddr :: proc(ep: Endpoint) -> (sockaddr: os.SOCKADDR_STORAGE_LH) {
switch a in ep.address {
diff --git a/core/net/socket_linux.odin b/core/net/socket_linux.odin
index 81419f6c9..690e09ab7 100644
--- a/core/net/socket_linux.odin
+++ b/core/net/socket_linux.odin
@@ -317,6 +317,29 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca
}
@(private)
+_set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_Error) {
+ socket := any_socket_to_socket(socket)
+
+ flags, getfl_err := os.fcntl(int(socket), os.F_GETFL, 0)
+ if getfl_err != os.ERROR_NONE {
+ return Set_Blocking_Error(getfl_err)
+ }
+
+ if should_block {
+ flags &= ~int(os.O_NONBLOCK)
+ } else {
+ flags |= int(os.O_NONBLOCK)
+ }
+
+ _, setfl_err := os.fcntl(int(socket), os.F_SETFL, flags)
+ if setfl_err != os.ERROR_NONE {
+ return Set_Blocking_Error(setfl_err)
+ }
+
+ return nil
+}
+
+@(private)
_endpoint_to_sockaddr :: proc(ep: Endpoint) -> (sockaddr: os.SOCKADDR_STORAGE_LH) {
switch a in ep.address {
case IP4_Address:
diff --git a/core/net/socket_windows.odin b/core/net/socket_windows.odin
index d7264d617..3b9623749 100644
--- a/core/net/socket_windows.odin
+++ b/core/net/socket_windows.odin
@@ -311,6 +311,18 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca
}
@(private)
+_set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_Error) {
+ socket := any_socket_to_socket(socket)
+ arg: win.DWORD = 0 if should_block else 1
+ res := win.ioctlsocket(win.SOCKET(socket), transmute(win.c_long)win.FIONBIO, &arg)
+ if res == win.SOCKET_ERROR {
+ return Set_Blocking_Error(win.WSAGetLastError())
+ }
+
+ return nil
+}
+
+@(private)
_endpoint_to_sockaddr :: proc(ep: Endpoint) -> (sockaddr: win.SOCKADDR_STORAGE_LH) {
switch a in ep.address {
case IP4_Address: