std.Io.Threaded: add dirMake for Windows

This commit is contained in:
Andrew Kelley 2025-10-19 20:42:43 -07:00
parent 10b1eef2d3
commit ed7747e90f
2 changed files with 27 additions and 26 deletions

View File

@ -164,7 +164,7 @@ pub fn io(t: *Threaded) Io {
.conditionWake = conditionWake,
.dirMake = switch (builtin.os.tag) {
.windows => @panic("TODO"),
.windows => dirMakeWindows,
.wasi => dirMakeWasi,
else => dirMakePosix,
},
@ -968,6 +968,28 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: I
}
}
fn dirMakeWindows(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: Io.Dir.Mode) Io.Dir.MakeError!void {
const t: *Threaded = @ptrCast(@alignCast(userdata));
try t.checkCancel();
const sub_path_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path);
_ = mode;
const sub_dir_handle = windows.OpenFile(sub_path_w.span(), .{
.dir = dir.handle,
.access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,
.creation = windows.FILE_CREATE,
.filter = .dir_only,
}) catch |err| switch (err) {
error.IsDir => return error.Unexpected,
error.PipeBusy => return error.Unexpected,
error.NoDevice => return error.Unexpected,
error.WouldBlock => return error.Unexpected,
error.AntivirusInterference => return error.Unexpected,
else => |e| return e,
};
windows.CloseHandle(sub_dir_handle);
}
fn dirStat(userdata: ?*anyopaque, dir: Io.Dir) Io.Dir.StatError!Io.Dir.Stat {
const t: *Threaded = @ptrCast(@alignCast(userdata));
try t.checkCancel();
@ -3164,7 +3186,7 @@ fn netInterfaceNameResolve(
if (native_os == .windows) {
try t.checkCancel();
const index = std.os.windows.ws2_32.if_nametoindex(&name.bytes);
const index = windows.ws2_32.if_nametoindex(&name.bytes);
if (index == 0) return error.InterfaceNotFound;
return .{ .index = index };
}

View File

@ -2691,8 +2691,7 @@ pub fn renameatW(
/// On other platforms, `sub_dir_path` is an opaque sequence of bytes with no particular encoding.
pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: mode_t) MakeDirError!void {
if (native_os == .windows) {
const sub_dir_path_w = try windows.sliceToPrefixedFileW(dir_fd, sub_dir_path);
return mkdiratW(dir_fd, sub_dir_path_w.span(), mode);
@compileError("use std.Io instead");
} else if (native_os == .wasi and !builtin.link_libc) {
@compileError("use std.Io instead");
} else {
@ -2704,10 +2703,9 @@ pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: mode_t) MakeDirErro
/// Same as `mkdirat` except the parameters are null-terminated.
pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: mode_t) MakeDirError!void {
if (native_os == .windows) {
const sub_dir_path_w = try windows.cStrToPrefixedFileW(dir_fd, sub_dir_path);
return mkdiratW(dir_fd, sub_dir_path_w.span(), mode);
@compileError("use std.Io instead");
} else if (native_os == .wasi and !builtin.link_libc) {
return mkdirat(dir_fd, mem.sliceTo(sub_dir_path, 0), mode);
@compileError("use std.Io instead");
}
switch (errno(system.mkdirat(dir_fd, sub_dir_path, mode))) {
.SUCCESS => return,
@ -2732,25 +2730,6 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: mode_t) MakeDir
}
}
/// Windows-only. Same as `mkdirat` except the parameter WTF16 LE encoded.
pub fn mkdiratW(dir_fd: fd_t, sub_path_w: []const u16, mode: mode_t) MakeDirError!void {
_ = mode;
const sub_dir_handle = windows.OpenFile(sub_path_w, .{
.dir = dir_fd,
.access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE,
.creation = windows.FILE_CREATE,
.filter = .dir_only,
}) catch |err| switch (err) {
error.IsDir => return error.Unexpected,
error.PipeBusy => return error.Unexpected,
error.NoDevice => return error.Unexpected,
error.WouldBlock => return error.Unexpected,
error.AntivirusInterference => return error.Unexpected,
else => |e| return e,
};
windows.CloseHandle(sub_dir_handle);
}
pub const MakeDirError = std.Io.Dir.MakeError;
/// Create a directory.