aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/node/node_fs.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-10-11 00:03:32 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-10-11 00:03:32 -0700
commit40623cf967b6e776281b1f79cc4cd02e5d87f7d9 (patch)
treedda4d53456121a8f673bd191503df048b987448f /src/bun.js/node/node_fs.zig
parentd07e4f8bd178b4e7450a6990c51ca3bfa0201127 (diff)
downloadbun-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.zig110
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 => {},