handle: Handle;
close :: socket_close
+ setting :: socket_setting
+ is_alive :: socket_is_alive
bind :: socket_bind
listen :: socket_listen
accept :: socket_accept
}
SocketSetting :: enum {
+ NonBlocking :: 0x01;
}
socket_create :: (domain: SocketDomain, type: SocketType) -> (Socket, SocketError) {
}
socket_setting :: (s: ^Socket, setting: SocketSetting, value: u32) {
+ __net_setting(s.handle, setting, value);
+}
+
+socket_is_alive :: (s: ^Socket) -> bool {
+ return s.vtable != null;
}
socket_connect :: (s: ^Socket, host: str, port: u16) -> SocketError {
return new_socket;
}
-socket_send :: (s: ^Socket, data: [] u8) -> u32 {
+socket_send :: (s: ^Socket, data: [] u8) -> i32 {
sent := __net_send(s.handle, data);
+ if sent < 0 { s.vtable = null; }
return sent;
}
while to_send.count > 0 {
sent := __net_send(s.handle, to_send);
- to_send = to_send[sent .. to_send.count];
+ if sent < 0 { s.vtable = null; return; }
+ else do to_send = to_send[sent .. to_send.count];
}
}
return result;
}
-socket_recv_into :: (s: ^Socket, buffer: [] u8) -> u32 {
+socket_recv_into :: (s: ^Socket, buffer: [] u8) -> i32 {
return __net_recv(s.handle, buffer);
}
#foreign "onyx_runtime" {
#package __net_create_socket :: (out_handle: ^Socket.Handle, domain: SocketDomain, type: SocketType) -> SocketError ---
#package __net_close_socket :: (handle: Socket.Handle) -> void ---
+ #package __net_setting :: (handle: Socket.Handle, setting: SocketSetting, value: i32) -> void ---
#package __net_bind :: (handle: Socket.Handle, port: u16) -> bool ---
#package __net_listen :: (handle: Socket.Handle, backlog: i32) -> void ---
#package __net_accept :: (handle: Socket.Handle) -> Socket.Handle --- // This should also return the address, but in what format?
#package __net_connect :: (handle: Socket.Handle, host: str, port: u16) -> SocketError ---
- #package __net_send :: (handle: Socket.Handle, data: [] u8) -> u32 ---
- #package __net_recv :: (handle: Socket.Handle, data: [] u8) -> u32 ---
+ #package __net_send :: (handle: Socket.Handle, data: [] u8) -> i32 ---
+ #package __net_recv :: (handle: Socket.Handle, data: [] u8) -> i32 ---
}
#operator >= macro (a, b: Socket.Handle) => cast(u32) a >= cast(u32) b;
ONYX_DEF(__net_close_socket, (WASM_I32), ()) {
#ifdef _BH_LINUX
+ shutdown(params->data[0].of.i32, SHUT_RDWR);
close(params->data[0].of.i32);
#endif
return NULL;
}
+ONYX_DEF(__net_setting, (WASM_I32, WASM_I32, WASM_I32), ()) {
+ #ifdef _BH_LINUX
+ switch (params->data[1].of.i32) {
+ case 1: { // :EnumDependent Non-Blocking
+ int s = params->data[0].of.i32;
+ int flags = fcntl(s, F_GETFL, 0);
+ if (params->data[2].of.i32) {
+ flags |= O_NONBLOCK;
+ } else {
+ flags &= ~O_NONBLOCK;
+ }
+
+ fcntl(s, F_SETFL, flags);
+ break;
+ }
+ }
+ #endif
+
+ return NULL;
+}
+
ONYX_DEF(__net_bind, (WASM_I32, WASM_I32), (WASM_I32)) {
#ifdef _BH_LINUX
ONYX_DEF(__net_send, (WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) {
#ifdef _BH_LINUX
// TODO: The flags at the end should be controllable.
- int sent = send(params->data[0].of.i32, ONYX_PTR(params->data[1].of.i32), params->data[2].of.i32, 0);
+ int sent = send(params->data[0].of.i32, ONYX_PTR(params->data[1].of.i32), params->data[2].of.i32, MSG_NOSIGNAL);
results->data[0] = WASM_I32_VAL(sent);
#endif
ONYX_FUNC(__net_create_socket)
ONYX_FUNC(__net_close_socket)
+ ONYX_FUNC(__net_setting)
ONYX_FUNC(__net_bind)
ONYX_FUNC(__net_listen)
ONYX_FUNC(__net_accept)