How to use non-blocked sockets without new Io (0.16.+)

Same days ago I already asked the same question

I got an answer:

std.posix layer of abstractions is gone, but the lower layer (obviously) isn’t going anywhere…

I tried to understand current status using as reference Threaded Io

pub fn io(t: *Threaded) Io {
    return .{
        .userdata = t,
        .vtable = &.{
            --------------
            .netConnectIp = switch (native_os) {
                .windows => netConnectIpWindows,
                else => netConnectIpPosix,
            },

```

Chain of functions (for linux)

netConectIpPosix calls

  • openSocketPosix - socket creation
  • posixConnect - connect to server

Both functions don’t use Io staff and may be great candidates for Io-independent working with sockets.

Two small problems:

  • they are part of Io/Threaded.zig
  • not public

Slightly different pattern have net Read/Write/.. functions

fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
    if (!have_networking) return error.NetworkDown;
    const t: *Threaded = @ptrCast(@alignCast(userdata));
    _ = t;

    code for read (t is not used ofc) 
    .....................................................

In order to work with non-blocked sockets without IO, low-level functions

should be public and placed somewhere , and I am not sure regarding Io/Threaded.zig

Is it the way to use non-blocked sockets without new Io (0.16.+)?