zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit e7e168727e3c024869de9d114a7dd49d2a80de4d (tree)
parent b9819fce69e0f208e9e20071071a40863fbdb8a9
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Thu, 29 Jan 2026 20:11:18 -0800

std.posix: goodbye connect, eventfd

Diffstat:
Mlib/std/os/linux/IoUring/test.zig | 17++++++++++++-----
Mlib/std/posix.zig | 78+++++++-----------------------------------------------------------------------
2 files changed, 19 insertions(+), 76 deletions(-)

diff --git a/lib/std/os/linux/IoUring/test.zig b/lib/std/os/linux/IoUring/test.zig @@ -1755,7 +1755,7 @@ test "accept multishot" { // connect client const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); errdefer posix.close(client); - try posix.connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); + try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); // test accept completion var cqe = try ring.copy_cqe(); @@ -1865,7 +1865,7 @@ test "accept_direct" { // connect const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); - try posix.connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); + try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); defer posix.close(client); // accept completion @@ -1899,7 +1899,7 @@ test "accept_direct" { try testing.expectEqual(@as(u32, 1), try ring.submit()); // connect const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); - try posix.connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); + try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); defer posix.close(client); // completion with error const cqe_accept = try ring.copy_cqe(); @@ -1949,7 +1949,7 @@ test "accept_multishot_direct" { for (registered_fds) |_| { // connect const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); - try posix.connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); + try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); defer posix.close(client); // accept completion @@ -1964,7 +1964,7 @@ test "accept_multishot_direct" { { // connect const client = try socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); - try posix.connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); + try connect(client, addrAny(&address), @sizeOf(linux.sockaddr.in)); defer posix.close(client); // completion with error const cqe_accept = try ring.copy_cqe(); @@ -2734,3 +2734,10 @@ fn send(sockfd: posix.socket_t, buf: []const u8, flags: u32) !usize { else => return error.SendFailed, } } + +fn connect(sock: posix.socket_t, sock_addr: *const posix.sockaddr, len: posix.socklen_t) !void { + switch (posix.errno(posix.system.connect(sock, sock_addr, len))) { + .SUCCESS => return, + else => return error.ConnectFailed, + } +} diff --git a/lib/std/posix.zig b/lib/std/posix.zig @@ -1,27 +1,18 @@ //! POSIX API layer. //! //! This is more cross platform than using OS-specific APIs, however, it is -//! lower-level and less portable than other namespaces such as `std.fs` and +//! lower-level and less portable than other namespaces such as `std.Io` and //! `std.process`. //! //! These APIs are generally lowered to libc function calls if and only if libc //! is linked. Most operating systems other than Windows, Linux, and WASI //! require always linking libc because they use it as the stable syscall ABI. -//! -//! Operating systems that are not POSIX-compliant are sometimes supported by -//! this API layer; sometimes not. Generally, an implementation will be -//! provided only if such implementation is straightforward on that operating -//! system. Otherwise, programmers are expected to use OS-specific logic to -//! deal with the exception. - const builtin = @import("builtin"); const native_os = builtin.os.tag; const std = @import("std.zig"); const Io = std.Io; const mem = std.mem; -const fs = std.fs; -const max_path_bytes = std.fs.max_path_bytes; const maxInt = std.math.maxInt; const cast = std.math.cast; const assert = std.debug.assert; @@ -122,15 +113,14 @@ pub const STDIN_FILENO = system.STDIN_FILENO; pub const STDOUT_FILENO = system.STDOUT_FILENO; pub const SYS = system.SYS; pub const Sigaction = system.Sigaction; +/// Windows has no concept of `stat`. +/// +/// On Linux, the `stat` bits/wrappers are removed due to having to maintain +/// the different varying stat structs per target and libc, leading to runtime +/// errors. Users targeting Linux should add a comptime check and use statx, +/// similar to how `Io.File.stat` does. pub const Stat = switch (native_os) { - // Has no concept of `stat`. .windows => void, - // The `stat` bits/wrappers are removed due to having to maintain the - // different varying `struct stat`s per target and libc, leading to runtime - // errors. - // - // Users targeting linux should add a comptime check and use `statx`, - // similar to how `std.fs.File.stat` does. .linux => void, else => system.Stat, }; @@ -645,26 +635,6 @@ fn setSockFlags(sock: socket_t, flags: u32) !void { } } -pub const EventFdError = error{ - SystemResources, - ProcessFdQuotaExceeded, - SystemFdQuotaExceeded, -} || UnexpectedError; - -pub fn eventfd(initval: u32, flags: u32) EventFdError!i32 { - const rc = system.eventfd(initval, flags); - switch (errno(rc)) { - .SUCCESS => return @intCast(rc), - else => |err| return unexpectedErrno(err), - - .INVAL => unreachable, // invalid parameters - .MFILE => return error.ProcessFdQuotaExceeded, - .NFILE => return error.SystemFdQuotaExceeded, - .NODEV => return error.SystemResources, - .NOMEM => return error.SystemResources, - } -} - pub const GetSockNameError = error{ /// Insufficient resources were available in the system to perform the operation. SystemResources, @@ -707,40 +677,6 @@ pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock } } -pub const ConnectError = std.Io.net.IpAddress.ConnectError || std.Io.net.UnixAddress.ConnectError; - -pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) ConnectError!void { - if (native_os == .windows) { - @compileError("use std.Io instead"); - } - - while (true) { - switch (errno(system.connect(sock, sock_addr, len))) { - .SUCCESS => return, - .ACCES => return error.AccessDenied, - .PERM => return error.PermissionDenied, - .ADDRNOTAVAIL => return error.AddressUnavailable, - .AFNOSUPPORT => return error.AddressFamilyUnsupported, - .AGAIN, .INPROGRESS => return error.WouldBlock, - .ALREADY => return error.ConnectionPending, - .BADF => unreachable, // sockfd is not a valid open file descriptor. - .CONNREFUSED => return error.ConnectionRefused, - .CONNRESET => return error.ConnectionResetByPeer, - .FAULT => unreachable, // The socket structure address is outside the user's address space. - .INTR => continue, - .ISCONN => @panic("AlreadyConnected"), // The socket is already connected. - .HOSTUNREACH => return error.NetworkUnreachable, - .NETUNREACH => return error.NetworkUnreachable, - .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket. - .PROTOTYPE => unreachable, // The socket type does not support the requested communications protocol. - .TIMEDOUT => return error.Timeout, - .NOENT => return error.FileNotFound, // Returned when socket is AF.UNIX and the given path does not exist. - .CONNABORTED => unreachable, // Tried to reuse socket that previously received error.ConnectionRefused. - else => |err| return unexpectedErrno(err), - } - } -} - pub const FStatError = std.Io.File.StatError; /// Return information about a file descriptor.