zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit d8f966a04b09ede06840b5fdd42b7d8e65b0cb25 (tree)
parent bfc569bc9877a4f305080bc6cde0e42fed7433e0
Author: daurnimator <quae@daurnimator.com>
Date:   Wed, 15 Jan 2020 18:17:14 +1000

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

Diffstat:
Mlib/std/fs.zig | 19++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/lib/std/fs.zig b/lib/std/fs.zig @@ -301,35 +301,32 @@ pub fn makeDirW(dir_path: [*:0]const u16) !void { /// already exists and is a directory. /// This function is not atomic, and if it returns an error, the file system may /// have been modified regardless. -/// TODO determine if we can remove the allocator requirement from this function -pub fn makePath(allocator: *Allocator, full_path: []const u8) !void { - const resolved_path = try path.resolve(allocator, &[_][]const u8{full_path}); - defer allocator.free(resolved_path); - - var end_index: usize = resolved_path.len; +pub fn makePath(full_path: []const u8) !void { + var end_index: usize = full_path.len; 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 => { // TODO stat the file and return an error if it's not a directory // this is important because otherwise a dangling symlink // could cause an infinite loop - if (end_index == resolved_path.len) return; + if (end_index == full_path.len) return; }, error.FileNotFound => { + if (end_index == 0) return err; // march end_index backward until next path component while (true) { end_index -= 1; - if (path.isSep(resolved_path[end_index])) break; + if (path.isSep(full_path[end_index])) break; } continue; }, 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 while (true) { 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; } } }