mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-07 22:34:28 +00:00
std.Io.Threaded: implement dirCreateFile for Windows
This commit is contained in:
parent
aa6e8eff40
commit
b561d5f3fe
5 changed files with 59 additions and 64 deletions
|
|
@ -101,6 +101,13 @@ pub fn openFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.OpenFlags) F
|
||||||
return io.vtable.dirOpenFile(io.userdata, dir, sub_path, flags);
|
return io.vtable.dirOpenFile(io.userdata, dir, sub_path, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates, opens, or overwrites a file with write access.
|
||||||
|
///
|
||||||
|
/// Allocates a resource to be dellocated with `File.close`.
|
||||||
|
///
|
||||||
|
/// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/).
|
||||||
|
/// On WASI, `sub_path` should be encoded as valid UTF-8.
|
||||||
|
/// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
|
||||||
pub fn createFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
|
pub fn createFile(dir: Dir, io: Io, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
|
||||||
return io.vtable.dirCreateFile(io.userdata, dir, sub_path, flags);
|
return io.vtable.dirCreateFile(io.userdata, dir, sub_path, flags);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ pub fn io(t: *Threaded) Io {
|
||||||
else => dirAccessPosix,
|
else => dirAccessPosix,
|
||||||
},
|
},
|
||||||
.dirCreateFile = switch (builtin.os.tag) {
|
.dirCreateFile = switch (builtin.os.tag) {
|
||||||
.windows => @panic("TODO"),
|
.windows => dirCreateFileWindows,
|
||||||
.wasi => dirCreateFileWasi,
|
.wasi => dirCreateFileWasi,
|
||||||
else => dirCreateFilePosix,
|
else => dirCreateFilePosix,
|
||||||
},
|
},
|
||||||
|
|
@ -1483,6 +1483,54 @@ fn dirCreateFilePosix(
|
||||||
return .{ .handle = fd };
|
return .{ .handle = fd };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dirCreateFileWindows(
|
||||||
|
userdata: ?*anyopaque,
|
||||||
|
dir: Io.Dir,
|
||||||
|
sub_path: []const u8,
|
||||||
|
flags: Io.File.CreateFlags,
|
||||||
|
) Io.File.OpenError!Io.File {
|
||||||
|
const w = windows;
|
||||||
|
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||||
|
try t.checkCancel();
|
||||||
|
|
||||||
|
const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, sub_path);
|
||||||
|
const sub_path_w = sub_path_w_array.span();
|
||||||
|
|
||||||
|
const read_flag = if (flags.read) @as(u32, w.GENERIC_READ) else 0;
|
||||||
|
const handle = try w.OpenFile(sub_path_w, .{
|
||||||
|
.dir = dir.handle,
|
||||||
|
.access_mask = w.SYNCHRONIZE | w.GENERIC_WRITE | read_flag,
|
||||||
|
.creation = if (flags.exclusive)
|
||||||
|
@as(u32, w.FILE_CREATE)
|
||||||
|
else if (flags.truncate)
|
||||||
|
@as(u32, w.FILE_OVERWRITE_IF)
|
||||||
|
else
|
||||||
|
@as(u32, w.FILE_OPEN_IF),
|
||||||
|
});
|
||||||
|
errdefer w.CloseHandle(handle);
|
||||||
|
var io_status_block: w.IO_STATUS_BLOCK = undefined;
|
||||||
|
const range_off: w.LARGE_INTEGER = 0;
|
||||||
|
const range_len: w.LARGE_INTEGER = 1;
|
||||||
|
const exclusive = switch (flags.lock) {
|
||||||
|
.none => return .{ .handle = handle },
|
||||||
|
.shared => false,
|
||||||
|
.exclusive => true,
|
||||||
|
};
|
||||||
|
try w.LockFile(
|
||||||
|
handle,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
&io_status_block,
|
||||||
|
&range_off,
|
||||||
|
&range_len,
|
||||||
|
null,
|
||||||
|
@intFromBool(flags.lock_nonblocking),
|
||||||
|
@intFromBool(exclusive),
|
||||||
|
);
|
||||||
|
return .{ .handle = handle };
|
||||||
|
}
|
||||||
|
|
||||||
fn dirCreateFileWasi(
|
fn dirCreateFileWasi(
|
||||||
userdata: ?*anyopaque,
|
userdata: ?*anyopaque,
|
||||||
dir: Io.Dir,
|
dir: Io.Dir,
|
||||||
|
|
|
||||||
|
|
@ -299,12 +299,6 @@ pub fn createFileAbsolute(absolute_path: []const u8, flags: File.CreateFlags) Fi
|
||||||
return cwd().createFile(absolute_path, flags);
|
return cwd().createFile(absolute_path, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `createFileAbsolute` but the path parameter is WTF-16 encoded.
|
|
||||||
pub fn createFileAbsoluteW(absolute_path_w: [*:0]const u16, flags: File.CreateFlags) File.OpenError!File {
|
|
||||||
assert(path.isAbsoluteWindowsW(absolute_path_w));
|
|
||||||
return cwd().createFileW(mem.span(absolute_path_w), flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Delete a file name and possibly the file it refers to, based on an absolute path.
|
/// Delete a file name and possibly the file it refers to, based on an absolute path.
|
||||||
/// Asserts that the path is absolute. See `Dir.deleteFile` for a function that
|
/// Asserts that the path is absolute. See `Dir.deleteFile` for a function that
|
||||||
/// operates on both absolute and relative paths.
|
/// operates on both absolute and relative paths.
|
||||||
|
|
|
||||||
|
|
@ -900,64 +900,14 @@ pub fn openFileW(self: Dir, sub_path_w: []const u16, flags: File.OpenFlags) File
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, opens, or overwrites a file with write access.
|
/// Deprecated in favor of `Io.Dir.createFile`.
|
||||||
/// Call `File.close` on the result when done.
|
|
||||||
/// Asserts that the path parameter has no null bytes.
|
|
||||||
/// On Windows, `sub_path` should be encoded as [WTF-8](https://wtf-8.codeberg.page/).
|
|
||||||
/// On WASI, `sub_path` should be encoded as valid UTF-8.
|
|
||||||
/// On other platforms, `sub_path` is an opaque sequence of bytes with no particular encoding.
|
|
||||||
pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
|
pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File {
|
||||||
if (native_os == .windows) {
|
|
||||||
const path_w = try windows.sliceToPrefixedFileW(self.fd, sub_path);
|
|
||||||
return self.createFileW(path_w.span(), flags);
|
|
||||||
}
|
|
||||||
var threaded: Io.Threaded = .init_single_threaded;
|
var threaded: Io.Threaded = .init_single_threaded;
|
||||||
const io = threaded.io();
|
const io = threaded.io();
|
||||||
const new_file = try Io.Dir.createFile(self.adaptToNewApi(), io, sub_path, flags);
|
const new_file = try Io.Dir.createFile(self.adaptToNewApi(), io, sub_path, flags);
|
||||||
return .adaptFromNewApi(new_file);
|
return .adaptFromNewApi(new_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `createFile` but Windows-only and the path parameter is
|
|
||||||
/// [WTF-16](https://wtf-8.codeberg.page/#potentially-ill-formed-utf-16) encoded.
|
|
||||||
pub fn createFileW(self: Dir, sub_path_w: []const u16, flags: File.CreateFlags) File.OpenError!File {
|
|
||||||
const w = windows;
|
|
||||||
const read_flag = if (flags.read) @as(u32, w.GENERIC_READ) else 0;
|
|
||||||
const file: File = .{
|
|
||||||
.handle = try w.OpenFile(sub_path_w, .{
|
|
||||||
.dir = self.fd,
|
|
||||||
.access_mask = w.SYNCHRONIZE | w.GENERIC_WRITE | read_flag,
|
|
||||||
.creation = if (flags.exclusive)
|
|
||||||
@as(u32, w.FILE_CREATE)
|
|
||||||
else if (flags.truncate)
|
|
||||||
@as(u32, w.FILE_OVERWRITE_IF)
|
|
||||||
else
|
|
||||||
@as(u32, w.FILE_OPEN_IF),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
errdefer file.close();
|
|
||||||
var io: w.IO_STATUS_BLOCK = undefined;
|
|
||||||
const range_off: w.LARGE_INTEGER = 0;
|
|
||||||
const range_len: w.LARGE_INTEGER = 1;
|
|
||||||
const exclusive = switch (flags.lock) {
|
|
||||||
.none => return file,
|
|
||||||
.shared => false,
|
|
||||||
.exclusive => true,
|
|
||||||
};
|
|
||||||
try w.LockFile(
|
|
||||||
file.handle,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
&io,
|
|
||||||
&range_off,
|
|
||||||
&range_len,
|
|
||||||
null,
|
|
||||||
@intFromBool(flags.lock_nonblocking),
|
|
||||||
@intFromBool(exclusive),
|
|
||||||
);
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deprecated in favor of `Io.Dir.MakeError`.
|
/// Deprecated in favor of `Io.Dir.MakeError`.
|
||||||
pub const MakeError = Io.Dir.MakeError;
|
pub const MakeError = Io.Dir.MakeError;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4684,9 +4684,7 @@ pub const AccessError = error{
|
||||||
/// Windows. See `fs` for the cross-platform file system API.
|
/// Windows. See `fs` for the cross-platform file system API.
|
||||||
pub fn access(path: []const u8, mode: u32) AccessError!void {
|
pub fn access(path: []const u8, mode: u32) AccessError!void {
|
||||||
if (native_os == .windows) {
|
if (native_os == .windows) {
|
||||||
const path_w = try windows.sliceToPrefixedFileW(null, path);
|
@compileError("use std.Io instead");
|
||||||
_ = try windows.GetFileAttributesW(path_w.span().ptr);
|
|
||||||
return;
|
|
||||||
} else if (native_os == .wasi and !builtin.link_libc) {
|
} else if (native_os == .wasi and !builtin.link_libc) {
|
||||||
@compileError("wasi doesn't support absolute paths");
|
@compileError("wasi doesn't support absolute paths");
|
||||||
}
|
}
|
||||||
|
|
@ -4697,9 +4695,7 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {
|
||||||
/// Same as `access` except `path` is null-terminated.
|
/// Same as `access` except `path` is null-terminated.
|
||||||
pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
|
pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
|
||||||
if (native_os == .windows) {
|
if (native_os == .windows) {
|
||||||
const path_w = try windows.cStrToPrefixedFileW(null, path);
|
@compileError("use std.Io instead");
|
||||||
_ = try windows.GetFileAttributesW(path_w.span().ptr);
|
|
||||||
return;
|
|
||||||
} else if (native_os == .wasi and !builtin.link_libc) {
|
} else if (native_os == .wasi and !builtin.link_libc) {
|
||||||
return access(mem.sliceTo(path, 0), mode);
|
return access(mem.sliceTo(path, 0), mode);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue