diff options
author | 2022-10-11 00:03:32 -0700 | |
---|---|---|
committer | 2022-10-11 00:03:32 -0700 | |
commit | 40623cf967b6e776281b1f79cc4cd02e5d87f7d9 (patch) | |
tree | dda4d53456121a8f673bd191503df048b987448f /src/bun.js/node/node_fs.zig | |
parent | d07e4f8bd178b4e7450a6990c51ca3bfa0201127 (diff) | |
download | bun-40623cf967b6e776281b1f79cc4cd02e5d87f7d9.tar.gz bun-40623cf967b6e776281b1f79cc4cd02e5d87f7d9.tar.zst bun-40623cf967b6e776281b1f79cc4cd02e5d87f7d9.zip |
Implement `fs.rm` cross-platformly
Diffstat (limited to 'src/bun.js/node/node_fs.zig')
-rw-r--r-- | src/bun.js/node/node_fs.zig | 110 |
1 files changed, 107 insertions, 3 deletions
diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index df79ab72a..ef0f2385b 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -3658,9 +3658,9 @@ pub const NodeFS = struct { _ = flavor; switch (comptime flavor) { .sync => { - var dest = args.path.sliceZ(&this.sync_error_buf); - if (comptime Environment.isMac) { + var dest = args.path.sliceZ(&this.sync_error_buf); + while (true) { var flags: u32 = 0; if (args.recursive) { @@ -3706,7 +3706,111 @@ pub const NodeFS = struct { return Maybe(Return.Rm).success; } } else if (comptime Environment.isLinux) { - // TODO: + if (args.recursive) { + std.fs.cwd().deleteTree(args.path.slice()) catch |err| { + const errno: std.os.E = switch (err) { + error.InvalidHandle => .BADF, + error.AccessDenied => .PERM, + error.FileTooBig => .FBIG, + error.SymLinkLoop => .LOOP, + error.ProcessFdQuotaExceeded => .NFILE, + error.NameTooLong => .NAMETOOLONG, + error.SystemFdQuotaExceeded => .MFILE, + error.SystemResources => .NOMEM, + error.ReadOnlyFileSystem => .ROFS, + error.FileSystem => .IO, + error.FileBusy => .BUSY, + error.DeviceBusy => .BUSY, + + // One of the path components was not a directory. + // This error is unreachable if `sub_path` does not contain a path separator. + error.NotDir => .NOTDIR, + // On Windows, file paths must be valid Unicode. + error.InvalidUtf8 => .INVAL, + + // On Windows, file paths cannot contain these characters: + // '/', '*', '?', '"', '<', '>', '|' + error.BadPathName => .INVAL, + + else => .FAULT, + }; + if (args.force) { + return Maybe(Return.Rm).success; + } + return Maybe(Return.Rm){ + .err = JSC.Node.Syscall.Error.fromCode(errno, .unlink), + }; + }; + return Maybe(Return.Rm).success; + } + } + + { + var dest = args.path.sliceZ(&this.sync_error_buf); + std.os.unlinkZ(dest) catch |er| { + // empircally, it seems to return AccessDenied when the + // file is actually a directory on macOS. + if (er == error.IsDir or + er == error.NotDir or + er == error.AccessDenied) + { + std.os.rmdirZ(dest) catch |err| { + if (args.force) { + return Maybe(Return.Rm).success; + } + + const code: std.os.E = switch (err) { + error.AccessDenied => .PERM, + error.SymLinkLoop => .LOOP, + error.NameTooLong => .NAMETOOLONG, + error.SystemResources => .NOMEM, + error.ReadOnlyFileSystem => .ROFS, + error.FileBusy => .BUSY, + error.FileNotFound => .NOENT, + error.InvalidUtf8 => .INVAL, + error.BadPathName => .INVAL, + else => .FAULT, + }; + + return .{ + .err = JSC.Node.Syscall.Error.fromCode( + code, + .rmdir, + ), + }; + }; + + return Maybe(Return.Rm).success; + } + + if (args.force) { + return Maybe(Return.Rm).success; + } + + { + const code: std.os.E = switch (er) { + error.AccessDenied => .PERM, + error.SymLinkLoop => .LOOP, + error.NameTooLong => .NAMETOOLONG, + error.SystemResources => .NOMEM, + error.ReadOnlyFileSystem => .ROFS, + error.FileBusy => .BUSY, + error.InvalidUtf8 => .INVAL, + error.BadPathName => .INVAL, + error.FileNotFound => .NOENT, + else => .FAULT, + }; + + return .{ + .err = JSC.Node.Syscall.Error.fromCode( + code, + .unlink, + ), + }; + } + }; + + return Maybe(Return.Rm).success; } }, else => {}, |