From e3d183d2347590d7809170af633e29784cc8ada5 Mon Sep 17 00:00:00 2001 From: ge Date: Fri, 1 May 2026 20:58:09 +0300 Subject: [PATCH] upd14 --- socket.c.v | 40 +++++++++++++++++++++++++--------------- socket_test.v | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 socket_test.v diff --git a/socket.c.v b/socket.c.v index 82f5a7a..3ff2860 100644 --- a/socket.c.v +++ b/socket.c.v @@ -39,7 +39,8 @@ pub fn Socket.new(domain AddrFamily, st SocketType, proto Protocol) !Socket { // type reports the actual socket type. pub fn (s Socket) type() !SocketType { - return s.get_option_int(C.SOL_SOCKET, C.SO_TYPE)! + // return s.get_option_int(sol_socket, so_type)! + return s.get_option[SocketType](sol_socket, so_type)! } // Socket shutdown modes. See [shutdown(3p)](https://man7.org/linux/man-pages/man3/shutdown.3p.html) for details. @@ -88,28 +89,37 @@ pub fn (s Socket) accept() !(Socket, SocketAddr) { return sock, sock_addr } +fn (s Socket) set_option_raw(level SocketLevel, option SocketOption, value voidptr) ! { + if C.setsockopt(s.fd, i32(level), i32(option), value, sizeof(value)) == -1 { + return os.last_error() + } +} + // set_option sets the socket option. See [socket(7)](https://man7.org/linux/man-pages/man7/socket.7.html) // and [setsockopt(3p)](https://man7.org/linux/man-pages/man3/setsockopt.3p.html) for details. -pub fn (s Socket) set_option(level SocketLevel, option SocketOption, value voidptr) ! { - if C.setsockopt(s.fd, i32(level), i32(option), value, sizeof(value)) == -1 { +pub fn (s Socket) set_option[T](level SocketLevel, option SocketOption, value T) ! { + s.set_option_raw(level, option, &value)! +} + +fn (s Socket) get_option_raw(level SocketLevel, option SocketOption, mut value voidptr, mut size voidptr) ! { + if C.getsockopt(s.fd, i32(level), i32(option), value, size) == -1 { return os.last_error() } } // get_option gets the socket option. See [socket(7)](https://man7.org/linux/man-pages/man7/socket.7.html) // and [getsockopt(3p)](https://man7.org/linux/man-pages/man3/getsockopt.3p.html) for details. -pub fn (s Socket) get_option(level SocketLevel, option SocketOption, mut value voidptr, mut size voidptr) ! { - if C.getsockopt(s.fd, i32(level), i32(option), value, size) == -1 { - return os.last_error() - } -} - -// get_option gets the socket option as int. The same as `get_option`, but always returns int. -pub fn (s Socket) get_option_int(level SocketLevel, option SocketOption) !int { - mut result := -1 - if C.getsockopt(s.fd, i32(level), i32(option), &result, sizeof(result)) == -1 { - return os.last_error() - } +// Example: +// ```v +// import netio +// mut socket := netio.Socket.new(netio.af_inet, netio.sock_stream, 0)! +// socket.set_option(netio.sol_socket, netio.so_reuseaddr, true)! +// assert socket.get_option[bool](netio.sol_socket, netio.so_reuseaddr)! == true +// ``` +pub fn (s Socket) get_option[T](level SocketLevel, option SocketOption) !T { + mut result := T{} + mut size := sizeof(result) + s.get_option_raw(level, option, mut &result, mut &size)! return result } diff --git a/socket_test.v b/socket_test.v new file mode 100644 index 0000000..6b4ee5c --- /dev/null +++ b/socket_test.v @@ -0,0 +1,24 @@ +import netio + +fn test_socket_new() { + socket := netio.Socket.new(netio.af_inet, netio.sock_stream, 0)! + socket.close() or { panic(err) } + assert socket.fd != -1 +} + +fn test_socket_type() { + socket := netio.Socket.new(netio.af_inet, netio.sock_stream, 0)! + socket_type := socket.type()! + socket.close() or { panic(err) } + assert socket_type == netio.sock_stream +} + +fn test_socket_option() { + mut socket := netio.Socket.new(netio.af_inet, netio.sock_stream, 0)! + socket.set_option(netio.sol_socket, netio.so_reuseaddr, true)! + opt_val_int := socket.get_option[int](netio.sol_socket, netio.so_reuseaddr)! + opt_val_bool := socket.get_option[bool](netio.sol_socket, netio.so_reuseaddr)! + socket.close() or { panic(err) } + assert opt_val_int == 1 + assert opt_val_bool == true +}