feature. See also
. The project being documented here (as the example) is the Zig library itself.
Dir.deleteTreeMinStackSizeWithKindHint
fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, kind_hint: File.Kind) DeleteTreeError!void
File
Code
fn deleteTreeMinStackSizeWithKindHint(parent: Dir, io: Io, sub_path: []const u8, kind_hint: File.Kind) DeleteTreeError!void {
start_over: while (true) {
var dir = (try parent.deleteTreeOpenInitialSubpath(io, sub_path, kind_hint)) orelse return;
var cleanup_dir_parent: ?Dir = null;
defer if (cleanup_dir_parent) |*d| d.close(io);
var cleanup_dir = true;
defer if (cleanup_dir) dir.close(io);
// ever store a single path component that was returned from the
// filesystem.
var dir_name_buf: [max_path_bytes]u8 = undefined;
var dir_name: []const u8 = sub_path;
// Go through each entry and if it is not a directory, delete it. If it is a directory,
// open it, and close the original directory. Repeat. Then start the entire operation over.
scan_dir: while (true) {
var dir_it = dir.iterateAssumeFirstIteration();
dir_it: while (try dir_it.next(io)) |entry| {
var treat_as_dir = entry.kind == .directory;
handle_entry: while (true) {
if (treat_as_dir) {
const new_dir = dir.openDir(io, entry.name, .{
.follow_symlinks = false,
.iterate = true,
}) catch |err| switch (err) {
error.NotDir => {
treat_as_dir = false;
continue :handle_entry;
},
error.FileNotFound => {
continue :dir_it;
},
error.AccessDenied,
error.PermissionDenied,
error.SymLinkLoop,
error.ProcessFdQuotaExceeded,
error.NameTooLong,
error.SystemFdQuotaExceeded,
error.NoDevice,
error.SystemResources,
error.Unexpected,
error.BadPathName,
error.NetworkNotFound,
error.Canceled,
=> |e| return e,
};
if (cleanup_dir_parent) |*d| d.close(io);
cleanup_dir_parent = dir;
dir = new_dir;
const result = dir_name_buf[0..entry.name.len];
@memcpy(result, entry.name);
dir_name = result;
continue :scan_dir;
} else {
if (dir.deleteFile(io, entry.name)) {
continue :dir_it;
} else |err| switch (err) {
error.FileNotFound => continue :dir_it,
error.NotDir => unreachable,
error.IsDir => {
treat_as_dir = true;
continue :handle_entry;
},
error.AccessDenied,
error.PermissionDenied,
error.SymLinkLoop,
error.NameTooLong,
error.SystemResources,
error.ReadOnlyFileSystem,
error.FileSystem,
error.FileBusy,
error.BadPathName,
error.NetworkNotFound,
error.Canceled,
error.Unexpected,
=> |e| return e,
}
}
}
}
// Now to remove the directory itself.
dir.close(io);
cleanup_dir = false;
if (cleanup_dir_parent) |d| {
d.deleteDir(io, dir_name) catch |err| switch (err) {
error.FileNotFound, error.DirNotEmpty => continue :start_over,
else => |e| return e,
};
continue :start_over;
} else {
parent.deleteDir(io, sub_path) catch |err| switch (err) {
error.FileNotFound => return,
error.DirNotEmpty => continue :start_over,
else => |e| return e,
};
return;
}
}
}
}