| author | |
| committer | |
| log | 51946f5adcc0e2a7c26f17ab7784e5e90aba2ea1 |
| tree | 1b0f1996abd450b2068d6e084c25e7f5daf9d7b3 |
| parent | 9335529b9be8f7c359e6f2ba79099f263f1a8479 |
Closes #184522 files changed, 25 insertions(+), 6 deletions(-)
lib/std/fs/Dir.zig+8| ... | @@ -1111,6 +1111,14 @@ pub fn makeDirW(self: Dir, sub_path: [*:0]const u16) !void { | ... | @@ -1111,6 +1111,14 @@ pub fn makeDirW(self: Dir, sub_path: [*:0]const u16) !void { |
| 1111 | /// Returns success if the path already exists and is a directory. | 1111 | /// Returns success if the path already exists and is a directory. |
| 1112 | /// This function is not atomic, and if it returns an error, the file system may | 1112 | /// This function is not atomic, and if it returns an error, the file system may |
| 1113 | /// have been modified regardless. | 1113 | /// have been modified regardless. |
| 1114 | /// | ||
| 1115 | /// Paths containing `..` components are handled differently depending on the platform: | ||
| 1116 | /// - On Windows, `..` are resolved before the path is passed to NtCreateFile, meaning | ||
| 1117 | /// a `sub_path` like "first/../second" will resolve to "second" and only a | ||
| 1118 | /// `./second` directory will be created. | ||
| 1119 | /// - On other platforms, `..` are not resolved before the path is passed to `mkdirat`, | ||
| 1120 | /// meaning a `sub_path` like "first/../second" will create both a `./first` | ||
| 1121 | /// and a `./second` directory. | ||
| 1114 | pub fn makePath(self: Dir, sub_path: []const u8) !void { | 1122 | pub fn makePath(self: Dir, sub_path: []const u8) !void { |
| 1115 | var it = try fs.path.componentIterator(sub_path); | 1123 | var it = try fs.path.componentIterator(sub_path); |
| 1116 | var component = it.last() orelse return; | 1124 | var component = it.last() orelse return; |
lib/std/fs/test.zig+17-6| ... | @@ -1131,12 +1131,23 @@ test "makepath relative walks" { | ... | @@ -1131,12 +1131,23 @@ test "makepath relative walks" { |
| 1131 | 1131 | ||
| 1132 | try tmp.dir.makePath(relPath); | 1132 | try tmp.dir.makePath(relPath); |
| 1133 | 1133 | ||
| 1134 | // verify created directories exist: | 1134 | // How .. is handled is different on Windows than non-Windows |
| 1135 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "A"); | 1135 | switch (builtin.os.tag) { |
| 1136 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "B"); | 1136 | .windows => { |
| 1137 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "C"); | 1137 | // On Windows, .. is resolved before passing the path to NtCreateFile, |
| 1138 | try expectDir(tmp.dir, "second"); | 1138 | // meaning everything except `first/C` drops out. |
| 1139 | try expectDir(tmp.dir, "third"); | 1139 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "C"); |
| 1140 | try testing.expectError(error.FileNotFound, tmp.dir.access("second", .{})); | ||
| 1141 | try testing.expectError(error.FileNotFound, tmp.dir.access("third", .{})); | ||
| 1142 | }, | ||
| 1143 | else => { | ||
| 1144 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "A"); | ||
| 1145 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "B"); | ||
| 1146 | try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "C"); | ||
| 1147 | try expectDir(tmp.dir, "second"); | ||
| 1148 | try expectDir(tmp.dir, "third"); | ||
| 1149 | }, | ||
| 1150 | } | ||
| 1140 | } | 1151 | } |
| 1141 | 1152 | ||
| 1142 | test "makepath ignores '.'" { | 1153 | test "makepath ignores '.'" { |