authorgravatar for pat.github@tullmann.orgPat Tullmann <pat.github@tullmann.org> 2025-02-18 17:18:03-08:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-03-24 16:20:45+01:00
log14c046fc0728070c575c0e849b7be649cbb2b9a0
tree0cd70f8ed2bd9d549609c289c3e62b93dff25dd2
parent02373eb2a59f4a16a06460c244958e236b1c5291

lib/std: PermissionDenied/AccessDenied cleanup and fallout

This PR consistently maps .ACCES into AccessDenied and .PERM into PermissionDenied. AccessDenied is returned if the file mode bit (user/group/other rwx bits) disallow access (errno was `EACCES`). PermissionDenied is returned if something else denies access (errno was `EPERM`) (immutable bit, SELinux, capabilities, etc). This somewhat subtle distinction is a POSIX thing. Most of the change is updating std.posix Error Sets to contain both errors, and then propagating the pair up through caller Error Sets. Fixes #16782

7 files changed, 93 insertions(+), 61 deletions(-)

lib/std/fs/Dir.zig+18-7
......@@ -247,7 +247,7 @@ pub const Iterator = switch (native_os) {
247247 .NOTDIR => unreachable,
248248 .INVAL => unreachable,
249249 .ACCES => return error.AccessDenied,
250 .PERM => return error.AccessDenied,
250 .PERM => return error.PermissionDenied,
251251 else => |err| return posix.unexpectedErrno(err),
252252 }
253253 self.first_iter = false;
......@@ -267,7 +267,7 @@ pub const Iterator = switch (native_os) {
267267 .INVAL => unreachable,
268268 .OVERFLOW => unreachable,
269269 .ACCES => return error.AccessDenied,
270 .PERM => return error.AccessDenied,
270 .PERM => return error.PermissionDenied,
271271 else => |err| return posix.unexpectedErrno(err),
272272 }
273273 }
......@@ -294,7 +294,7 @@ pub const Iterator = switch (native_os) {
294294 .BADF => unreachable, // Dir is invalid
295295 .NOMEM => return error.SystemResources,
296296 .ACCES => return error.AccessDenied,
297 .PERM => return error.AccessDenied,
297 .PERM => return error.PermissionDenied,
298298 .FAULT => unreachable,
299299 .NAMETOOLONG => unreachable,
300300 .LOOP => unreachable,
......@@ -768,6 +768,7 @@ pub const OpenError = error{
768768 FileNotFound,
769769 NotDir,
770770 AccessDenied,
771 PermissionDenied,
771772 SymLinkLoop,
772773 ProcessFdQuotaExceeded,
773774 NameTooLong,
......@@ -1503,7 +1504,7 @@ pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenOptions) OpenErr
15031504 .NOENT => return error.FileNotFound,
15041505 .NOMEM => return error.SystemResources,
15051506 .NOTDIR => return error.NotDir,
1506 .PERM => return error.AccessDenied,
1507 .PERM => return error.PermissionDenied,
15071508 .BUSY => return error.DeviceBusy,
15081509 else => |err| return posix.unexpectedErrno(err),
15091510 }
......@@ -1652,9 +1653,9 @@ pub fn deleteFile(self: Dir, sub_path: []const u8) DeleteFileError!void {
16521653pub fn deleteFileZ(self: Dir, sub_path_c: [*:0]const u8) DeleteFileError!void {
16531654 posix.unlinkatZ(self.fd, sub_path_c, 0) catch |err| switch (err) {
16541655 error.DirNotEmpty => unreachable, // not passing AT.REMOVEDIR
1655 error.AccessDenied => |e| switch (native_os) {
1656 // non-Linux POSIX systems return EPERM when trying to delete a directory, so
1657 // we need to handle that case specifically and translate the error
1656 error.AccessDenied, error.PermissionDenied => |e| switch (native_os) {
1657 // non-Linux POSIX systems return permission errors when trying to delete a
1658 // directory, so we need to handle that case specifically and translate the error
16581659 .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => {
16591660 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)
16601661 const fstat = posix.fstatatZ(self.fd, sub_path_c, posix.AT.SYMLINK_NOFOLLOW) catch return e;
......@@ -1679,6 +1680,7 @@ pub const DeleteDirError = error{
16791680 DirNotEmpty,
16801681 FileNotFound,
16811682 AccessDenied,
1683 PermissionDenied,
16821684 FileBusy,
16831685 FileSystem,
16841686 SymLinkLoop,
......@@ -1991,6 +1993,7 @@ pub fn readFileAllocOptions(
19911993
19921994pub const DeleteTreeError = error{
19931995 AccessDenied,
1996 PermissionDenied,
19941997 FileTooBig,
19951998 SymLinkLoop,
19961999 ProcessFdQuotaExceeded,
......@@ -2073,6 +2076,7 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void {
20732076 },
20742077
20752078 error.AccessDenied,
2079 error.PermissionDenied,
20762080 error.SymLinkLoop,
20772081 error.ProcessFdQuotaExceeded,
20782082 error.NameTooLong,
......@@ -2112,6 +2116,7 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void {
21122116 },
21132117
21142118 error.AccessDenied,
2119 error.PermissionDenied,
21152120 error.InvalidUtf8,
21162121 error.InvalidWtf8,
21172122 error.SymLinkLoop,
......@@ -2168,6 +2173,7 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void {
21682173 },
21692174
21702175 error.AccessDenied,
2176 error.PermissionDenied,
21712177 error.SymLinkLoop,
21722178 error.ProcessFdQuotaExceeded,
21732179 error.NameTooLong,
......@@ -2197,6 +2203,7 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void {
21972203 },
21982204
21992205 error.AccessDenied,
2206 error.PermissionDenied,
22002207 error.InvalidUtf8,
22012208 error.InvalidWtf8,
22022209 error.SymLinkLoop,
......@@ -2273,6 +2280,7 @@ fn deleteTreeMinStackSizeWithKindHint(self: Dir, sub_path: []const u8, kind_hint
22732280 },
22742281
22752282 error.AccessDenied,
2283 error.PermissionDenied,
22762284 error.SymLinkLoop,
22772285 error.ProcessFdQuotaExceeded,
22782286 error.NameTooLong,
......@@ -2309,6 +2317,7 @@ fn deleteTreeMinStackSizeWithKindHint(self: Dir, sub_path: []const u8, kind_hint
23092317 },
23102318
23112319 error.AccessDenied,
2320 error.PermissionDenied,
23122321 error.InvalidUtf8,
23132322 error.InvalidWtf8,
23142323 error.SymLinkLoop,
......@@ -2371,6 +2380,7 @@ fn deleteTreeOpenInitialSubpath(self: Dir, sub_path: []const u8, kind_hint: File
23712380 },
23722381
23732382 error.AccessDenied,
2383 error.PermissionDenied,
23742384 error.SymLinkLoop,
23752385 error.ProcessFdQuotaExceeded,
23762386 error.NameTooLong,
......@@ -2397,6 +2407,7 @@ fn deleteTreeOpenInitialSubpath(self: Dir, sub_path: []const u8, kind_hint: File
23972407 },
23982408
23992409 error.AccessDenied,
2410 error.PermissionDenied,
24002411 error.InvalidUtf8,
24012412 error.InvalidWtf8,
24022413 error.SymLinkLoop,
lib/std/io/c_writer.zig+1-1
......@@ -23,7 +23,7 @@ fn cWriterWrite(c_file: *std.c.FILE, bytes: []const u8) std.fs.File.WriteError!u
2323 .FBIG => return error.FileTooBig,
2424 .IO => return error.InputOutput,
2525 .NOSPC => return error.NoSpaceLeft,
26 .PERM => return error.AccessDenied,
26 .PERM => return error.PermissionDenied,
2727 .PIPE => return error.BrokenPipe,
2828 else => |err| return std.posix.unexpectedErrno(err),
2929 }
lib/std/os.zig+1-1
......@@ -65,7 +65,7 @@ pub fn accessW(path: [*:0]const u16) windows.GetFileAttributesError!void {
6565 switch (windows.GetLastError()) {
6666 .FILE_NOT_FOUND => return error.FileNotFound,
6767 .PATH_NOT_FOUND => return error.FileNotFound,
68 .ACCESS_DENIED => return error.PermissionDenied,
68 .ACCESS_DENIED => return error.AccessDenied,
6969 else => |err| return windows.unexpectedError(err),
7070 }
7171}
lib/std/os/linux/bpf.zig+6-6
......@@ -1548,7 +1548,7 @@ pub fn map_create(map_type: MapType, key_size: u32, value_size: u32, max_entries
15481548 .SUCCESS => return @as(fd_t, @intCast(rc)),
15491549 .INVAL => return error.MapTypeOrAttrInvalid,
15501550 .NOMEM => return error.SystemResources,
1551 .PERM => return error.AccessDenied,
1551 .PERM => return error.PermissionDenied,
15521552 else => |err| return unexpectedErrno(err),
15531553 }
15541554}
......@@ -1574,7 +1574,7 @@ pub fn map_lookup_elem(fd: fd_t, key: []const u8, value: []u8) !void {
15741574 .FAULT => unreachable,
15751575 .INVAL => return error.FieldInAttrNeedsZeroing,
15761576 .NOENT => return error.NotFound,
1577 .PERM => return error.AccessDenied,
1577 .PERM => return error.PermissionDenied,
15781578 else => |err| return unexpectedErrno(err),
15791579 }
15801580}
......@@ -1597,7 +1597,7 @@ pub fn map_update_elem(fd: fd_t, key: []const u8, value: []const u8, flags: u64)
15971597 .FAULT => unreachable,
15981598 .INVAL => return error.FieldInAttrNeedsZeroing,
15991599 .NOMEM => return error.SystemResources,
1600 .PERM => return error.AccessDenied,
1600 .PERM => return error.PermissionDenied,
16011601 else => |err| return unexpectedErrno(err),
16021602 }
16031603}
......@@ -1617,7 +1617,7 @@ pub fn map_delete_elem(fd: fd_t, key: []const u8) !void {
16171617 .FAULT => unreachable,
16181618 .INVAL => return error.FieldInAttrNeedsZeroing,
16191619 .NOENT => return error.NotFound,
1620 .PERM => return error.AccessDenied,
1620 .PERM => return error.PermissionDenied,
16211621 else => |err| return unexpectedErrno(err),
16221622 }
16231623}
......@@ -1638,7 +1638,7 @@ pub fn map_get_next_key(fd: fd_t, key: []const u8, next_key: []u8) !bool {
16381638 .FAULT => unreachable,
16391639 .INVAL => return error.FieldInAttrNeedsZeroing,
16401640 .NOENT => return false,
1641 .PERM => return error.AccessDenied,
1641 .PERM => return error.PermissionDenied,
16421642 else => |err| return unexpectedErrno(err),
16431643 }
16441644}
......@@ -1712,7 +1712,7 @@ pub fn prog_load(
17121712 .ACCES => error.UnsafeProgram,
17131713 .FAULT => unreachable,
17141714 .INVAL => error.InvalidProgram,
1715 .PERM => error.AccessDenied,
1715 .PERM => error.PermissionDenied,
17161716 else => |err| unexpectedErrno(err),
17171717 };
17181718}
lib/std/posix.zig+61-45
......@@ -281,6 +281,7 @@ pub fn close(fd: fd_t) void {
281281
282282pub const FChmodError = error{
283283 AccessDenied,
284 PermissionDenied,
284285 InputOutput,
285286 SymLinkLoop,
286287 FileNotFound,
......@@ -310,7 +311,7 @@ pub fn fchmod(fd: fd_t, mode: mode_t) FChmodError!void {
310311 .NOENT => return error.FileNotFound,
311312 .NOMEM => return error.SystemResources,
312313 .NOTDIR => return error.FileNotFound,
313 .PERM => return error.AccessDenied,
314 .PERM => return error.PermissionDenied,
314315 .ROFS => return error.ReadOnlyFileSystem,
315316 else => |err| return unexpectedErrno(err),
316317 }
......@@ -387,7 +388,7 @@ fn fchmodat1(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
387388 .NOTDIR => return error.FileNotFound,
388389 .NOMEM => return error.SystemResources,
389390 .OPNOTSUPP => return error.OperationNotSupported,
390 .PERM => return error.AccessDenied,
391 .PERM => return error.PermissionDenied,
391392 .ROFS => return error.ReadOnlyFileSystem,
392393 else => |err| return unexpectedErrno(err),
393394 }
......@@ -418,7 +419,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
418419 .NOMEM => return error.SystemResources,
419420 .NOTDIR => return error.FileNotFound,
420421 .OPNOTSUPP => return error.OperationNotSupported,
421 .PERM => return error.AccessDenied,
422 .PERM => return error.PermissionDenied,
422423 .ROFS => return error.ReadOnlyFileSystem,
423424
424425 .NOSYS => {
......@@ -447,7 +448,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
447448 .FAULT => unreachable,
448449 .INVAL => unreachable,
449450 .ACCES => return error.AccessDenied,
450 .PERM => return error.AccessDenied,
451 .PERM => return error.PermissionDenied,
451452 .LOOP => return error.SymLinkLoop,
452453 .MFILE => return error.ProcessFdQuotaExceeded,
453454 .NAMETOOLONG => return error.NameTooLong,
......@@ -486,7 +487,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
486487 .LOOP => return error.SymLinkLoop,
487488 .NOMEM => return error.SystemResources,
488489 .NOTDIR => return error.FileNotFound,
489 .PERM => return error.AccessDenied,
490 .PERM => return error.PermissionDenied,
490491 .ROFS => return error.ReadOnlyFileSystem,
491492 else => |err| return unexpectedErrno(err),
492493 }
......@@ -495,6 +496,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
495496
496497pub const FChownError = error{
497498 AccessDenied,
499 PermissionDenied,
498500 InputOutput,
499501 SymLinkLoop,
500502 FileNotFound,
......@@ -529,7 +531,7 @@ pub fn fchown(fd: fd_t, owner: ?uid_t, group: ?gid_t) FChownError!void {
529531 .NOENT => return error.FileNotFound,
530532 .NOMEM => return error.SystemResources,
531533 .NOTDIR => return error.FileNotFound,
532 .PERM => return error.AccessDenied,
534 .PERM => return error.PermissionDenied,
533535 .ROFS => return error.ReadOnlyFileSystem,
534536 else => |err| return unexpectedErrno(err),
535537 }
......@@ -1031,10 +1033,8 @@ pub const TruncateError = error{
10311033 FileTooBig,
10321034 InputOutput,
10331035 FileBusy,
1034
1035 /// In WASI, this error occurs when the file descriptor does
1036 /// not hold the required rights to call `ftruncate` on it.
10371036 AccessDenied,
1037 PermissionDenied,
10381038} || UnexpectedError;
10391039
10401040pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
......@@ -1066,7 +1066,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
10661066 .INTR => unreachable,
10671067 .FBIG => return error.FileTooBig,
10681068 .IO => return error.InputOutput,
1069 .PERM => return error.AccessDenied,
1069 .PERM => return error.PermissionDenied,
10701070 .TXTBSY => return error.FileBusy,
10711071 .BADF => unreachable, // Handle not open for writing
10721072 .INVAL => unreachable, // Handle not open for writing
......@@ -1082,7 +1082,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
10821082 .INTR => continue,
10831083 .FBIG => return error.FileTooBig,
10841084 .IO => return error.InputOutput,
1085 .PERM => return error.AccessDenied,
1085 .PERM => return error.PermissionDenied,
10861086 .TXTBSY => return error.FileBusy,
10871087 .BADF => unreachable, // Handle not open for writing
10881088 .INVAL => unreachable, // Handle not open for writing
......@@ -1176,6 +1176,7 @@ pub const WriteError = error{
11761176
11771177 /// File descriptor does not hold the required rights to write to it.
11781178 AccessDenied,
1179 PermissionDenied,
11791180 BrokenPipe,
11801181 SystemResources,
11811182 OperationAborted,
......@@ -1250,7 +1251,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
12501251 .FBIG => return error.FileTooBig,
12511252 .IO => return error.InputOutput,
12521253 .NOSPC => return error.NoSpaceLeft,
1253 .PERM => return error.AccessDenied,
1254 .PERM => return error.PermissionDenied,
12541255 .PIPE => return error.BrokenPipe,
12551256 .NOTCAPABLE => return error.AccessDenied,
12561257 else => |err| return unexpectedErrno(err),
......@@ -1278,7 +1279,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
12781279 .IO => return error.InputOutput,
12791280 .NOSPC => return error.NoSpaceLeft,
12801281 .ACCES => return error.AccessDenied,
1281 .PERM => return error.AccessDenied,
1282 .PERM => return error.PermissionDenied,
12821283 .PIPE => return error.BrokenPipe,
12831284 .CONNRESET => return error.ConnectionResetByPeer,
12841285 .BUSY => return error.DeviceBusy,
......@@ -1331,7 +1332,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {
13311332 .FBIG => return error.FileTooBig,
13321333 .IO => return error.InputOutput,
13331334 .NOSPC => return error.NoSpaceLeft,
1334 .PERM => return error.AccessDenied,
1335 .PERM => return error.PermissionDenied,
13351336 .PIPE => return error.BrokenPipe,
13361337 .NOTCAPABLE => return error.AccessDenied,
13371338 else => |err| return unexpectedErrno(err),
......@@ -1353,7 +1354,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {
13531354 .FBIG => return error.FileTooBig,
13541355 .IO => return error.InputOutput,
13551356 .NOSPC => return error.NoSpaceLeft,
1356 .PERM => return error.AccessDenied,
1357 .PERM => return error.PermissionDenied,
13571358 .PIPE => return error.BrokenPipe,
13581359 .CONNRESET => return error.ConnectionResetByPeer,
13591360 .BUSY => return error.DeviceBusy,
......@@ -1410,7 +1411,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
14101411 .FBIG => return error.FileTooBig,
14111412 .IO => return error.InputOutput,
14121413 .NOSPC => return error.NoSpaceLeft,
1413 .PERM => return error.AccessDenied,
1414 .PERM => return error.PermissionDenied,
14141415 .PIPE => return error.BrokenPipe,
14151416 .NXIO => return error.Unseekable,
14161417 .SPIPE => return error.Unseekable,
......@@ -1443,7 +1444,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
14431444 .FBIG => return error.FileTooBig,
14441445 .IO => return error.InputOutput,
14451446 .NOSPC => return error.NoSpaceLeft,
1446 .PERM => return error.AccessDenied,
1447 .PERM => return error.PermissionDenied,
14471448 .PIPE => return error.BrokenPipe,
14481449 .NXIO => return error.Unseekable,
14491450 .SPIPE => return error.Unseekable,
......@@ -1502,7 +1503,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz
15021503 .FBIG => return error.FileTooBig,
15031504 .IO => return error.InputOutput,
15041505 .NOSPC => return error.NoSpaceLeft,
1505 .PERM => return error.AccessDenied,
1506 .PERM => return error.PermissionDenied,
15061507 .PIPE => return error.BrokenPipe,
15071508 .NXIO => return error.Unseekable,
15081509 .SPIPE => return error.Unseekable,
......@@ -1528,7 +1529,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz
15281529 .FBIG => return error.FileTooBig,
15291530 .IO => return error.InputOutput,
15301531 .NOSPC => return error.NoSpaceLeft,
1531 .PERM => return error.AccessDenied,
1532 .PERM => return error.PermissionDenied,
15321533 .PIPE => return error.BrokenPipe,
15331534 .NXIO => return error.Unseekable,
15341535 .SPIPE => return error.Unseekable,
......@@ -1543,6 +1544,7 @@ pub const OpenError = error{
15431544 /// In WASI, this error may occur when the file descriptor does
15441545 /// not hold the required rights to open a new resource relative to it.
15451546 AccessDenied,
1547 PermissionDenied,
15461548 SymLinkLoop,
15471549 ProcessFdQuotaExceeded,
15481550 SystemFdQuotaExceeded,
......@@ -1660,7 +1662,7 @@ pub fn openZ(file_path: [*:0]const u8, flags: O, perm: mode_t) OpenError!fd_t {
16601662 .NOMEM => return error.SystemResources,
16611663 .NOSPC => return error.NoSpaceLeft,
16621664 .NOTDIR => return error.NotDir,
1663 .PERM => return error.AccessDenied,
1665 .PERM => return error.PermissionDenied,
16641666 .EXIST => return error.PathAlreadyExists,
16651667 .BUSY => return error.DeviceBusy,
16661668 .ILSEQ => |err| if (native_os == .wasi)
......@@ -1831,7 +1833,7 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: O, mode: mode_t) O
18311833 .NOMEM => return error.SystemResources,
18321834 .NOSPC => return error.NoSpaceLeft,
18331835 .NOTDIR => return error.NotDir,
1834 .PERM => return error.AccessDenied,
1836 .PERM => return error.PermissionDenied,
18351837 .EXIST => return error.PathAlreadyExists,
18361838 .BUSY => return error.DeviceBusy,
18371839 .OPNOTSUPP => return error.FileLocksNotSupported,
......@@ -1873,6 +1875,7 @@ pub fn dup2(old_fd: fd_t, new_fd: fd_t) !void {
18731875pub const ExecveError = error{
18741876 SystemResources,
18751877 AccessDenied,
1878 PermissionDenied,
18761879 InvalidExe,
18771880 FileSystem,
18781881 IsDir,
......@@ -1899,7 +1902,7 @@ pub fn execveZ(
18991902 .NFILE => return error.SystemFdQuotaExceeded,
19001903 .NOMEM => return error.SystemResources,
19011904 .ACCES => return error.AccessDenied,
1902 .PERM => return error.AccessDenied,
1905 .PERM => return error.PermissionDenied,
19031906 .INVAL => return error.InvalidExe,
19041907 .NOEXEC => return error.InvalidExe,
19051908 .IO => return error.FileSystem,
......@@ -2077,6 +2080,7 @@ pub const SymLinkError = error{
20772080 /// In WASI, this error may occur when the file descriptor does
20782081 /// not hold the required rights to create a new symbolic link relative to it.
20792082 AccessDenied,
2083 PermissionDenied,
20802084 DiskQuota,
20812085 PathAlreadyExists,
20822086 FileSystem,
......@@ -2130,7 +2134,7 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin
21302134 .FAULT => unreachable,
21312135 .INVAL => unreachable,
21322136 .ACCES => return error.AccessDenied,
2133 .PERM => return error.AccessDenied,
2137 .PERM => return error.PermissionDenied,
21342138 .DQUOT => return error.DiskQuota,
21352139 .EXIST => return error.PathAlreadyExists,
21362140 .IO => return error.FileSystem,
......@@ -2208,7 +2212,7 @@ pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:
22082212 .FAULT => unreachable,
22092213 .INVAL => unreachable,
22102214 .ACCES => return error.AccessDenied,
2211 .PERM => return error.AccessDenied,
2215 .PERM => return error.PermissionDenied,
22122216 .DQUOT => return error.DiskQuota,
22132217 .EXIST => return error.PathAlreadyExists,
22142218 .IO => return error.FileSystem,
......@@ -2229,6 +2233,7 @@ pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:
22292233
22302234pub const LinkError = UnexpectedError || error{
22312235 AccessDenied,
2236 PermissionDenied,
22322237 DiskQuota,
22332238 PathAlreadyExists,
22342239 FileSystem,
......@@ -2264,7 +2269,7 @@ pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8) LinkError!void {
22642269 .NOENT => return error.FileNotFound,
22652270 .NOMEM => return error.SystemResources,
22662271 .NOSPC => return error.NoSpaceLeft,
2267 .PERM => return error.AccessDenied,
2272 .PERM => return error.PermissionDenied,
22682273 .ROFS => return error.ReadOnlyFileSystem,
22692274 .XDEV => return error.NotSameFileSystem,
22702275 .INVAL => unreachable,
......@@ -2318,7 +2323,7 @@ pub fn linkatZ(
23182323 .NOMEM => return error.SystemResources,
23192324 .NOSPC => return error.NoSpaceLeft,
23202325 .NOTDIR => return error.NotDir,
2321 .PERM => return error.AccessDenied,
2326 .PERM => return error.PermissionDenied,
23222327 .ROFS => return error.ReadOnlyFileSystem,
23232328 .XDEV => return error.NotSameFileSystem,
23242329 .INVAL => unreachable,
......@@ -2367,7 +2372,7 @@ pub fn linkat(
23672372 .NOMEM => return error.SystemResources,
23682373 .NOSPC => return error.NoSpaceLeft,
23692374 .NOTDIR => return error.NotDir,
2370 .PERM => return error.AccessDenied,
2375 .PERM => return error.PermissionDenied,
23712376 .ROFS => return error.ReadOnlyFileSystem,
23722377 .XDEV => return error.NotSameFileSystem,
23732378 .INVAL => unreachable,
......@@ -2386,6 +2391,7 @@ pub const UnlinkError = error{
23862391 /// In WASI, this error may occur when the file descriptor does
23872392 /// not hold the required rights to unlink a resource by path relative to it.
23882393 AccessDenied,
2394 PermissionDenied,
23892395 FileBusy,
23902396 FileSystem,
23912397 IsDir,
......@@ -2441,7 +2447,7 @@ pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void {
24412447 switch (errno(system.unlink(file_path))) {
24422448 .SUCCESS => return,
24432449 .ACCES => return error.AccessDenied,
2444 .PERM => return error.AccessDenied,
2450 .PERM => return error.PermissionDenied,
24452451 .BUSY => return error.FileBusy,
24462452 .FAULT => unreachable,
24472453 .INVAL => unreachable,
......@@ -2535,7 +2541,7 @@ pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatEr
25352541 switch (errno(system.unlinkat(dirfd, file_path_c, flags))) {
25362542 .SUCCESS => return,
25372543 .ACCES => return error.AccessDenied,
2538 .PERM => return error.AccessDenied,
2544 .PERM => return error.PermissionDenied,
25392545 .BUSY => return error.FileBusy,
25402546 .FAULT => unreachable,
25412547 .IO => return error.FileSystem,
......@@ -2573,6 +2579,7 @@ pub const RenameError = error{
25732579 /// On Windows, this error may be returned instead of PathAlreadyExists when
25742580 /// renaming a directory over an existing directory.
25752581 AccessDenied,
2582 PermissionDenied,
25762583 FileBusy,
25772584 DiskQuota,
25782585 IsDir,
......@@ -2635,7 +2642,7 @@ pub fn renameZ(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!voi
26352642 switch (errno(system.rename(old_path, new_path))) {
26362643 .SUCCESS => return,
26372644 .ACCES => return error.AccessDenied,
2638 .PERM => return error.AccessDenied,
2645 .PERM => return error.PermissionDenied,
26392646 .BUSY => return error.FileBusy,
26402647 .DQUOT => return error.DiskQuota,
26412648 .FAULT => unreachable,
......@@ -2750,7 +2757,7 @@ pub fn renameatZ(
27502757 switch (errno(system.renameat(old_dir_fd, old_path, new_dir_fd, new_path))) {
27512758 .SUCCESS => return,
27522759 .ACCES => return error.AccessDenied,
2753 .PERM => return error.AccessDenied,
2760 .PERM => return error.PermissionDenied,
27542761 .BUSY => return error.FileBusy,
27552762 .DQUOT => return error.DiskQuota,
27562763 .FAULT => unreachable,
......@@ -2933,7 +2940,7 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: mode_t) MakeDir
29332940 .SUCCESS => return,
29342941 .ACCES => return error.AccessDenied,
29352942 .BADF => unreachable,
2936 .PERM => return error.AccessDenied,
2943 .PERM => return error.PermissionDenied,
29372944 .DQUOT => return error.DiskQuota,
29382945 .EXIST => return error.PathAlreadyExists,
29392946 .FAULT => unreachable,
......@@ -2978,6 +2985,7 @@ pub const MakeDirError = error{
29782985 /// In WASI, this error may occur when the file descriptor does
29792986 /// not hold the required rights to create a new directory relative to it.
29802987 AccessDenied,
2988 PermissionDenied,
29812989 DiskQuota,
29822990 PathAlreadyExists,
29832991 SymLinkLoop,
......@@ -3030,7 +3038,7 @@ pub fn mkdirZ(dir_path: [*:0]const u8, mode: mode_t) MakeDirError!void {
30303038 switch (errno(system.mkdir(dir_path, mode))) {
30313039 .SUCCESS => return,
30323040 .ACCES => return error.AccessDenied,
3033 .PERM => return error.AccessDenied,
3041 .PERM => return error.PermissionDenied,
30343042 .DQUOT => return error.DiskQuota,
30353043 .EXIST => return error.PathAlreadyExists,
30363044 .FAULT => unreachable,
......@@ -3071,6 +3079,7 @@ pub fn mkdirW(dir_path_w: []const u16, mode: mode_t) MakeDirError!void {
30713079
30723080pub const DeleteDirError = error{
30733081 AccessDenied,
3082 PermissionDenied,
30743083 FileBusy,
30753084 SymLinkLoop,
30763085 NameTooLong,
......@@ -3123,7 +3132,7 @@ pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void {
31233132 switch (errno(system.rmdir(dir_path))) {
31243133 .SUCCESS => return,
31253134 .ACCES => return error.AccessDenied,
3126 .PERM => return error.AccessDenied,
3135 .PERM => return error.PermissionDenied,
31273136 .BUSY => return error.FileBusy,
31283137 .FAULT => unreachable,
31293138 .INVAL => return error.BadPathName,
......@@ -3254,6 +3263,7 @@ pub const ReadLinkError = error{
32543263 /// In WASI, this error may occur when the file descriptor does
32553264 /// not hold the required rights to read value of a symbolic link relative to it.
32563265 AccessDenied,
3266 PermissionDenied,
32573267 FileSystem,
32583268 SymLinkLoop,
32593269 NameTooLong,
......@@ -3534,7 +3544,7 @@ pub fn isatty(handle: fd_t) bool {
35343544pub const SocketError = error{
35353545 /// Permission to create a socket of the specified type and/or
35363546 /// pro‐tocol is denied.
3537 PermissionDenied,
3547 AccessDenied,
35383548
35393549 /// The implementation does not support the specified address family.
35403550 AddressFamilyNotSupported,
......@@ -3604,7 +3614,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
36043614 }
36053615 return fd;
36063616 },
3607 .ACCES => return error.PermissionDenied,
3617 .ACCES => return error.AccessDenied,
36083618 .AFNOSUPPORT => return error.AddressFamilyNotSupported,
36093619 .INVAL => return error.ProtocolFamilyNotAvailable,
36103620 .MFILE => return error.ProcessFdQuotaExceeded,
......@@ -4188,6 +4198,9 @@ pub const ConnectError = error{
41884198 /// or
41894199 /// The user tried to connect to a broadcast address without having the socket broadcast flag enabled or
41904200 /// the connection request failed because of a local firewall rule.
4201 AccessDenied,
4202
4203 /// See AccessDenied
41914204 PermissionDenied,
41924205
41934206 /// Local address is already in use.
......@@ -4261,7 +4274,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne
42614274 while (true) {
42624275 switch (errno(system.connect(sock, sock_addr, len))) {
42634276 .SUCCESS => return,
4264 .ACCES => return error.PermissionDenied,
4277 .ACCES => return error.AccessDenied,
42654278 .PERM => return error.PermissionDenied,
42664279 .ADDRINUSE => return error.AddressInUse,
42674280 .ADDRNOTAVAIL => return error.AddressNotAvailable,
......@@ -4323,7 +4336,7 @@ pub fn getsockoptError(sockfd: fd_t) ConnectError!void {
43234336 switch (errno(rc)) {
43244337 .SUCCESS => switch (@as(E, @enumFromInt(err_code))) {
43254338 .SUCCESS => return,
4326 .ACCES => return error.PermissionDenied,
4339 .ACCES => return error.AccessDenied,
43274340 .PERM => return error.PermissionDenied,
43284341 .ADDRINUSE => return error.AddressInUse,
43294342 .ADDRNOTAVAIL => return error.AddressNotAvailable,
......@@ -4398,6 +4411,7 @@ pub const FStatError = error{
43984411 /// In WASI, this error may occur when the file descriptor does
43994412 /// not hold the required rights to get its filestat information.
44004413 AccessDenied,
4414 PermissionDenied,
44014415} || UnexpectedError;
44024416
44034417/// Return information about a file descriptor.
......@@ -4466,7 +4480,7 @@ pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!S
44664480 .BADF => unreachable, // Always a race condition.
44674481 .NOMEM => return error.SystemResources,
44684482 .ACCES => return error.AccessDenied,
4469 .PERM => return error.AccessDenied,
4483 .PERM => return error.PermissionDenied,
44704484 .FAULT => unreachable,
44714485 .NAMETOOLONG => return error.NameTooLong,
44724486 .LOOP => return error.SymLinkLoop,
......@@ -4870,6 +4884,7 @@ pub fn msync(memory: []align(page_size_min) u8, flags: i32) MSyncError!void {
48704884}
48714885
48724886pub const AccessError = error{
4887 AccessDenied,
48734888 PermissionDenied,
48744889 FileNotFound,
48754890 NameTooLong,
......@@ -4917,7 +4932,7 @@ pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
49174932 }
49184933 switch (errno(system.access(path, mode))) {
49194934 .SUCCESS => return,
4920 .ACCES => return error.PermissionDenied,
4935 .ACCES => return error.AccessDenied,
49214936 .PERM => return error.PermissionDenied,
49224937 .ROFS => return error.ReadOnlyFileSystem,
49234938 .LOOP => return error.SymLinkLoop,
......@@ -4998,7 +5013,7 @@ pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) Acces
49985013 }
49995014 switch (errno(system.faccessat(dirfd, path, mode, flags))) {
50005015 .SUCCESS => return,
5001 .ACCES => return error.PermissionDenied,
5016 .ACCES => return error.AccessDenied,
50025017 .PERM => return error.PermissionDenied,
50035018 .ROFS => return error.ReadOnlyFileSystem,
50045019 .LOOP => return error.SymLinkLoop,
......@@ -5049,7 +5064,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16) AccessError!void {
50495064 .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
50505065 .OBJECT_NAME_INVALID => unreachable,
50515066 .INVALID_PARAMETER => unreachable,
5052 .ACCESS_DENIED => return error.PermissionDenied,
5067 .ACCESS_DENIED => return error.AccessDenied,
50535068 .OBJECT_PATH_SYNTAX_BAD => unreachable,
50545069 else => |rc| return windows.unexpectedStatus(rc),
50555070 }
......@@ -5431,6 +5446,7 @@ pub fn flock(fd: fd_t, operation: i32) FlockError!void {
54315446pub const RealPathError = error{
54325447 FileNotFound,
54335448 AccessDenied,
5449 PermissionDenied,
54345450 NameTooLong,
54355451 NotSupported,
54365452 NotDir,
......@@ -6812,7 +6828,7 @@ pub const SetSockOptError = error{
68126828 /// Insufficient resources are available in the system to complete the call.
68136829 SystemResources,
68146830
6815 // Setting the socket option requires more elevated permissions.
6831 /// Setting the socket option requires more elevated permissions.
68166832 PermissionDenied,
68176833
68186834 OperationNotSupported,
......@@ -7307,7 +7323,7 @@ pub fn perf_event_open(
73077323}
73087324
73097325pub const TimerFdCreateError = error{
7310 AccessDenied,
7326 PermissionDenied,
73117327 ProcessFdQuotaExceeded,
73127328 SystemFdQuotaExceeded,
73137329 NoDevice,
......@@ -7326,7 +7342,7 @@ pub fn timerfd_create(clock_id: system.timerfd_clockid_t, flags: system.TFD) Tim
73267342 .NFILE => return error.SystemFdQuotaExceeded,
73277343 .NODEV => return error.NoDevice,
73287344 .NOMEM => return error.SystemResources,
7329 .PERM => return error.AccessDenied,
7345 .PERM => return error.PermissionDenied,
73307346 else => |err| return unexpectedErrno(err),
73317347 };
73327348}
lib/std/zig/system.zig+4
......@@ -731,6 +731,7 @@ pub fn abiAndDynamicLinkerFromFile(
731731 error.NetworkNotFound => unreachable, // Windows only
732732
733733 error.AccessDenied,
734 error.PermissionDenied,
734735 error.FileNotFound,
735736 error.NotLink,
736737 error.NotDir,
......@@ -825,6 +826,7 @@ fn glibcVerFromRPath(rpath: []const u8) !std.SemanticVersion {
825826 error.FileNotFound,
826827 error.NotDir,
827828 error.AccessDenied,
829 error.PermissionDenied,
828830 error.NoDevice,
829831 => return error.GLibCNotFound,
830832
......@@ -863,6 +865,7 @@ fn glibcVerFromRPath(rpath: []const u8) !std.SemanticVersion {
863865 error.NoDevice => unreachable, // not asking for a special device
864866
865867 error.AccessDenied,
868 error.PermissionDenied,
866869 error.FileNotFound,
867870 error.NotDir,
868871 error.IsDir,
......@@ -1122,6 +1125,7 @@ fn detectAbiAndDynamicLinker(
11221125 error.IsDir,
11231126 error.NotDir,
11241127 error.AccessDenied,
1128 error.PermissionDenied,
11251129 error.NoDevice,
11261130 error.FileNotFound,
11271131 error.NetworkNotFound,
src/DarwinPosixSpawn.zig+2-1
......@@ -6,6 +6,7 @@ pub const Error = error{
66 InvalidFileDescriptor,
77 NameTooLong,
88 TooBig,
9 AccessDenied,
910 PermissionDenied,
1011 InputOutput,
1112 FileSystem,
......@@ -188,7 +189,7 @@ pub fn spawnZ(
188189 .@"2BIG" => return error.TooBig,
189190 .NOMEM => return error.SystemResources,
190191 .BADF => return error.InvalidFileDescriptor,
191 .ACCES => return error.PermissionDenied,
192 .ACCES => return error.AccessDenied,
192193 .IO => return error.InputOutput,
193194 .LOOP => return error.FileSystem,
194195 .NAMETOOLONG => return error.NameTooLong,