Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

netInterfaceNameResolve

Threaded.netInterfaceNameResolve
fn netInterfaceNameResolve(
    userdata: ?*anyopaque,
    name: *const net.Interface.Name,
) net.Interface.Name.ResolveError!net.Interface

File

lib/std/Io/Threaded.zig:13473

Code

fn netInterfaceNameResolve(
    userdata: ?*anyopaque,
    name: *const net.Interface.Name,
) net.Interface.Name.ResolveError!net.Interface {
    if (!have_networking) return error.InterfaceNotFound;
    const t: *Threaded = @ptrCast(@alignCast(userdata));

    if (native_os == .linux) {
        const sock_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) {
            error.ProcessFdQuotaExceeded => return error.SystemResources,
            error.SystemFdQuotaExceeded => return error.SystemResources,
            error.AddressFamilyUnsupported => return error.Unexpected,
            error.ProtocolUnsupportedBySystem => return error.Unexpected,
            error.ProtocolUnsupportedByAddressFamily => return error.Unexpected,
            error.SocketModeUnsupported => return error.Unexpected,
            error.OptionUnsupported => return error.Unexpected,
            else => |e| return e,
        };
        defer closeFd(sock_fd);

        var ifr: posix.ifreq = .{
            .ifrn = .{ .name = @bitCast(name.bytes) },
            .ifru = undefined,
        };

        const syscall: Syscall = try .start();
        while (true) switch (posix.errno(posix.system.ioctl(sock_fd, posix.SIOCGIFINDEX, @intFromPtr(&ifr)))) {
            .SUCCESS => {
                syscall.finish();
                return .{ .index = @bitCast(ifr.ifru.ivalue) };
            },
            .INTR => {
                try syscall.checkCancel();
                continue;
            },
            .NODEV => return syscall.fail(error.InterfaceNotFound),
            else => |err| return syscall.unexpectedErrno(err),
        };
    }

    if (is_windows) {
        var ConvertInterfaceNameToLuidW = t.dl.ConvertInterfaceNameToLuidW.load(.acquire);
        var ConvertInterfaceLuidToIndex = t.dl.ConvertInterfaceLuidToIndex.load(.acquire);
        if (ConvertInterfaceNameToLuidW == null or ConvertInterfaceLuidToIndex == null) {
            const iphlpapi_dll = t.dl.iphlpapi_dll.load(.acquire) orelse iphlpapi_dll: {
                try Thread.checkCancel();
                var iphlpapi_dll: *anyopaque = undefined;
                switch (windows.ntdll.LdrLoadDll(null, null, &.init(
                    &.{ 'I', 'P', 'H', 'L', 'P', 'A', 'P', 'I', '.', 'D', 'L', 'L' },
                ), &iphlpapi_dll)) {
                    .SUCCESS => {},
                    .DLL_NOT_FOUND => return error.Unexpected,
                    else => |status| return windows.unexpectedStatus(status),
                }
                const handle = t.dl.iphlpapi_dll.cmpxchgStrong(null, iphlpapi_dll, .release, .monotonic) orelse
                    break :iphlpapi_dll iphlpapi_dll;
                switch (windows.ntdll.LdrUnloadDll(iphlpapi_dll)) {
                    .SUCCESS => break :iphlpapi_dll handle.?,
                    else => |status| return windows.unexpectedStatus(status),
                }
            };
            switch (windows.ntdll.LdrGetProcedureAddress(iphlpapi_dll, &.init(
                &.{
                    'C', 'o', 'n', 'v', 'e', 'r', 't', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e',
                    'N', 'a', 'm', 'e', 'T', 'o', 'L', 'u', 'i', 'd', 'W',
                },
            ), 0, @ptrCast(&ConvertInterfaceNameToLuidW))) {
                .SUCCESS => t.dl.ConvertInterfaceNameToLuidW.store(ConvertInterfaceNameToLuidW, .release),
                else => |status| return windows.unexpectedStatus(status),
            }
            switch (windows.ntdll.LdrGetProcedureAddress(iphlpapi_dll, &.init(
                &.{
                    'C', 'o', 'n', 'v', 'e', 'r', 't', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e',
                    'L', 'u', 'i', 'd', 'T', 'o', 'I', 'n', 'd', 'e', 'x',
                },
            ), 0, @ptrCast(&ConvertInterfaceLuidToIndex))) {
                .SUCCESS => t.dl.ConvertInterfaceLuidToIndex.store(ConvertInterfaceLuidToIndex, .release),
                else => |status| return windows.unexpectedStatus(status),
            }
        }
        try Thread.checkCancel();
        var name_w: [net.Interface.Name.max_len:0]windows.WCHAR = undefined;
        name_w[
            std.unicode.wtf8ToWtf16Le(&name_w, name.toSlice()) catch |err| switch (err) {
                error.InvalidWtf8 => return error.InterfaceNotFound,
            }
        ] = 0;
        var luid: windows.NET.LUID = undefined;
        switch (ConvertInterfaceNameToLuidW.?(&name_w, &luid)) {
            .SUCCESS => {},
            .INVALID_NAME => return error.InterfaceNotFound,
            .INVALID_PARAMETER => unreachable,
            else => |err| return windows.unexpectedError(err),
        }
        var index: windows.NET.IFINDEX = undefined;
        switch (ConvertInterfaceLuidToIndex.?(&luid, &index)) {
            .SUCCESS => {},
            .INVALID_PARAMETER => unreachable,
            else => |err| return windows.unexpectedError(err),
        }
        return .{ .index = @backingInt(index) };
    }

    if (builtin.link_libc) {
        try Thread.checkCancel();
        const index = std.c.if_nametoindex(&name.bytes);
        if (index == 0) return error.InterfaceNotFound;
        return .{ .index = @bitCast(index) };
    }

    @panic("unimplemented");
}