net: add basic unix socket support (#8642)
parent
09cff69919
commit
1a2ae0aead
|
@ -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]
|
||||||
|
|
|
@ -3,22 +3,22 @@ module net
|
||||||
// Addr represents an ip address
|
// Addr represents an ip address
|
||||||
pub struct Addr {
|
pub struct Addr {
|
||||||
addr C.sockaddr
|
addr C.sockaddr
|
||||||
len int
|
len int
|
||||||
pub:
|
pub:
|
||||||
saddr string
|
saddr string
|
||||||
port int
|
port int
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.addrinfo {
|
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 (
|
||||||
max_ipv4_addr_len = 24
|
max_ipv4_addr_len = 24
|
||||||
ipv4_addr_size = sizeof(C.sockaddr_in)
|
ipv4_addr_size = sizeof(C.sockaddr_in)
|
||||||
)
|
)
|
||||||
|
|
||||||
fn new_addr(addr C.sockaddr) ?Addr {
|
fn new_addr(addr C.sockaddr) ?Addr {
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue