Files
netio1/socket.c.v
T
2026-04-12 16:30:28 +03:00

127 lines
3.5 KiB
V

module netio
import os
#include <sys/socket.h>
#include <netinet/in.h>
fn C.socket(i32, i32, i32) i32
fn C.bind(i32, voidptr, i32) i32
fn C.connect(i32, voidptr, i32) i32
fn C.listen(i32, i32) i32
fn C.accept(i32, voidptr, voidptr) i32
fn C.shutdown(i32, i32) i32
fn C.close(i32) i32
fn C.setsockopt(i32, i32, i32, voidptr, i32) i32
fn C.getsockopt(i32, i32, i32, voidptr, voidptr) i32
struct C.sockaddr_storage {}
pub struct Socket {
pub:
fd int = -1
}
// Socket.new creates new socket.
// See [socket(7)](https://www.man7.org/linux/man-pages/man7/socket.7.html) and
// [socket(3)](https://man7.org/linux/man-pages/man3/socket.3p.html) for details.
pub fn Socket.new(domain AddrFamily, st SocketType, proto Protocol) !Socket {
fd := C.socket(i32(domain), i32(st), i32(proto))
if fd == -1 {
return os.last_error()
}
return Socket{
fd: fd
}
}
// type_of reports the actual socket type.
pub fn (s Socket) type_of() !SocketType {
return s.get_option_int(C.SOL_SOCKET, C.SO_TYPE)!
}
// Socket shutdown modes. See [shutdown(3p)](https://man7.org/linux/man-pages/man3/shutdown.3p.html) for details.
pub enum Shutdown {
read
write
read_and_write
}
// connect connects a socket.
pub fn (s Socket) connect(addr SocketAddr) ! {
if C.connect(s.fd, addr.ptr(), addr.size()) == -1 {
return os.last_error()
}
}
// bind binds a name to a socket.
pub fn (s Socket) bind(addr SocketAddr) ! {
if C.bind(s.fd, addr.ptr(), addr.size()) == -1 {
return os.last_error()
}
}
// listen starts listening for socket connections and limit the queue of incoming connections.
pub fn (s Socket) listen(backlog int) ! {
if C.listen(s.fd, backlog) == -1 {
return os.last_error()
}
}
// accept accepts a new connection on a socket.
// The return values are the new socket connected to remote and the remote socket address.
pub fn (s Socket) accept() !(Socket, SocketAddr) {
mut sock_addr_storage := &C.sockaddr_storage{}
mut sock_addr_len := sizeof(C.sockaddr_storage)
fd := C.accept(s.fd, sock_addr_storage, &sock_addr_len)
if fd == -1 {
return os.last_error()
}
sock := Socket{
fd: fd
}
sock_addr := unsafe {
SocketAddr.from_ptr(sock_addr_storage, sock_addr_len)!
}
return sock, sock_addr
}
// 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 {
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()
}
return result
}
// shutdown shut downs socket send and receive operations.
pub fn (s Socket) shutdown(how Shutdown) ! {
if C.shutdown(s.fd, i32(how)) == -1 {
return os.last_error()
}
}
// close closes the socket.
pub fn (s Socket) close() ! {
if C.close(s.fd) == -1 {
return os.last_error()
}
}