commit 14c3c47fb7315e6199751082f9ef544972bb13e6 (tree)
parent 0e3d74df8a8c06bcc0b1e4bff205f4ab8e4c6c13
Author: Ryan Liptak <squeek502@hotmail.com>
Date: Fri, 26 Jun 2020 15:49:31 -0700
fs.deleteFile: Translate to error.IsDir when appropriate on POSIX systems
Linux deviates from POSIX and returns EISDIR while other POSIX systems return EPERM. To make all platforms consistent in their errors when calling deleteFile on a directory, we have to do a stat to translate EPERM (AccessDenied) to EISDIR (IsDir).
Diffstat:
1 file changed, 20 insertions(+), 0 deletions(-)
diff --git a/lib/std/fs.zig b/lib/std/fs.zig
@@ -1112,6 +1112,16 @@ pub const Dir = struct {
pub fn deleteFile(self: Dir, sub_path: []const u8) DeleteFileError!void {
os.unlinkat(self.fd, sub_path, 0) catch |err| switch (err) {
error.DirNotEmpty => unreachable, // not passing AT_REMOVEDIR
+ error.AccessDenied => |e| switch (builtin.os.tag) {
+ // non-Linux POSIX systems return EPERM when trying to delete a directory, so
+ // we need to handle that case specifically and translate the error
+ .macosx, .ios, .freebsd, .netbsd, .dragonfly => {
+ const fstat = os.fstatat(self.fd, sub_path, 0) catch return e;
+ const is_dir = fstat.mode & os.S_IFMT == os.S_IFDIR;
+ return if (is_dir) error.IsDir else e;
+ },
+ else => return e,
+ },
else => |e| return e,
};
}
@@ -1122,6 +1132,16 @@ pub const Dir = struct {
pub fn deleteFileZ(self: Dir, sub_path_c: [*:0]const u8) DeleteFileError!void {
os.unlinkatZ(self.fd, sub_path_c, 0) catch |err| switch (err) {
error.DirNotEmpty => unreachable, // not passing AT_REMOVEDIR
+ error.AccessDenied => |e| switch (builtin.os.tag) {
+ // non-Linux POSIX systems return EPERM when trying to delete a directory, so
+ // we need to handle that case specifically and translate the error
+ .macosx, .ios, .freebsd, .netbsd, .dragonfly => {
+ const fstat = os.fstatatZ(self.fd, sub_path_c, 0) catch return e;
+ const is_dir = fstat.mode & os.S_IFMT == os.S_IFDIR;
+ return if (is_dir) error.IsDir else e;
+ },
+ else => return e,
+ },
else => |e| return e,
};
}