Skip to content

Commit 4891108

Browse files
committed
Dir.makePath: Document/test platform differences around .. component handling
Closes #18452
1 parent 9335529 commit 4891108

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

lib/std/fs/Dir.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,14 @@ pub fn makeDirW(self: Dir, sub_path: [*:0]const u16) !void {
11111111
/// Returns success if the path already exists and is a directory.
11121112
/// This function is not atomic, and if it returns an error, the file system may
11131113
/// 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.
11141122
pub fn makePath(self: Dir, sub_path: []const u8) !void {
11151123
var it = try fs.path.componentIterator(sub_path);
11161124
var component = it.last() orelse return;

lib/std/fs/test.zig

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,12 +1131,21 @@ test "makepath relative walks" {
11311131

11321132
try tmp.dir.makePath(relPath);
11331133

1134-
// verify created directories exist:
1135-
try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "A");
1136-
try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "B");
1137-
try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "C");
1138-
try expectDir(tmp.dir, "second");
1139-
try expectDir(tmp.dir, "third");
1134+
// How .. is handled is different on Windows than non-Windows
1135+
switch (builtin.os.tag) {
1136+
.windows => {
1137+
// On Windows, .. is resolved before passing the path to NtCreateFile,
1138+
// meaning everything except `first/C` drops out.
1139+
try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "C");
1140+
},
1141+
else => {
1142+
try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "A");
1143+
try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "B");
1144+
try expectDir(tmp.dir, "first" ++ fs.path.sep_str ++ "C");
1145+
try expectDir(tmp.dir, "second");
1146+
try expectDir(tmp.dir, "third");
1147+
},
1148+
}
11401149
}
11411150

11421151
test "makepath ignores '.'" {

0 commit comments

Comments
 (0)