mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 22:28:46 +00:00
Add set_blocking for network sockets
This commit is contained in:
@@ -64,6 +64,7 @@ Network_Error :: union #shared_nil {
|
|||||||
UDP_Recv_Error,
|
UDP_Recv_Error,
|
||||||
Shutdown_Error,
|
Shutdown_Error,
|
||||||
Socket_Option_Error,
|
Socket_Option_Error,
|
||||||
|
Set_Blocking_Error,
|
||||||
Parse_Endpoint_Error,
|
Parse_Endpoint_Error,
|
||||||
Resolve_Error,
|
Resolve_Error,
|
||||||
DNS_Error,
|
DNS_Error,
|
||||||
|
|||||||
@@ -197,4 +197,10 @@ Socket_Option_Error :: enum c.int {
|
|||||||
Invalid_Option_For_Socket = c.int(os.ENOPROTOOPT),
|
Invalid_Option_For_Socket = c.int(os.ENOPROTOOPT),
|
||||||
Reset_When_Keepalive_Set = c.int(os.ENOTCONN),
|
Reset_When_Keepalive_Set = c.int(os.ENOTCONN),
|
||||||
Not_Socket = c.int(os.ENOTSOCK),
|
Not_Socket = c.int(os.ENOTSOCK),
|
||||||
|
}
|
||||||
|
|
||||||
|
Set_Blocking_Error :: enum c.int {
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
// TODO: Add errors for `set_blocking`
|
||||||
}
|
}
|
||||||
@@ -190,4 +190,12 @@ Socket_Option_Error :: enum c.int {
|
|||||||
Invalid_Option_For_Socket = c.int(os.ENOPROTOOPT),
|
Invalid_Option_For_Socket = c.int(os.ENOPROTOOPT),
|
||||||
Reset_When_Keepalive_Set = c.int(os.ENOTCONN),
|
Reset_When_Keepalive_Set = c.int(os.ENOTCONN),
|
||||||
Not_Socket = c.int(os.ENOTSOCK),
|
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))
|
||||||
}
|
}
|
||||||
@@ -259,3 +259,15 @@ Socket_Option_Error :: enum c.int {
|
|||||||
Reset_When_Keepalive_Set = win.WSAENOTCONN,
|
Reset_When_Keepalive_Set = win.WSAENOTCONN,
|
||||||
Not_Socket = win.WSAENOTSOCK,
|
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,
|
||||||
|
}
|
||||||
@@ -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 {
|
set_option :: proc(socket: Any_Socket, option: Socket_Option, value: any, loc := #caller_location) -> Network_Error {
|
||||||
return _set_option(socket, option, value, loc)
|
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)
|
||||||
}
|
}
|
||||||
@@ -301,6 +301,12 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_Error) {
|
||||||
|
// TODO: Implement
|
||||||
|
unimplemented()
|
||||||
|
}
|
||||||
|
|
||||||
@private
|
@private
|
||||||
_endpoint_to_sockaddr :: proc(ep: Endpoint) -> (sockaddr: os.SOCKADDR_STORAGE_LH) {
|
_endpoint_to_sockaddr :: proc(ep: Endpoint) -> (sockaddr: os.SOCKADDR_STORAGE_LH) {
|
||||||
switch a in ep.address {
|
switch a in ep.address {
|
||||||
|
|||||||
@@ -316,6 +316,29 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(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)
|
@(private)
|
||||||
_endpoint_to_sockaddr :: proc(ep: Endpoint) -> (sockaddr: os.SOCKADDR_STORAGE_LH) {
|
_endpoint_to_sockaddr :: proc(ep: Endpoint) -> (sockaddr: os.SOCKADDR_STORAGE_LH) {
|
||||||
switch a in ep.address {
|
switch a in ep.address {
|
||||||
|
|||||||
@@ -310,6 +310,18 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(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)
|
@(private)
|
||||||
_endpoint_to_sockaddr :: proc(ep: Endpoint) -> (sockaddr: win.SOCKADDR_STORAGE_LH) {
|
_endpoint_to_sockaddr :: proc(ep: Endpoint) -> (sockaddr: win.SOCKADDR_STORAGE_LH) {
|
||||||
switch a in ep.address {
|
switch a in ep.address {
|
||||||
|
|||||||
@@ -225,6 +225,11 @@ TCP_CORK: int : 3
|
|||||||
|
|
||||||
MSG_TRUNC : int : 0x20
|
MSG_TRUNC : int : 0x20
|
||||||
|
|
||||||
|
// TODO: add remaining fcntl commands
|
||||||
|
// reference: https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/fcntl.h
|
||||||
|
F_GETFL: int : 3 /* Get file flags */
|
||||||
|
F_SETFL: int : 4 /* Set file flags */
|
||||||
|
|
||||||
// NOTE(zangent): These are OS specific!
|
// NOTE(zangent): These are OS specific!
|
||||||
// Do not mix these up!
|
// Do not mix these up!
|
||||||
RTLD_LAZY :: 0x001
|
RTLD_LAZY :: 0x001
|
||||||
@@ -1074,3 +1079,11 @@ shutdown :: proc(sd: Socket, how: int) -> (Errno) {
|
|||||||
}
|
}
|
||||||
return ERROR_NONE
|
return ERROR_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fcntl :: proc(fd: int, cmd: int, arg: int) -> (int, Errno) {
|
||||||
|
result := unix.sys_fcntl(fd, cmd, arg)
|
||||||
|
if result < 0 {
|
||||||
|
return 0, _get_errno(result)
|
||||||
|
}
|
||||||
|
return result, ERROR_NONE
|
||||||
|
}
|
||||||
@@ -2053,6 +2053,10 @@ sys_personality :: proc(persona: u64) -> int {
|
|||||||
return int(intrinsics.syscall(SYS_personality, uintptr(persona)))
|
return int(intrinsics.syscall(SYS_personality, uintptr(persona)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sys_fcntl :: proc "contextless" (fd: int, cmd: int, arg: int) -> int {
|
||||||
|
return int(intrinsics.syscall(SYS_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg)))
|
||||||
|
}
|
||||||
|
|
||||||
get_errno :: proc "contextless" (res: int) -> i32 {
|
get_errno :: proc "contextless" (res: int) -> i32 {
|
||||||
if res < 0 && res > -4096 {
|
if res < 0 && res > -4096 {
|
||||||
return i32(-res)
|
return i32(-res)
|
||||||
|
|||||||
Reference in New Issue
Block a user