NonBlocking :: 0x01;
}
+Socket_Address :: struct {
+ Handle :: #distinct u64
+ addr: Handle;
+
+ get_address :: (s: ^Socket_Address, allocator := context.allocator) -> [] u8 {
+ buf: [256] u8;
+ addr_len := __net_address_get_address(s.addr, buf);
+
+ ret := memory.copy_slice(buf[0 .. addr_len], allocator=allocator);
+ return ret;
+ }
+
+ get_port :: (s: ^Socket_Address) -> u32 {
+ return __net_address_get_port(s.addr);
+ }
+}
+
socket_create :: (domain: SocketDomain, type: SocketType) -> (Socket, SocketError) {
s: Socket;
__net_listen(s.handle, backlog);
}
-socket_accept :: (s: ^Socket) -> Socket {
+socket_accept :: (s: ^Socket) -> (Socket, Socket_Address) {
new_socket: Socket;
- new_socket.handle = __net_accept(s.handle);
+ new_addr: Socket_Address;
+ new_socket.handle = __net_accept(s.handle, ^new_addr.addr);
+
if new_socket.handle >= 0 {
new_socket.vtable = ^__net_socket_vtable;
}
- return new_socket;
+ return new_socket, new_addr;
}
socket_poll_all :: (changed: ^[] ^Socket, timeout: i32, sockets: [] ^Socket) {
#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_accept :: (handle: Socket.Handle, out_address: ^Socket_Address.Handle) -> Socket.Handle ---
#package __net_connect :: (handle: Socket.Handle, host: str, port: u16) -> SocketError ---
#package __net_send :: (handle: Socket.Handle, data: [] u8) -> i32 ---
#package __net_recv :: (handle: Socket.Handle, data: [] u8) -> i32 ---
#package __net_poll_recv :: (handle: [] Socket.Handle, timeout: i32, out_recv: ^Socket.Handle) -> i32 ---
+
+ #package __net_address_get_address :: (address: Socket_Address.Handle, out_buffer: [] u8) -> i32 ---
+ #package __net_address_get_port :: (address: Socket_Address.Handle) -> i32 ---
}
#operator >= macro (a, b: Socket.Handle) => cast(u32) a >= cast(u32) b;
#include <sys/types.h>
#include <dlfcn.h>
#include <dirent.h>
+ #include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
+ #include <sys/socket.h>
#include <poll.h>
#endif
return NULL;
}
-ONYX_DEF(__net_accept, (WASM_I32), (WASM_I32)) {
+ONYX_DEF(__net_accept, (WASM_I32, WASM_I32), (WASM_I32)) {
#ifdef _BH_LINUX
- struct sockaddr_in client_addr;
- int client_len = sizeof(client_addr);
+ struct sockaddr_in *client_addr = malloc(sizeof(*client_addr));
+ int client_len = sizeof(*client_addr);
+ memset(client_addr, 0, client_len);
- int client_socket = accept(params->data[0].of.i32, &client_addr, &client_len);
+ int client_socket = accept(params->data[0].of.i32, client_addr, &client_len);
+ *(i64 *) ONYX_PTR(params->data[1].of.i32) = (i64) client_addr;
results->data[0] = WASM_I32_VAL(client_socket);
#endif
return NULL;
}
+ONYX_DEF(__net_address_get_address, (WASM_I64, WASM_I32, WASM_I32), (WASM_I32)) {
+ int maximum_length = params->data[2].of.i32;
+ int address_len = 0;
+
+ struct sockaddr_in *addr = (struct sockaddr_in *) params->data[0].of.i64;
+ if (addr == NULL) goto done;
+
+ char *address = inet_ntoa(addr->sin_addr);
+ if (address) address_len = strnlen(address, maximum_length);
+
+ memcpy(ONYX_PTR(params->data[1].of.i32), address, address_len);
+
+done:
+ results->data[0] = WASM_I32_VAL(address_len);
+ return NULL;
+}
+
+ONYX_DEF(__net_address_get_port, (WASM_I64), (WASM_I32)) {
+ struct sockaddr_in *addr = (struct sockaddr_in *) params->data[0].of.i64;
+ if (addr == NULL) results->data[0] = WASM_I32_VAL(-1);
+ else results->data[0] = WASM_I32_VAL(addr->sin_port);
+ return NULL;
+}
+
ONYX_LIBRARY {
ONYX_FUNC(__file_open_impl)
ONYX_FUNC(__net_send)
ONYX_FUNC(__net_recv)
ONYX_FUNC(__net_poll_recv)
+ ONYX_FUNC(__net_address_get_address)
+ ONYX_FUNC(__net_address_get_port)
NULL
};