authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-02 15:28:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-06-02 15:28:46-04:00
log7fd937fef4547a98d7c33ea67eca76e6336f9152
tree9122d4a2eab8b9deef81e089cecee0e7699a08fa
parent0d091dc92374a49c41d406b5bf9a4b508a3d450c

cleanups

* improve docs * add TODO comments for things that don't have open issues * remove redundant namespacing of struct fields * guard against ioctl returning EINTR * remove the general std.os.ioctl function in favor of the specific ioctl_SIOCGIFINDEX function. This allows us to have a more precise error set, and more type-safe API.

5 files changed, 66 insertions(+), 50 deletions(-)

lib/std/net.zig+8-12
......@@ -22,7 +22,7 @@ pub const Address = extern union {
2222 //pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
2323
2424 /// Parse the given IP address string into an Address value.
25 /// It is recommended to use Address.resolveIp instead, to handle
25 /// It is recommended to use `resolveIp` instead, to handle
2626 /// IPv6 link-local unix addresses.
2727 pub fn parseIp(name: []const u8, port: u16) !Address {
2828 if (parseIp4(name, port)) |ip4| return ip4 else |err| switch (err) {
......@@ -78,6 +78,7 @@ pub const Address = extern union {
7878
7979 /// Parse a given IPv6 address string into an Address.
8080 /// Assumes the Scope ID of the address is fully numeric.
81 /// For non-numeric addresses, see `resolveIp6`.
8182 pub fn parseIp6(buf: []const u8, port: u16) !Address {
8283 var result = Address{
8384 .in6 = os.sockaddr_in6{
......@@ -185,8 +186,7 @@ pub const Address = extern union {
185186 }
186187
187188 pub fn resolveIp6(buf: []const u8, port: u16) !Address {
188 // FIXME: this is a very bad implementation, since it's only a copy
189 // of parseIp6 with alphanumerical scope id support
189 // TODO: Unify the implementations of resolveIp6 and parseIp6.
190190 var result = Address{
191191 .in6 = os.sockaddr_in6{
192192 .scope_id = 0,
......@@ -543,17 +543,13 @@ fn if_nametoindex(name: []const u8) !u32 {
543543 var sockfd = try os.socket(os.AF_UNIX, os.SOCK_DGRAM | os.SOCK_CLOEXEC, 0);
544544 defer os.close(sockfd);
545545
546 std.mem.copy(u8, &ifr.ifr_ifrn.name, name);
547 ifr.ifr_ifrn.name[name.len] = 0;
546 std.mem.copy(u8, &ifr.ifrn.name, name);
547 ifr.ifrn.name[name.len] = 0;
548548
549 os.ioctl(sockfd, os.system.SIOCGIFINDEX, @ptrToInt(&ifr)) catch |err| {
550 switch (err) {
551 error.NoDevice => return error.InterfaceNotFound,
552 else => return err,
553 }
554 };
549 // TODO investigate if this needs to be integrated with evented I/O.
550 try os.ioctl_SIOCGIFINDEX(sockfd, &ifr);
555551
556 return @bitCast(u32, ifr.ifr_ifru.ifru_ivalue);
552 return @bitCast(u32, ifr.ifru.ivalue);
557553}
558554
559555pub const AddressList = struct {
lib/std/net/test.zig+3-1
......@@ -48,6 +48,7 @@ test "parse and render IPv6 addresses" {
4848 testing.expectError(error.InvalidEnd, net.Address.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));
4949 testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0));
5050 testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0));
51 // TODO Make this test pass on other operating systems.
5152 if (std.builtin.os.tag == .linux) {
5253 testing.expectError(error.Incomplete, net.Address.resolveIp6("ff01::fb%", 0));
5354 testing.expectError(error.Overflow, net.Address.resolveIp6("ff01::fb%wlp3s0s0s0s0s0s0s0s0", 0));
......@@ -56,8 +57,9 @@ test "parse and render IPv6 addresses" {
5657}
5758
5859test "invalid but parseable IPv6 scope ids" {
59 // Currently, resolveIp6 with alphanumerical scope IDs only works on Linux.
6060 if (std.builtin.os.tag != .linux) {
61 // Currently, resolveIp6 with alphanumerical scope IDs only works on Linux.
62 // TODO Make this test pass on other operating systems.
6163 return error.SkipZigTest;
6264 }
6365
lib/std/os.zig+37-19
......@@ -2390,8 +2390,15 @@ pub fn isatty(handle: fd_t) bool {
23902390 return true;
23912391 }
23922392 if (builtin.os.tag == .linux) {
2393 var wsz: linux.winsize = undefined;
2394 return linux.ioctl(handle, linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
2393 while (true) {
2394 var wsz: linux.winsize = undefined;
2395 const fd = @bitCast(usize, @as(isize, handle));
2396 switch (linux.syscall3(.ioctl, fd, linux.TIOCGWINSZ, @ptrToInt(&wsz))) {
2397 0 => return true,
2398 EINTR => continue,
2399 else => return false,
2400 }
2401 }
23952402 }
23962403 unreachable;
23972404}
......@@ -4880,12 +4887,15 @@ pub fn getrusage(who: i32) rusage {
48804887pub const TermiosGetError = error{NotATerminal} || UnexpectedError;
48814888
48824889pub fn tcgetattr(handle: fd_t) TermiosGetError!termios {
4883 var term: termios = undefined;
4884 switch (errno(system.tcgetattr(handle, &term))) {
4885 0 => return term,
4886 EBADF => unreachable,
4887 ENOTTY => return error.NotATerminal,
4888 else => |err| return unexpectedErrno(err),
4890 while (true) {
4891 var term: termios = undefined;
4892 switch (errno(system.tcgetattr(handle, &term))) {
4893 0 => return term,
4894 EINTR => continue,
4895 EBADF => unreachable,
4896 ENOTTY => return error.NotATerminal,
4897 else => |err| return unexpectedErrno(err),
4898 }
48894899 }
48904900}
48914901
......@@ -4905,16 +4915,24 @@ pub fn tcsetattr(handle: fd_t, optional_action: TCSA, termios_p: termios) Termio
49054915 }
49064916}
49074917
4908pub fn ioctl(handle: fd_t, request: i32, arg: var) !void {
4909 switch (errno(system.ioctl(handle, request, arg))) {
4910 0 => {},
4911 EINVAL => unreachable,
4912 ENOTTY => unreachable,
4913 ENXIO => unreachable,
4914 EBADF => return error.BadFile,
4915 EINTR => return error.CaughtSignal,
4916 EIO => return error.FileSystem,
4917 ENODEV => return error.NoDevice,
4918 else => |err| return unexpectedErrno(err),
4918const IoCtl_SIOCGIFINDEX_Error = error{
4919 FileSystem,
4920 InterfaceNotFound,
4921} || UnexpectedError;
4922
4923pub fn ioctl_SIOCGIFINDEX(fd: fd_t, ifr: *ifreq) IoCtl_SIOCGIFINDEX_Error!void {
4924 while (true) {
4925 switch (errno(system.ioctl(fd, SIOCGIFINDEX, @ptrToInt(ifr)))) {
4926 0 => return,
4927 EINVAL => unreachable, // Bad parameters.
4928 ENOTTY => unreachable,
4929 ENXIO => unreachable,
4930 EBADF => unreachable, // Always a race condition.
4931 EFAULT => unreachable, // Bad pointer parameter.
4932 EINTR => continue,
4933 EIO => return error.FileSystem,
4934 ENODEV => return error.InterfaceNotFound,
4935 else => |err| return unexpectedErrno(err),
4936 }
49194937 }
49204938}
lib/std/os/bits/linux.zig+14-14
......@@ -1719,21 +1719,21 @@ pub const ifmap = extern struct {
17191719};
17201720
17211721pub const ifreq = extern struct {
1722 ifr_ifrn: extern union {
1722 ifrn: extern union {
17231723 name: [IFNAMESIZE]u8,
17241724 },
1725 ifr_ifru: extern union {
1726 ifru_addr: sockaddr,
1727 ifru_dstaddr: sockaddr,
1728 ifru_broadaddr: sockaddr,
1729 ifru_netmask: sockaddr,
1730 ifru_hwaddr: sockaddr,
1731 ifru_flags: i16,
1732 ifru_ivalue: i32,
1733 ifru_mtu: i32,
1734 ifru_map: ifmap,
1735 ifru_slave: [IFNAMESIZE - 1:0]u8,
1736 ifru_newname: [IFNAMESIZE - 1:0]u8,
1737 ifru_data: ?[*]u8,
1725 ifru: extern union {
1726 addr: sockaddr,
1727 dstaddr: sockaddr,
1728 broadaddr: sockaddr,
1729 netmask: sockaddr,
1730 hwaddr: sockaddr,
1731 flags: i16,
1732 ivalue: i32,
1733 mtu: i32,
1734 map: ifmap,
1735 slave: [IFNAMESIZE - 1:0]u8,
1736 newname: [IFNAMESIZE - 1:0]u8,
1737 data: ?[*]u8,
17381738 },
17391739};
lib/std/os/linux.zig+4-4
......@@ -1186,15 +1186,15 @@ pub fn getrusage(who: i32, usage: *rusage) usize {
11861186}
11871187
11881188pub fn tcgetattr(fd: fd_t, termios_p: *termios) usize {
1189 return ioctl(fd, TCGETS, @ptrToInt(termios_p));
1189 return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), TCGETS, @ptrToInt(termios_p));
11901190}
11911191
11921192pub fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) usize {
1193 return ioctl(fd, TCSETS + @enumToInt(optional_action), @ptrToInt(termios_p));
1193 return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), TCSETS + @enumToInt(optional_action), @ptrToInt(termios_p));
11941194}
11951195
1196pub fn ioctl(fd: fd_t, request: i32, arg: var) usize {
1197 return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, request)), arg);
1196pub fn ioctl(fd: fd_t, request: u32, arg: usize) usize {
1197 return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), request, arg);
11981198}
11991199
12001200test "" {