authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-14 23:37:36-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-15 14:18:20-08:00
log2b01764d86d8c1b808a1ffb5913442e8f055762f
treecc382115461ea949b40f4cbdb8bb6912617461f6
parentcb37a5c1fbfd991c6c299b27f35bbbe0b2b8d8de

std: fix handling of EBADF error code

In the context of read/write it's ambiguous, means file was opened without read/write respectively.

6 files changed, 17 insertions(+), 18 deletions(-)

lib/std/Io/File.zig+4
......@@ -554,6 +554,8 @@ pub const ReadPositionalError = error{
554554 LockViolation,
555555 /// This file cannot be read positionally.
556556 Unseekable,
557 /// File was not opened with read capability.
558 NotOpenForReading,
557559} || Io.Cancelable || Io.UnexpectedError;
558560
559561/// Returns 0 on stream end or if `buffer` has no space available for data.
......@@ -588,6 +590,8 @@ pub const WritePositionalError = error{
588590 FileBusy,
589591 /// This file cannot be written positionally.
590592 Unseekable,
593 /// File was not opened with write capability.
594 NotOpenForWriting,
591595} || Io.Cancelable || Io.UnexpectedError;
592596
593597/// See also:
lib/std/Io/File/Reader.zig+2-1
......@@ -33,7 +33,8 @@ pub const Error = error{
3333 IsDir,
3434 BrokenPipe,
3535 ConnectionResetByPeer,
36 Timeout,
36 /// File was not opened with read capability.
37 NotOpenForReading,
3738 SocketUnconnected,
3839 /// Non-blocking has been enabled, and reading from the file descriptor
3940 /// would block.
lib/std/Io/Threaded.zig+9-11
......@@ -7954,7 +7954,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
79547954 syscall.finish();
79557955 return nread;
79567956 },
7957 .INTR => {
7957 .INTR, .TIMEDOUT => {
79587958 try syscall.checkCancel();
79597959 continue;
79607960 },
......@@ -7970,7 +7970,6 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
79707970 .NOMEM => return error.SystemResources,
79717971 .NOTCONN => return error.SocketUnconnected,
79727972 .CONNRESET => return error.ConnectionResetByPeer,
7973 .TIMEDOUT => return error.Timeout,
79747973 .NOTCAPABLE => return error.AccessDenied,
79757974 else => |err| return posix.unexpectedErrno(err),
79767975 }
......@@ -7987,7 +7986,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
79877986 syscall.finish();
79887987 return @intCast(rc);
79897988 },
7990 .INTR => {
7989 .INTR, .TIMEDOUT => {
79917990 try syscall.checkCancel();
79927991 continue;
79937992 },
......@@ -7997,9 +7996,9 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
79977996 .INVAL => |err| return errnoBug(err),
79987997 .FAULT => |err| return errnoBug(err),
79997998 .AGAIN => return error.WouldBlock,
8000 .BADF => |err| {
7999 .BADF => {
80018000 if (native_os == .wasi) return error.IsDir; // File operation on directory.
8002 return errnoBug(err); // File descriptor used after closed.
8001 return error.NotOpenForReading;
80038002 },
80048003 .IO => return error.InputOutput,
80058004 .ISDIR => return error.IsDir,
......@@ -8007,7 +8006,6 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
80078006 .NOMEM => return error.SystemResources,
80088007 .NOTCONN => return error.SocketUnconnected,
80098008 .CONNRESET => return error.ConnectionResetByPeer,
8010 .TIMEDOUT => return error.Timeout,
80118009 else => |err| return posix.unexpectedErrno(err),
80128010 }
80138011 },
......@@ -8136,10 +8134,10 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8
81368134 .CONNRESET => |err| return syscall.errnoBug(err), // not a socket
81378135 .INVAL => |err| return syscall.errnoBug(err),
81388136 .FAULT => |err| return syscall.errnoBug(err),
8139 .BADF => |err| {
8137 .BADF => {
81408138 syscall.finish();
81418139 if (native_os == .wasi) return error.IsDir; // File operation on directory.
8142 return errnoBug(err); // File descriptor used after closed.
8140 return error.NotOpenForReading;
81438141 },
81448142 else => |err| return syscall.unexpectedErrno(err),
81458143 }
......@@ -8793,7 +8791,7 @@ fn fileWritePositional(
87938791 .INVAL => |err| return errnoBug(err),
87948792 .FAULT => |err| return errnoBug(err),
87958793 .AGAIN => |err| return errnoBug(err),
8796 .BADF => |err| return errnoBug(err), // use after free
8794 .BADF => return error.NotOpenForWriting,
87978795 .DESTADDRREQ => |err| return errnoBug(err), // `connect` was never called.
87988796 .DQUOT => return error.DiskQuota,
87998797 .FBIG => return error.FileTooBig,
......@@ -8828,7 +8826,7 @@ fn fileWritePositional(
88288826 .FAULT => |err| return syscall.errnoBug(err),
88298827 .DESTADDRREQ => |err| return syscall.errnoBug(err), // `connect` was never called.
88308828 .CONNRESET => |err| return syscall.errnoBug(err), // Not a socket handle.
8831 .BADF => |err| return syscall.errnoBug(err), // use after free
8829 .BADF => return syscall.fail(error.NotOpenForWriting),
88328830 .AGAIN => return syscall.fail(error.WouldBlock),
88338831 .DQUOT => return syscall.fail(error.DiskQuota),
88348832 .FBIG => return syscall.fail(error.FileTooBig),
......@@ -16636,7 +16634,7 @@ fn mmSyncWrite(file: File, memory: []u8, offset: u64) File.WritePositionalError!
1663616634 .FAULT => |err| return syscall.errnoBug(err),
1663716635 .DESTADDRREQ => |err| return syscall.errnoBug(err), // not a socket
1663816636 .CONNRESET => |err| return syscall.errnoBug(err), // not a socket
16639 .BADF => |err| return syscall.errnoBug(err), // use after free
16637 .BADF => return syscall.fail(error.NotOpenForWriting),
1664016638 .AGAIN => return syscall.fail(error.WouldBlock),
1664116639 .DQUOT => return syscall.fail(error.DiskQuota),
1664216640 .FBIG => return syscall.fail(error.FileTooBig),
lib/std/posix.zig+1-1
......@@ -441,7 +441,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
441441 .NOMEM => return error.SystemResources,
442442 .NOTCONN => return error.SocketUnconnected,
443443 .CONNRESET => return error.ConnectionResetByPeer,
444 .TIMEDOUT => return error.Timeout,
444 .TIMEDOUT => return error.Unexpected,
445445 else => |err| return unexpectedErrno(err),
446446 }
447447 }
lib/std/zig/system.zig+1-1
......@@ -420,7 +420,7 @@ pub fn resolveTargetQuery(io: Io, query: Target.Query) DetectError!Target {
420420 error.WouldBlock => return error.Unexpected,
421421 error.BrokenPipe => return error.Unexpected,
422422 error.ConnectionResetByPeer => return error.Unexpected,
423 error.Timeout => return error.Unexpected,
423 error.NotOpenForReading => return error.Unexpected,
424424 error.SocketUnconnected => return error.Unexpected,
425425
426426 error.AccessDenied,
src/link/Dwarf.zig-4
......@@ -50,13 +50,9 @@ pub const UpdateError = error{
5050 UnexpectedEndOfFile,
5151 NonResizable,
5252 /// TODO why is this in the error set?
53 Timeout,
54 /// TODO why is this in the error set?
5553 ConnectionResetByPeer,
5654 /// TODO why is this in the error set?
5755 SocketUnconnected,
58 /// TODO why is this in the error set?
59 NotOpenForWriting,
6056} ||
6157 codegen.GenerateSymbolError ||
6258 Io.File.OpenError ||