std: fix fs.makePath
The previous behaviour of using path.resolve has unexpected behaviour around symlinks. This more simple implementation is more correct and doesn't require an allocator
This commit is contained in:
parent
bfc569bc98
commit
d8f966a04b
@ -301,35 +301,32 @@ pub fn makeDirW(dir_path: [*:0]const u16) !void {
|
|||||||
/// already exists and is a directory.
|
/// already exists and is a directory.
|
||||||
/// This function is not atomic, and if it returns an error, the file system may
|
/// This function is not atomic, and if it returns an error, the file system may
|
||||||
/// have been modified regardless.
|
/// have been modified regardless.
|
||||||
/// TODO determine if we can remove the allocator requirement from this function
|
pub fn makePath(full_path: []const u8) !void {
|
||||||
pub fn makePath(allocator: *Allocator, full_path: []const u8) !void {
|
var end_index: usize = full_path.len;
|
||||||
const resolved_path = try path.resolve(allocator, &[_][]const u8{full_path});
|
|
||||||
defer allocator.free(resolved_path);
|
|
||||||
|
|
||||||
var end_index: usize = resolved_path.len;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
makeDir(resolved_path[0..end_index]) catch |err| switch (err) {
|
cwd().makeDir(full_path[0..end_index]) catch |err| switch (err) {
|
||||||
error.PathAlreadyExists => {
|
error.PathAlreadyExists => {
|
||||||
// TODO stat the file and return an error if it's not a directory
|
// TODO stat the file and return an error if it's not a directory
|
||||||
// this is important because otherwise a dangling symlink
|
// this is important because otherwise a dangling symlink
|
||||||
// could cause an infinite loop
|
// could cause an infinite loop
|
||||||
if (end_index == resolved_path.len) return;
|
if (end_index == full_path.len) return;
|
||||||
},
|
},
|
||||||
error.FileNotFound => {
|
error.FileNotFound => {
|
||||||
|
if (end_index == 0) return err;
|
||||||
// march end_index backward until next path component
|
// march end_index backward until next path component
|
||||||
while (true) {
|
while (true) {
|
||||||
end_index -= 1;
|
end_index -= 1;
|
||||||
if (path.isSep(resolved_path[end_index])) break;
|
if (path.isSep(full_path[end_index])) break;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
else => return err,
|
else => return err,
|
||||||
};
|
};
|
||||||
if (end_index == resolved_path.len) return;
|
if (end_index == full_path.len) return;
|
||||||
// march end_index forward until next path component
|
// march end_index forward until next path component
|
||||||
while (true) {
|
while (true) {
|
||||||
end_index += 1;
|
end_index += 1;
|
||||||
if (end_index == resolved_path.len or path.isSep(resolved_path[end_index])) break;
|
if (end_index == full_path.len or path.isSep(full_path[end_index])) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user