zig

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

commit 2f372b3dc00c60a625e1cc3518fa1bda3429de59 (tree)
parent 520397b48fac7fd0c107257c57f2cca4f0a40a98
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Wed,  7 Jan 2026 13:54:02 -0800

goodbye posix.write

see #6600

Diffstat:
Mlib/std/Thread.zig | 2+-
Mlib/std/posix.zig | 97-------------------------------------------------------------------------------
Mlib/std/posix/test.zig | 13+++++++++----
3 files changed, 10 insertions(+), 102 deletions(-)

diff --git a/lib/std/Thread.zig b/lib/std/Thread.zig @@ -175,7 +175,7 @@ pub const SetNameError = error{ Unsupported, Unexpected, InvalidWtf8, -} || posix.PrctlError || posix.WriteError || Io.File.OpenError || std.fmt.BufPrintError; +} || posix.PrctlError || Io.File.Writer.Error || Io.File.OpenError || std.fmt.BufPrintError; pub fn setName(self: Thread, io: Io, name: []const u8) SetNameError!void { if (name.len > max_name_len) return error.NameTooLong; diff --git a/lib/std/posix.zig b/lib/std/posix.zig @@ -446,103 +446,6 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { } } -pub const WriteError = error{ - DiskQuota, - FileTooBig, - InputOutput, - NoSpaceLeft, - DeviceBusy, - InvalidArgument, - - /// File descriptor does not hold the required rights to write to it. - AccessDenied, - PermissionDenied, - BrokenPipe, - SystemResources, - Canceled, - NotOpenForWriting, - - /// The process cannot access the file because another process has locked - /// a portion of the file. Windows-only. - LockViolation, - - /// This error occurs when no global event loop is configured, - /// and reading from the file descriptor would block. - WouldBlock, - - /// Connection reset by peer. - ConnectionResetByPeer, - - /// This error occurs in Linux if the process being written to - /// no longer exists. - ProcessNotFound, - /// This error occurs when a device gets disconnected before or mid-flush - /// while it's being written to - errno(6): No such device or address. - NoDevice, - - /// The socket type requires that message be sent atomically, and the size of the message - /// to be sent made this impossible. The message is not transmitted. - MessageOversize, -} || UnexpectedError; - -/// Write to a file descriptor. -/// Retries when interrupted by a signal. -/// Returns the number of bytes written. If nonzero bytes were supplied, this will be nonzero. -/// -/// Note that a successful write() may transfer fewer than count bytes. Such partial writes can -/// occur for various reasons; for example, because there was insufficient space on the disk -/// device to write all of the requested bytes, or because a blocked write() to a socket, pipe, or -/// similar was interrupted by a signal handler after it had transferred some, but before it had -/// transferred all of the requested bytes. In the event of a partial write, the caller can make -/// another write() call to transfer the remaining bytes. The subsequent call will either -/// transfer further bytes or may result in an error (e.g., if the disk is now full). -/// -/// For POSIX systems, if `fd` is opened in non blocking mode, the function will -/// return error.WouldBlock when EAGAIN is received. -/// On Windows, if the application has a global event loop enabled, I/O Completion Ports are -/// used to perform the I/O. `error.WouldBlock` is not possible on Windows. -/// -/// Linux has a limit on how many bytes may be transferred in one `write` call, which is `0x7ffff000` -/// on both 64-bit and 32-bit systems. This is due to using a signed C int as the return value, as -/// well as stuffing the errno codes into the last `4096` values. This is noted on the `write` man page. -/// The limit on Darwin is `0x7fffffff`, trying to read more than that returns EINVAL. -/// The corresponding POSIX limit is `maxInt(isize)`. -pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize { - if (bytes.len == 0) return 0; - if (native_os == .windows) @compileError("unsupported OS"); - if (native_os == .wasi) @compileError("unsupported OS"); - - const max_count = switch (native_os) { - .linux => 0x7ffff000, - .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => maxInt(i32), - else => maxInt(isize), - }; - while (true) { - const rc = system.write(fd, bytes.ptr, @min(bytes.len, max_count)); - switch (errno(rc)) { - .SUCCESS => return @intCast(rc), - .INTR => continue, - .INVAL => return error.InvalidArgument, - .FAULT => unreachable, - .AGAIN => return error.WouldBlock, - .BADF => return error.NotOpenForWriting, // can be a race condition. - .DESTADDRREQ => unreachable, // `connect` was never called. - .DQUOT => return error.DiskQuota, - .FBIG => return error.FileTooBig, - .IO => return error.InputOutput, - .NOSPC => return error.NoSpaceLeft, - .ACCES => return error.AccessDenied, - .PERM => return error.PermissionDenied, - .PIPE => return error.BrokenPipe, - .CONNRESET => return error.ConnectionResetByPeer, - .BUSY => return error.DeviceBusy, - .NXIO => return error.NoDevice, - .MSGSIZE => return error.MessageOversize, - else => |err| return unexpectedErrno(err), - } - } -} - pub const OpenError = std.Io.File.OpenError || error{WouldBlock}; /// Open and possibly create a file. Keeps trying if it gets interrupted. diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig @@ -121,13 +121,18 @@ test "pipe" { if (native_os == .windows or native_os == .wasi) return error.SkipZigTest; + const io = testing.io; + const fds = try std.Io.Threaded.pipe2(.{}); - try expect((try posix.write(fds[1], "hello")) == 5); + const out: Io.File = .{ .handle = fds[0] }; + const in: Io.File = .{ .handle = fds[1] }; + try in.writeStreamingAll(io, "hello"); var buf: [16]u8 = undefined; - try expect((try posix.read(fds[0], buf[0..])) == 5); + try expect((try out.readStreaming(io, &.{&buf})) == 5); + try expectEqualSlices(u8, buf[0..5], "hello"); - posix.close(fds[1]); - posix.close(fds[0]); + out.close(io); + in.close(io); } test "memfd_create" {