net: ensure that `net` and `net.unix` can be imported together in the same program
parent
14073ac0fe
commit
c9867a9ae4
|
@ -6,6 +6,19 @@ $if windows {
|
||||||
#include "@VMODROOT/vlib/net/ipv6_v6only.h"
|
#include "@VMODROOT/vlib/net/ipv6_v6only.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$if windows {
|
||||||
|
$if msvc {
|
||||||
|
// Force these to be included before afunix!
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <afunix.h>
|
||||||
|
} $else {
|
||||||
|
#include "@VMODROOT/vlib/net/afunix.h"
|
||||||
|
}
|
||||||
|
} $else {
|
||||||
|
#include <sys/un.h>
|
||||||
|
}
|
||||||
|
|
||||||
// Select represents a select operation
|
// Select represents a select operation
|
||||||
enum Select {
|
enum Select {
|
||||||
read
|
read
|
||||||
|
|
|
@ -15,18 +15,21 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_in {
|
struct C.sockaddr_in {
|
||||||
|
mut:
|
||||||
sin_family u16
|
sin_family u16
|
||||||
sin_port u16
|
sin_port u16
|
||||||
sin_addr u32
|
sin_addr u32
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_in6 {
|
struct C.sockaddr_in6 {
|
||||||
|
mut:
|
||||||
sin6_family u16
|
sin6_family u16
|
||||||
sin6_port u16
|
sin6_port u16
|
||||||
sin6_addr [4]u32
|
sin6_addr [4]u32
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_un {
|
struct C.sockaddr_un {
|
||||||
|
mut:
|
||||||
sun_family u16
|
sun_family u16
|
||||||
sun_path [max_unix_path]char
|
sun_path [max_unix_path]char
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,18 +15,21 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_in {
|
struct C.sockaddr_in {
|
||||||
|
mut:
|
||||||
sin_family byte
|
sin_family byte
|
||||||
sin_port u16
|
sin_port u16
|
||||||
sin_addr u32
|
sin_addr u32
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_in6 {
|
struct C.sockaddr_in6 {
|
||||||
|
mut:
|
||||||
sin6_family byte
|
sin6_family byte
|
||||||
sin6_port u16
|
sin6_port u16
|
||||||
sin6_addr [4]u32
|
sin6_addr [4]u32
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_un {
|
struct C.sockaddr_un {
|
||||||
|
mut:
|
||||||
sun_family byte
|
sun_family byte
|
||||||
sun_path [max_unix_path]char
|
sun_path [max_unix_path]char
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,18 +15,21 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_in {
|
struct C.sockaddr_in {
|
||||||
|
mut:
|
||||||
sin_family u16
|
sin_family u16
|
||||||
sin_port u16
|
sin_port u16
|
||||||
sin_addr u32
|
sin_addr u32
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_in6 {
|
struct C.sockaddr_in6 {
|
||||||
|
mut:
|
||||||
sin6_family u16
|
sin6_family u16
|
||||||
sin6_port u16
|
sin6_port u16
|
||||||
sin6_addr [4]u32
|
sin6_addr [4]u32
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_un {
|
struct C.sockaddr_un {
|
||||||
|
mut:
|
||||||
sun_family u16
|
sun_family u16
|
||||||
sun_path [max_unix_path]char
|
sun_path [max_unix_path]char
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,5 @@
|
||||||
module net
|
module net
|
||||||
|
|
||||||
$if windows {
|
|
||||||
$if msvc {
|
|
||||||
// Force these to be included before afunix!
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <afunix.h>
|
|
||||||
} $else {
|
|
||||||
#include "@VMODROOT/vlib/net/afunix.h"
|
|
||||||
}
|
|
||||||
} $else {
|
|
||||||
#include <sys/un.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_diagnostics() {
|
fn test_diagnostics() {
|
||||||
dump(aoffset)
|
dump(aoffset)
|
||||||
eprintln('--------')
|
eprintln('--------')
|
||||||
|
|
|
@ -15,18 +15,21 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_in {
|
struct C.sockaddr_in {
|
||||||
|
mut:
|
||||||
sin_family u16
|
sin_family u16
|
||||||
sin_port u16
|
sin_port u16
|
||||||
sin_addr u32
|
sin_addr u32
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_in6 {
|
struct C.sockaddr_in6 {
|
||||||
|
mut:
|
||||||
sin6_family u16
|
sin6_family u16
|
||||||
sin6_port u16
|
sin6_port u16
|
||||||
sin6_addr [4]u32
|
sin6_addr [4]u32
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.sockaddr_un {
|
struct C.sockaddr_un {
|
||||||
|
mut:
|
||||||
sun_family u16
|
sun_family u16
|
||||||
sun_path [max_unix_path]char
|
sun_path [max_unix_path]char
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
module unix
|
module unix
|
||||||
|
|
||||||
#include <sys/un.h>
|
import net
|
||||||
|
|
||||||
|
const use_net = net.no_timeout
|
||||||
|
|
||||||
|
// 104 for macos, 108 for linux => use the minimum
|
||||||
|
const max_sun_path = 104
|
||||||
|
|
||||||
// Select represents a select operation
|
// Select represents a select operation
|
||||||
enum Select {
|
enum Select {
|
||||||
|
@ -15,88 +20,3 @@ enum Select {
|
||||||
// stream = C.SOCK_STREAM
|
// stream = C.SOCK_STREAM
|
||||||
// seqpacket = C.SOCK_SEQPACKET
|
// seqpacket = C.SOCK_SEQPACKET
|
||||||
// }
|
// }
|
||||||
|
|
||||||
struct C.sockaddr {
|
|
||||||
sa_family u16
|
|
||||||
}
|
|
||||||
|
|
||||||
const max_sun_path = 104
|
|
||||||
|
|
||||||
// 104 for macos, 108 for linux => use the minimum
|
|
||||||
|
|
||||||
struct C.sockaddr_un {
|
|
||||||
mut:
|
|
||||||
// sun_len byte // only on macos
|
|
||||||
sun_family int
|
|
||||||
sun_path [104]char // on linux that is 108
|
|
||||||
}
|
|
||||||
|
|
||||||
struct C.addrinfo {
|
|
||||||
mut:
|
|
||||||
ai_family int
|
|
||||||
ai_socktype int
|
|
||||||
ai_flags int
|
|
||||||
ai_protocol int
|
|
||||||
ai_addrlen int
|
|
||||||
ai_addr voidptr
|
|
||||||
ai_canonname voidptr
|
|
||||||
ai_next voidptr
|
|
||||||
}
|
|
||||||
|
|
||||||
struct C.sockaddr_storage {
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn C.socket() int
|
|
||||||
|
|
||||||
// fn C.setsockopt() int
|
|
||||||
|
|
||||||
// fn C.htonl() int
|
|
||||||
|
|
||||||
// fn C.htons() int
|
|
||||||
|
|
||||||
// fn C.bind() int
|
|
||||||
|
|
||||||
// fn C.listen() int
|
|
||||||
|
|
||||||
// fn C.accept() int
|
|
||||||
|
|
||||||
// fn C.getaddrinfo() int
|
|
||||||
|
|
||||||
// fn C.connect() int
|
|
||||||
|
|
||||||
// fn C.send() int
|
|
||||||
|
|
||||||
// fn C.sendto() int
|
|
||||||
|
|
||||||
// fn C.recv() int
|
|
||||||
|
|
||||||
// fn C.recvfrom() int
|
|
||||||
|
|
||||||
// fn C.shutdown() int
|
|
||||||
|
|
||||||
// fn C.getpeername() int
|
|
||||||
|
|
||||||
// fn C.inet_ntop(af int, src voidptr, dst charptr, dst_size int) charptr
|
|
||||||
|
|
||||||
fn C.WSAAddressToStringA() int
|
|
||||||
|
|
||||||
// fn C.getsockname() int
|
|
||||||
|
|
||||||
// defined in builtin
|
|
||||||
// fn C.read() int
|
|
||||||
// fn C.close() int
|
|
||||||
|
|
||||||
fn C.ioctlsocket() int
|
|
||||||
|
|
||||||
// fn C.fcntl() int
|
|
||||||
|
|
||||||
// fn C.@select() int
|
|
||||||
|
|
||||||
// fn C.FD_ZERO()
|
|
||||||
|
|
||||||
// fn C.FD_SET()
|
|
||||||
|
|
||||||
// fn C.FD_ISSET() bool
|
|
||||||
|
|
||||||
[typedef]
|
|
||||||
struct C.fd_set {}
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ fn (mut s StreamSocket) connect(a string) ? {
|
||||||
}
|
}
|
||||||
mut addr := C.sockaddr_un{}
|
mut addr := C.sockaddr_un{}
|
||||||
unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_un)) }
|
unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_un)) }
|
||||||
addr.sun_family = C.AF_UNIX
|
addr.sun_family = u16(C.AF_UNIX)
|
||||||
unsafe { C.strncpy(&addr.sun_path[0], &char(a.str), max_sun_path) }
|
unsafe { C.strncpy(&addr.sun_path[0], &char(a.str), max_sun_path) }
|
||||||
size := C.SUN_LEN(&addr)
|
size := C.SUN_LEN(&addr)
|
||||||
res := C.connect(s.handle, voidptr(&addr), size)
|
res := C.connect(s.handle, voidptr(&addr), size)
|
||||||
|
@ -94,7 +94,7 @@ pub fn listen_stream(sock string) ?&StreamListener {
|
||||||
s.path = sock
|
s.path = sock
|
||||||
mut addr := C.sockaddr_un{}
|
mut addr := C.sockaddr_un{}
|
||||||
unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_un)) }
|
unsafe { C.memset(&addr, 0, sizeof(C.sockaddr_un)) }
|
||||||
addr.sun_family = C.AF_UNIX
|
addr.sun_family = u16(C.AF_UNIX)
|
||||||
unsafe { C.strncpy(&addr.sun_path[0], &char(sock.str), max_sun_path) }
|
unsafe { C.strncpy(&addr.sun_path[0], &char(sock.str), max_sun_path) }
|
||||||
size := C.SUN_LEN(&addr)
|
size := C.SUN_LEN(&addr)
|
||||||
if os.exists(sock) {
|
if os.exists(sock) {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import os
|
||||||
|
import net.unix
|
||||||
|
import net
|
||||||
|
|
||||||
|
// ensure that `net` is used, i.e. no warnings
|
||||||
|
const use_net = net.no_timeout
|
||||||
|
|
||||||
|
const test_port = os.join_path(os.temp_dir(), 'unix_domain_socket')
|
||||||
|
|
||||||
|
fn test_that_net_and_net_unix_can_be_imported_together_without_conflicts() ? {
|
||||||
|
mut l := unix.listen_stream(test_port) or { panic(err) }
|
||||||
|
go echo_server(mut l)
|
||||||
|
defer {
|
||||||
|
l.close() ?
|
||||||
|
}
|
||||||
|
//
|
||||||
|
mut c := unix.connect_stream(test_port) ?
|
||||||
|
defer {
|
||||||
|
c.close() ?
|
||||||
|
}
|
||||||
|
//
|
||||||
|
data := 'Hello from vlib/net!'
|
||||||
|
c.write_string(data) ?
|
||||||
|
mut buf := []byte{len: 100}
|
||||||
|
assert c.read(mut buf) ? == data.len
|
||||||
|
eprintln('< client read back buf: |${buf[0..data.len].bytestr()}|')
|
||||||
|
assert buf[0..data.len] == data.bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn perror(s string) ? {
|
||||||
|
println(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_conn(mut c unix.StreamConn) ? {
|
||||||
|
for {
|
||||||
|
mut buf := []byte{len: 100, init: 0}
|
||||||
|
read := c.read(mut buf) or { return perror('Server: connection dropped') }
|
||||||
|
eprintln('> server read ${read:3}, buf: |$buf.bytestr()|')
|
||||||
|
c.write(buf[..read]) or { return perror('Server: connection dropped') }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn echo_server(mut l unix.StreamListener) ? {
|
||||||
|
for {
|
||||||
|
mut new_conn := l.accept() or { continue }
|
||||||
|
handle_conn(mut new_conn) or {}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue