net: add basic unix socket support (#8642)

pull/8650/head
bettafish04 2021-02-08 23:48:23 +01:00 committed by GitHub
parent 09cff69919
commit 1a2ae0aead
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 17 deletions

View File

@ -2,7 +2,9 @@ module net
// Select represents a select operation // Select represents a select operation
enum Select { enum Select {
read write except read
write
except
} }
// SocketType are the available sockets // SocketType are the available sockets
@ -13,7 +15,8 @@ pub enum SocketType {
// SocketFamily are the available address families // SocketFamily are the available address families
pub enum SocketFamily { pub enum SocketFamily {
inet = C. AF_INET inet = C.AF_INET
unix = C.AF_UNIX
} }
struct C.in_addr { struct C.in_addr {
@ -32,6 +35,11 @@ mut:
sin_addr C.in_addr sin_addr C.in_addr
} }
struct C.sockaddr_un {
mut:
sun_family int
sun_path charptr
}
struct C.addrinfo { struct C.addrinfo {
mut: mut:
@ -67,9 +75,11 @@ fn C.getaddrinfo() int
fn C.connect() int fn C.connect() int
fn C.send() int fn C.send() int
fn C.sendto() int fn C.sendto() int
fn C.recv() int fn C.recv() int
fn C.recvfrom() int fn C.recvfrom() int
fn C.shutdown() int fn C.shutdown() int
@ -89,11 +99,15 @@ fn C.getsockname() int
// fn C.close() int // fn C.close() int
fn C.ioctlsocket() int fn C.ioctlsocket() int
fn C.fcntl() int fn C.fcntl() int
fn C.@select() int fn C.@select() int
fn C.FD_ZERO() fn C.FD_ZERO()
fn C.FD_SET() fn C.FD_SET()
fn C.FD_ISSET() bool fn C.FD_ISSET() bool
[typedef] [typedef]

View File

@ -13,7 +13,7 @@ struct C.addrinfo {
} }
pub fn (a Addr) str() string { pub fn (a Addr) str() string {
return '${a.saddr}:${a.port}' return '$a.saddr:$a.port'
} }
const ( const (
@ -29,21 +29,21 @@ fn new_addr(addr C.sockaddr) ?Addr {
0 0
} }
// Convert to string representation // Convert to string representation
buf := []byte{ len: max_ipv4_addr_len, init: 0 } buf := []byte{len: net.max_ipv4_addr_len, init: 0}
$if windows { $if windows {
res := C.WSAAddressToStringA(&addr, addr_len, C.NULL, buf.data, &buf.len) res := C.WSAAddressToStringA(&addr, addr_len, C.NULL, buf.data, &buf.len)
if res != 0 { if res != 0 {
socket_error(-1)? socket_error(-1) ?
} }
} $else { } $else {
res := C.inet_ntop(SocketFamily.inet, &addr, buf.data, buf.len) res := C.inet_ntop(SocketFamily.inet, &addr, buf.data, buf.len)
if res == 0 { if res == 0 {
socket_error(-1)? socket_error(-1) ?
} }
} }
mut saddr := buf.bytestr() mut saddr := buf.bytestr()
hport := unsafe {&C.sockaddr_in(&addr)}.sin_port hport := unsafe { &C.sockaddr_in(&addr) }.sin_port
port := C.ntohs(hport) port := C.ntohs(hport)
$if windows { $if windows {
@ -51,13 +51,11 @@ fn new_addr(addr C.sockaddr) ?Addr {
saddr = saddr.split(':')[0] saddr = saddr.split(':')[0]
} }
return Addr { return Addr{addr, int(addr_len), saddr, port}
addr int(addr_len) saddr port
}
} }
pub fn resolve_addr(addr string, family SocketFamily, typ SocketType) ?Addr { pub fn resolve_addr(addr string, family SocketFamily, typ SocketType) ?Addr {
address, port := split_address(addr)? address, port := split_address(addr) ?
mut hints := C.addrinfo{} mut hints := C.addrinfo{}
hints.ai_family = int(family) hints.ai_family = int(family)
@ -74,10 +72,10 @@ pub fn resolve_addr(addr string, family SocketFamily, typ SocketType) ?Addr {
// This might look silly but is recommended by MSDN // This might look silly but is recommended by MSDN
$if windows { $if windows {
socket_error(0-C.getaddrinfo(address.str, sport.str, &hints, &info))? socket_error(0 - C.getaddrinfo(address.str, sport.str, &hints, &info)) ?
} $else { } $else {
x := C.getaddrinfo(address.str, sport.str, &hints, &info) x := C.getaddrinfo(address.str, sport.str, &hints, &info)
wrap_error(x)? wrap_error(x) ?
} }
return new_addr(*info.ai_addr) return new_addr(*info.ai_addr)

View File

@ -3,6 +3,7 @@ module net
#include <unistd.h> #include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h>
#include <sys/select.h> #include <sys/select.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -10,6 +11,7 @@ module net
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#flag solaris -lsocket #flag solaris -lsocket
fn error_code() int { fn error_code() int {
return C.errno return C.errno
} }