mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 08:45:52 +00:00
make std.net more portable
* Delete `std.net.TmpWinAddr`. I don't think that was ever meant to be a real thing. * Delete `std.net.OsAddress`. This abstraction was not helpful. * Rename `std.net.Address` to `std.net.IpAddress`. It is now an extern union of IPv4 and IPv6 addresses. * Move `std.net.parseIp4` and `std.net.parseIp6` to the `std.net.IpAddress` namespace. They now return `IpAddress` instead of `u32` and `std.net.Ip6Addr`, which is deleted. * Add `std.net.IpAddress.parse` which accepts a port and parses either an IPv4 or IPv6 address. * Add `std.net.IpAddress.parseExpectingFamily` which additionally accepts a `family` parameter. * `std.net.IpAddress.initIp4` and `std.net.IpAddress.initIp6` are improved to directly take the address fields instead of a weird in-between type. * `std.net.IpAddress.port` is renamed to `std.net.IpAddress.getPort`. * Added `std.net.IpAddress.setPort`. * `os.sockaddr` struct on all targets is improved to match the corresponding system struct. Previously I had made it a union of sockaddr_in, sockaddr_in6, and sockaddr_un. The new abstraction for this is now `std.net.IpAddress`. * `os.sockaddr` and related bits are added for Windows. * `os.sockaddr` and related bits now have the `zero` fields default to zero initialization, and `len` fields default to the correct size. This is enough to abstract the differences across targets, and so no more switch on the target OS is needed in `std.net.IpAddress`. * Add the missing `os.sockaddr_un` on FreeBSD and NetBSD. * `std.net.IpAddress.initPosix` now takes a pointer to `os.sockaddr`.
This commit is contained in:
parent
618ee5b63a
commit
0de862e8ba
@ -99,7 +99,7 @@ pub const Allocator = struct {
|
||||
/// memory is no longer needed, to avoid a resource leak. If the
|
||||
/// `Allocator` implementation is unknown, then correct code will
|
||||
/// call `free` when done.
|
||||
///
|
||||
///
|
||||
/// For allocating a single item, see `create`.
|
||||
pub fn alloc(self: *Allocator, comptime T: type, n: usize) Error![]T {
|
||||
return self.alignedAlloc(T, null, n);
|
||||
|
||||
693
lib/std/net.zig
693
lib/std/net.zig
File diff suppressed because it is too large
Load Diff
@ -3,44 +3,32 @@ const net = std.net;
|
||||
const mem = std.mem;
|
||||
const testing = std.testing;
|
||||
|
||||
test "parseIp4" {
|
||||
testing.expect((try net.parseIp4("127.0.0.1")) == mem.bigToNative(u32, 0x7f000001));
|
||||
|
||||
testParseIp4Fail("256.0.0.1", error.Overflow);
|
||||
testParseIp4Fail("x.0.0.1", error.InvalidCharacter);
|
||||
testParseIp4Fail("127.0.0.1.1", error.InvalidEnd);
|
||||
testParseIp4Fail("127.0.0.", error.Incomplete);
|
||||
testParseIp4Fail("100..0.1", error.InvalidCharacter);
|
||||
}
|
||||
|
||||
fn testParseIp4Fail(buf: []const u8, expected_err: anyerror) void {
|
||||
if (net.parseIp4(buf)) |_| {
|
||||
@panic("expected error");
|
||||
} else |e| {
|
||||
testing.expect(e == expected_err);
|
||||
}
|
||||
}
|
||||
|
||||
test "parseIp6" {
|
||||
const ip6 = try net.parseIp6("FF01:0:0:0:0:0:0:FB");
|
||||
const addr = net.Address.initIp6(ip6, 80);
|
||||
test "parse and render IPv6 addresses" {
|
||||
const addr = net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB", 80);
|
||||
var buf: [100]u8 = undefined;
|
||||
const printed = try std.fmt.bufPrint(&buf, "{}", addr);
|
||||
std.testing.expect(mem.eql(u8, "[ff01::fb]:80", printed));
|
||||
}
|
||||
|
||||
test "ip4s" {
|
||||
test "parse and render IPv4 addresses" {
|
||||
var buffer: [18]u8 = undefined;
|
||||
for ([_][]const u8{
|
||||
"0.0.0.0",
|
||||
"255.255.255.255",
|
||||
"1.2.3.4",
|
||||
"123.255.0.91",
|
||||
"127.0.0.1",
|
||||
}) |ip| {
|
||||
var addr = net.Address.initIp4(net.parseIp4(ip) catch unreachable, 0);
|
||||
var addr = net.IpAddress.parseIp4(ip, 0);
|
||||
var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;
|
||||
std.testing.expect(std.mem.eql(u8, ip, newIp[0 .. newIp.len - 2]));
|
||||
}
|
||||
|
||||
testing.expectError(error.Overflow, net.IpAddress.parseIp4("256.0.0.1", 0));
|
||||
testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("x.0.0.1", 0));
|
||||
testing.expectError(error.InvalidEnd, net.IpAddress.parseIp4("127.0.0.1.1", 0));
|
||||
testing.expectError(error.Incomplete, net.IpAddress.parseIp4("127.0.0.", 0));
|
||||
testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("100..0.1", 0));
|
||||
}
|
||||
|
||||
test "resolve DNS" {
|
||||
@ -72,7 +60,7 @@ test "listen on a port, send bytes, receive bytes" {
|
||||
}
|
||||
|
||||
// TODO doing this at comptime crashed the compiler
|
||||
const localhost = net.Address.initIp4(net.parseIp4("127.0.0.1") catch unreachable, 0);
|
||||
const localhost = net.IpAddress.parse("127.0.0.1", 0);
|
||||
|
||||
var server = net.TcpServer.init(net.TcpServer.Options{});
|
||||
defer server.deinit();
|
||||
@ -85,7 +73,7 @@ test "listen on a port, send bytes, receive bytes" {
|
||||
try await client_frame;
|
||||
}
|
||||
|
||||
fn testClient(addr: net.Address) anyerror!void {
|
||||
fn testClient(addr: net.IpAddress) anyerror!void {
|
||||
const socket_file = try net.tcpConnectToAddress(addr);
|
||||
defer socket_file.close();
|
||||
|
||||
|
||||
@ -1920,9 +1920,9 @@ pub const ConnectError = error{
|
||||
} || UnexpectedError;
|
||||
|
||||
/// Initiate a connection on a socket.
|
||||
pub fn connect(sockfd: fd_t, sock_addr: sockaddr, len: socklen_t) ConnectError!void {
|
||||
pub fn connect(sockfd: fd_t, sock_addr: *const sockaddr, len: socklen_t) ConnectError!void {
|
||||
while (true) {
|
||||
switch (errno(system.connect(sockfd, &sock_addr, len))) {
|
||||
switch (errno(system.connect(sockfd, sock_addr, len))) {
|
||||
0 => return,
|
||||
EACCES => return error.PermissionDenied,
|
||||
EPERM => return error.PermissionDenied,
|
||||
|
||||
@ -9,28 +9,31 @@ pub const in_port_t = u16;
|
||||
pub const sa_family_t = u8;
|
||||
pub const socklen_t = u32;
|
||||
pub const sockaddr = extern union {
|
||||
in: sockaddr_in,
|
||||
in6: sockaddr_in6,
|
||||
un: sockaddr_un,
|
||||
len: u8,
|
||||
family: sa_family_t,
|
||||
data: [14]u8,
|
||||
};
|
||||
pub const sockaddr_in = extern struct {
|
||||
len: u8,
|
||||
family: sa_family_t,
|
||||
len: u8 = @sizeOf(sockaddr_in),
|
||||
family: sa_family_t = AF_INET,
|
||||
port: in_port_t,
|
||||
addr: u32,
|
||||
zero: [8]u8,
|
||||
zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
pub const sockaddr_in6 = extern struct {
|
||||
len: u8,
|
||||
family: sa_family_t,
|
||||
len: u8 = @sizeOf(sockaddr_in6),
|
||||
family: sa_family_t = AF_INET6,
|
||||
port: in_port_t,
|
||||
flowinfo: u32,
|
||||
addr: [16]u8,
|
||||
scope_id: u32,
|
||||
};
|
||||
|
||||
/// UNIX domain socket
|
||||
pub const sockaddr_un = extern struct {
|
||||
len: u8,
|
||||
family: sa_family_t,
|
||||
len: u8 = @sizeOf(sockaddr_un),
|
||||
family: sa_family_t = AF_UNIX,
|
||||
path: [104]u8,
|
||||
};
|
||||
|
||||
pub const timeval = extern struct {
|
||||
|
||||
@ -138,27 +138,39 @@ pub const in_port_t = u16;
|
||||
pub const sa_family_t = u16;
|
||||
|
||||
pub const sockaddr = extern union {
|
||||
in: sockaddr_in,
|
||||
in6: sockaddr_in6,
|
||||
/// total length
|
||||
len: u8,
|
||||
|
||||
/// address family
|
||||
family: sa_family_t,
|
||||
|
||||
/// actually longer; address value
|
||||
data: [14]u8,
|
||||
};
|
||||
|
||||
pub const sockaddr_in = extern struct {
|
||||
len: u8,
|
||||
family: sa_family_t,
|
||||
len: u8 = @sizeOf(sockaddr_in),
|
||||
family: sa_family_t = AF_INET,
|
||||
port: in_port_t,
|
||||
addr: [16]u8,
|
||||
zero: [8]u8,
|
||||
addr: u32,
|
||||
zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
pub const sockaddr_in6 = extern struct {
|
||||
len: u8,
|
||||
family: sa_family_t,
|
||||
len: u8 = @sizeOf(sockaddr_in6),
|
||||
family: sa_family_t = AF_INET6,
|
||||
port: in_port_t,
|
||||
flowinfo: u32,
|
||||
addr: [16]u8,
|
||||
scope_id: u32,
|
||||
};
|
||||
|
||||
pub const sockaddr_un = extern struct {
|
||||
len: u8 = @sizeOf(sockaddr_un),
|
||||
family: sa_family_t = AF_UNIX,
|
||||
path: [104]u8,
|
||||
};
|
||||
|
||||
pub const CTL_KERN = 1;
|
||||
pub const CTL_DEBUG = 5;
|
||||
|
||||
|
||||
@ -846,30 +846,31 @@ pub const in_port_t = u16;
|
||||
pub const sa_family_t = u16;
|
||||
pub const socklen_t = u32;
|
||||
|
||||
/// This intentionally only has ip4 and ip6
|
||||
pub const sockaddr = extern union {
|
||||
in: sockaddr_in,
|
||||
in6: sockaddr_in6,
|
||||
un: sockaddr_un,
|
||||
family: sa_family_t,
|
||||
data: [14]u8,
|
||||
};
|
||||
|
||||
/// IPv4 socket address
|
||||
pub const sockaddr_in = extern struct {
|
||||
family: sa_family_t,
|
||||
family: sa_family_t = AF_INET,
|
||||
port: in_port_t,
|
||||
addr: u32,
|
||||
zero: [8]u8,
|
||||
zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
/// IPv6 socket address
|
||||
pub const sockaddr_in6 = extern struct {
|
||||
family: sa_family_t,
|
||||
family: sa_family_t = AF_INET6,
|
||||
port: in_port_t,
|
||||
flowinfo: u32,
|
||||
addr: [16]u8,
|
||||
scope_id: u32,
|
||||
};
|
||||
|
||||
/// UNIX domain socket address
|
||||
pub const sockaddr_un = extern struct {
|
||||
family: sa_family_t,
|
||||
family: sa_family_t = AF_UNIX,
|
||||
path: [108]u8,
|
||||
};
|
||||
|
||||
|
||||
@ -134,20 +134,26 @@ pub const in_port_t = u16;
|
||||
pub const sa_family_t = u8;
|
||||
|
||||
pub const sockaddr = extern union {
|
||||
in: sockaddr_in,
|
||||
in6: sockaddr_in6,
|
||||
/// total length
|
||||
len: u8,
|
||||
|
||||
/// address family
|
||||
family: sa_family_t,
|
||||
|
||||
/// actually longer; address value
|
||||
data: [14]u8,
|
||||
};
|
||||
|
||||
pub const sockaddr_in = extern struct {
|
||||
len: u8,
|
||||
len: u8 = @sizeOf(sockaddr_in),
|
||||
family: sa_family_t,
|
||||
port: in_port_t,
|
||||
addr: u32,
|
||||
zero: [8]u8,
|
||||
zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
pub const sockaddr_in6 = extern struct {
|
||||
len: u8,
|
||||
len: u8 = @sizeOf(sockaddr_in6),
|
||||
family: sa_family_t,
|
||||
port: in_port_t,
|
||||
flowinfo: u32,
|
||||
@ -155,6 +161,18 @@ pub const sockaddr_in6 = extern struct {
|
||||
scope_id: u32,
|
||||
};
|
||||
|
||||
/// Definitions for UNIX IPC domain.
|
||||
pub const sockaddr_un = extern struct {
|
||||
/// total sockaddr length
|
||||
len: u8 = @sizeOf(sockaddr_un),
|
||||
|
||||
/// AF_LOCAL
|
||||
family: sa_family_t,
|
||||
|
||||
/// path name
|
||||
path: [104]u8,
|
||||
};
|
||||
|
||||
pub const CTL_KERN = 1;
|
||||
pub const CTL_DEBUG = 5;
|
||||
|
||||
|
||||
@ -161,3 +161,63 @@ pub const F_OK = 0;
|
||||
|
||||
/// Remove directory instead of unlinking file
|
||||
pub const AT_REMOVEDIR = 0x200;
|
||||
|
||||
pub const in_port_t = u16;
|
||||
pub const sa_family_t = u16;
|
||||
pub const socklen_t = u32;
|
||||
|
||||
pub const sockaddr = extern struct {
|
||||
family: sa_family_t,
|
||||
data: [14]u8,
|
||||
};
|
||||
pub const sockaddr_in = extern struct {
|
||||
family: sa_family_t = AF_INET,
|
||||
port: in_port_t,
|
||||
addr: in_addr,
|
||||
zero: [8]u8 = [8]u8{ 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
pub const sockaddr_in6 = extern struct {
|
||||
family: sa_family_t = AF_INET6,
|
||||
port: in_port_t,
|
||||
flowinfo: u32,
|
||||
addr: in6_addr,
|
||||
scope_id: u32,
|
||||
};
|
||||
pub const in6_addr = [16]u8;
|
||||
pub const in_addr = u32;
|
||||
|
||||
pub const AF_UNSPEC = 0;
|
||||
pub const AF_UNIX = 1;
|
||||
pub const AF_INET = 2;
|
||||
pub const AF_IMPLINK = 3;
|
||||
pub const AF_PUP = 4;
|
||||
pub const AF_CHAOS = 5;
|
||||
pub const AF_NS = 6;
|
||||
pub const AF_IPX = AF_NS;
|
||||
pub const AF_ISO = 7;
|
||||
pub const AF_OSI = AF_ISO;
|
||||
pub const AF_ECMA = 8;
|
||||
pub const AF_DATAKIT = 9;
|
||||
pub const AF_CCITT = 10;
|
||||
pub const AF_SNA = 11;
|
||||
pub const AF_DECnet = 12;
|
||||
pub const AF_DLI = 13;
|
||||
pub const AF_LAT = 14;
|
||||
pub const AF_HYLINK = 15;
|
||||
pub const AF_APPLETALK = 16;
|
||||
pub const AF_NETBIOS = 17;
|
||||
pub const AF_VOICEVIEW = 18;
|
||||
pub const AF_FIREFOX = 19;
|
||||
pub const AF_UNKNOWN1 = 20;
|
||||
pub const AF_BAN = 21;
|
||||
pub const AF_ATM = 22;
|
||||
pub const AF_INET6 = 23;
|
||||
pub const AF_CLUSTER = 24;
|
||||
pub const AF_12844 = 25;
|
||||
pub const AF_IRDA = 26;
|
||||
pub const AF_NETDES = 28;
|
||||
pub const AF_TCNPROCESS = 29;
|
||||
pub const AF_TCNMESSAGE = 30;
|
||||
pub const AF_ICLFXBM = 31;
|
||||
pub const AF_BTH = 32;
|
||||
pub const AF_MAX = 33;
|
||||
|
||||
@ -162,9 +162,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
\\ const obj = AstObject{ .lhsExpr = lhsExpr };
|
||||
\\}
|
||||
,
|
||||
"tmp.zig:1:17: error: struct 'LhsExpr' depends on itself",
|
||||
"tmp.zig:5:5: note: while checking this field",
|
||||
"tmp.zig:4:19: error: union 'AstObject' depends on itself",
|
||||
"tmp.zig:2:5: note: while checking this field",
|
||||
"tmp.zig:5:5: note: while checking this field",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user