Skip to content

Commit bcb07ec

Browse files
committed
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
1 parent 64cf22e commit bcb07ec

File tree

7 files changed

+93
-61
lines changed

7 files changed

+93
-61
lines changed

lib/std/fs/Dir.zig

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {
16521653
pub 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

19921994
pub 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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

0 commit comments

Comments
 (0)