Commit c8468bed42

Luna <git@l4.pm>
2020-04-20 21:34:37
Add std.os.ioctl
1 parent c7b790d
Changed files (3)
lib/std/os/linux.zig
@@ -1193,6 +1193,10 @@ pub fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) usi
     return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), TCSETS + @enumToInt(optional_action), @ptrToInt(termios_p));
 }
 
+pub fn ioctl(fd: fd_t, request: u32, arg: var) usize {
+    return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), request, arg);
+}
+
 test "" {
     if (builtin.os.tag == .linux) {
         _ = @import("linux/test.zig");
lib/std/net.zig
@@ -545,24 +545,12 @@ fn if_nametoindex(name: []const u8) !u32 {
     std.mem.copy(u8, &ifr.ifr_ifrn.name, name);
     ifr.ifr_ifrn.name[name.len] = 0;
 
-    const rc = os.system.syscall3(
-        os.linux.SYS_ioctl,
-        @bitCast(usize, @as(isize, sockfd)),
-        os.linux.SIOCGIFINDEX,
-        @ptrToInt(&ifr),
-    );
-
-    switch (os.errno(rc)) {
-        os.EBADF => return error.BadFile,
-        os.EINTR => return error.CaughtSignal,
-        os.EIO => return error.FileSystem,
-        os.EINVAL => unreachable,
-        os.ENOTTY => unreachable,
-        os.ENXIO => unreachable,
-        // ioctl() sends ENODEV for an unknown scope id.
-        os.ENODEV => return error.InterfaceNotFound,
-        else => {},
-    }
+    std.os.ioctl(sockfd, os.linux.SIOCGIFINDEX, @ptrToInt(&ifr)) catch |err| {
+        switch (err) {
+            error.NoDevice => return error.InterfaceNotFound,
+            else => return err,
+        }
+    };
 
     return @bitCast(u32, ifr.ifr_ifru.ifru_ivalue);
 }
lib/std/os.zig
@@ -405,7 +405,6 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
             else => |err| return unexpectedErrno(err),
         }
     }
-
     const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);
     while (true) {
         // TODO handle the case when iov_len is too large and get rid of this @intCast
@@ -2451,9 +2450,8 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
     if (builtin.os.tag == .windows) {
         // NOTE: windows translates the SOCK_NONBLOCK/SOCK_CLOEXEC flags into windows-analagous operations
         const filtered_sock_type = socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC);
-        const flags : u32 = if ((socket_type & SOCK_CLOEXEC) != 0) windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT else 0;
-        const rc = windows.ws2_32.WSASocketW(@intCast(c_int, domain), @intCast(c_int, filtered_sock_type),
-            @intCast(c_int, protocol), null, 0, flags);
+        const flags: u32 = if ((socket_type & SOCK_CLOEXEC) != 0) windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT else 0;
+        const rc = windows.ws2_32.WSASocketW(@intCast(c_int, domain), @intCast(c_int, filtered_sock_type), @intCast(c_int, protocol), null, 0, flags);
         if (rc == windows.ws2_32.INVALID_SOCKET) switch (windows.ws2_32.WSAGetLastError()) {
             .WSAEMFILE => return error.ProcessFdQuotaExceeded,
             .WSAENOBUFS => return error.SystemResources,
@@ -2463,7 +2461,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
         };
         errdefer windows.closesocket(rc) catch unreachable;
         if ((socket_type & SOCK_NONBLOCK) != 0) {
-            var mode : c_ulong = 1; // nonblocking
+            var mode: c_ulong = 1; // nonblocking
             if (windows.ws2_32.SOCKET_ERROR == windows.ws2_32.ioctlsocket(rc, windows.ws2_32.FIONBIO, &mode)) {
                 switch (windows.ws2_32.WSAGetLastError()) {
                     // have not identified any error codes that should be handled yet
@@ -2858,7 +2856,7 @@ pub fn connect(sockfd: socket_t, sock_addr: *const sockaddr, len: socklen_t) Con
             .WSAECONNREFUSED => return error.ConnectionRefused,
             .WSAETIMEDOUT => return error.ConnectionTimedOut,
             .WSAEHOSTUNREACH // TODO: should we return NetworkUnreachable in this case as well?
-            ,.WSAENETUNREACH => return error.NetworkUnreachable,
+                , .WSAENETUNREACH => return error.NetworkUnreachable,
             .WSAEFAULT => unreachable,
             .WSAEINVAL => unreachable,
             .WSAEISCONN => unreachable,
@@ -4906,3 +4904,17 @@ pub fn tcsetattr(handle: fd_t, optional_action: TCSA, termios_p: termios) Termio
         }
     }
 }
+
+pub fn ioctl(handle: fd_t, request: u32, arg: var) !void {
+    switch (errno(system.ioctl(handle, request, arg))) {
+        0 => {},
+        EINVAL => unreachable,
+        ENOTTY => unreachable,
+        ENXIO => unreachable,
+        EBADF => return error.BadFile,
+        EINTR => return error.CaughtSignal,
+        EIO => return error.FileSystem,
+        ENODEV => return error.NoDevice,
+        else => |err| return unexpectedErrno(err),
+    }
+}