net: ensure that `net` and `net.unix` can be imported together in the same program

pull/13511/head
Delyan Angelov 2022-02-18 11:23:45 +02:00
parent 14073ac0fe
commit c9867a9ae4
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
9 changed files with 81 additions and 101 deletions

View File

@ -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

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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('--------')

View File

@ -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
} }

View File

@ -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 {}

View File

@ -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) {

View File

@ -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 {}
}
}