mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
std.Io.Threaded: implement fileStat for Windows
This commit is contained in:
parent
5d7672f2ad
commit
5c527a1854
@ -1033,7 +1033,7 @@ fn dirMakePathPosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mo
|
|||||||
_ = dir;
|
_ = dir;
|
||||||
_ = sub_path;
|
_ = sub_path;
|
||||||
_ = mode;
|
_ = mode;
|
||||||
@panic("TODO");
|
@panic("TODO implement dirMakePathPosix");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dirMakePathWindows(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: Io.Dir.Mode) Io.Dir.MakeError!void {
|
fn dirMakePathWindows(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: Io.Dir.Mode) Io.Dir.MakeError!void {
|
||||||
@ -1042,7 +1042,7 @@ fn dirMakePathWindows(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8,
|
|||||||
_ = dir;
|
_ = dir;
|
||||||
_ = sub_path;
|
_ = sub_path;
|
||||||
_ = mode;
|
_ = mode;
|
||||||
@panic("TODO");
|
@panic("TODO implement dirMakePathWindows");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dirMakeOpenPathPosix(
|
fn dirMakeOpenPathPosix(
|
||||||
@ -1176,7 +1176,7 @@ fn dirMakeOpenPathWasi(
|
|||||||
_ = dir;
|
_ = dir;
|
||||||
_ = sub_path;
|
_ = sub_path;
|
||||||
_ = mode;
|
_ = mode;
|
||||||
@panic("TODO");
|
@panic("TODO implement dirMakeOpenPathWindows");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dirStat(userdata: ?*anyopaque, dir: Io.Dir) Io.Dir.StatError!Io.Dir.Stat {
|
fn dirStat(userdata: ?*anyopaque, dir: Io.Dir) Io.Dir.StatError!Io.Dir.Stat {
|
||||||
@ -1184,7 +1184,7 @@ fn dirStat(userdata: ?*anyopaque, dir: Io.Dir) Io.Dir.StatError!Io.Dir.Stat {
|
|||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
|
|
||||||
_ = dir;
|
_ = dir;
|
||||||
@panic("TODO");
|
@panic("TODO implement dirStat");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dirStatPathLinux(
|
fn dirStatPathLinux(
|
||||||
@ -1375,8 +1375,48 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
|
|||||||
fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
fn fileStatWindows(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
||||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
_ = file;
|
|
||||||
@panic("TODO");
|
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
|
||||||
|
var info: windows.FILE_ALL_INFORMATION = undefined;
|
||||||
|
const rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
|
||||||
|
switch (rc) {
|
||||||
|
.SUCCESS => {},
|
||||||
|
// Buffer overflow here indicates that there is more information available than was able to be stored in the buffer
|
||||||
|
// size provided. This is treated as success because the type of variable-length information that this would be relevant for
|
||||||
|
// (name, volume name, etc) we don't care about.
|
||||||
|
.BUFFER_OVERFLOW => {},
|
||||||
|
.INVALID_PARAMETER => unreachable,
|
||||||
|
.ACCESS_DENIED => return error.AccessDenied,
|
||||||
|
else => return windows.unexpectedStatus(rc),
|
||||||
|
}
|
||||||
|
return .{
|
||||||
|
.inode = info.InternalInformation.IndexNumber,
|
||||||
|
.size = @as(u64, @bitCast(info.StandardInformation.EndOfFile)),
|
||||||
|
.mode = 0,
|
||||||
|
.kind = if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_REPARSE_POINT != 0) reparse_point: {
|
||||||
|
var tag_info: windows.FILE_ATTRIBUTE_TAG_INFO = undefined;
|
||||||
|
const tag_rc = windows.ntdll.NtQueryInformationFile(file.handle, &io_status_block, &tag_info, @sizeOf(windows.FILE_ATTRIBUTE_TAG_INFO), .FileAttributeTagInformation);
|
||||||
|
switch (tag_rc) {
|
||||||
|
.SUCCESS => {},
|
||||||
|
// INFO_LENGTH_MISMATCH and ACCESS_DENIED are the only documented possible errors
|
||||||
|
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/d295752f-ce89-4b98-8553-266d37c84f0e
|
||||||
|
.INFO_LENGTH_MISMATCH => unreachable,
|
||||||
|
.ACCESS_DENIED => return error.AccessDenied,
|
||||||
|
else => return windows.unexpectedStatus(rc),
|
||||||
|
}
|
||||||
|
if (tag_info.ReparseTag & windows.reparse_tag_name_surrogate_bit != 0) {
|
||||||
|
break :reparse_point .sym_link;
|
||||||
|
}
|
||||||
|
// Unknown reparse point
|
||||||
|
break :reparse_point .unknown;
|
||||||
|
} else if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_DIRECTORY != 0)
|
||||||
|
.directory
|
||||||
|
else
|
||||||
|
.file,
|
||||||
|
.atime = windows.fromSysTime(info.BasicInformation.LastAccessTime),
|
||||||
|
.mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime),
|
||||||
|
.ctime = windows.fromSysTime(info.BasicInformation.ChangeTime),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.Stat {
|
||||||
@ -2490,7 +2530,7 @@ fn fileSeekBy(userdata: ?*anyopaque, file: Io.File, offset: i64) Io.File.SeekErr
|
|||||||
|
|
||||||
_ = file;
|
_ = file;
|
||||||
_ = offset;
|
_ = offset;
|
||||||
@panic("TODO");
|
@panic("TODO implement fileSeekBy");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekError!void {
|
fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekError!void {
|
||||||
@ -2571,7 +2611,7 @@ fn openSelfExe(userdata: ?*anyopaque, flags: Io.File.OpenFlags) Io.File.OpenSelf
|
|||||||
|
|
||||||
return dirOpenFileWindowsInner(t, .{ .handle = cwd_handle }, image_path_name, flags);
|
return dirOpenFileWindowsInner(t, .{ .handle = cwd_handle }, image_path_name, flags);
|
||||||
}
|
}
|
||||||
@panic("TODO");
|
@panic("TODO implement openSelfExe");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fileWritePositional(
|
fn fileWritePositional(
|
||||||
@ -2586,7 +2626,7 @@ fn fileWritePositional(
|
|||||||
_ = file;
|
_ = file;
|
||||||
_ = buffer;
|
_ = buffer;
|
||||||
_ = offset;
|
_ = offset;
|
||||||
@panic("TODO");
|
@panic("TODO implement fileWritePositional");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2596,7 +2636,7 @@ fn fileWriteStreaming(userdata: ?*anyopaque, file: Io.File, buffer: [][]const u8
|
|||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
_ = file;
|
_ = file;
|
||||||
_ = buffer;
|
_ = buffer;
|
||||||
@panic("TODO");
|
@panic("TODO implement fileWriteStreaming");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2922,7 +2962,7 @@ fn netListenUnixWindows(
|
|||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
_ = address;
|
_ = address;
|
||||||
_ = options;
|
_ = options;
|
||||||
@panic("TODO");
|
@panic("TODO implement netListenUnixWindows");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn posixBindUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
|
fn posixBindUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
|
||||||
@ -3122,7 +3162,7 @@ fn netConnectIpPosix(
|
|||||||
options: IpAddress.ConnectOptions,
|
options: IpAddress.ConnectOptions,
|
||||||
) IpAddress.ConnectError!net.Stream {
|
) IpAddress.ConnectError!net.Stream {
|
||||||
if (!have_networking) return error.NetworkDown;
|
if (!have_networking) return error.NetworkDown;
|
||||||
if (options.timeout != .none) @panic("TODO");
|
if (options.timeout != .none) @panic("TODO implement netConnectIpPosix with timeout");
|
||||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||||
const family = posixAddressFamily(address);
|
const family = posixAddressFamily(address);
|
||||||
const socket_fd = try openSocketPosix(t, family, .{
|
const socket_fd = try openSocketPosix(t, family, .{
|
||||||
@ -3146,7 +3186,7 @@ fn netConnectIpWindows(
|
|||||||
options: IpAddress.ConnectOptions,
|
options: IpAddress.ConnectOptions,
|
||||||
) IpAddress.ConnectError!net.Stream {
|
) IpAddress.ConnectError!net.Stream {
|
||||||
if (!have_networking) return error.NetworkDown;
|
if (!have_networking) return error.NetworkDown;
|
||||||
if (options.timeout != .none) @panic("TODO");
|
if (options.timeout != .none) @panic("TODO implement netConnectIpWindows with timeout");
|
||||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||||
const family = posixAddressFamily(address);
|
const family = posixAddressFamily(address);
|
||||||
const socket_handle = try openSocketWsa(t, family, .{
|
const socket_handle = try openSocketWsa(t, family, .{
|
||||||
@ -3220,7 +3260,7 @@ fn netConnectUnixWindows(
|
|||||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
_ = address;
|
_ = address;
|
||||||
@panic("TODO");
|
@panic("TODO implement netConnectUnixWindows");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn netBindIpPosix(
|
fn netBindIpPosix(
|
||||||
@ -3525,7 +3565,7 @@ fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8
|
|||||||
_ = t;
|
_ = t;
|
||||||
_ = handle;
|
_ = handle;
|
||||||
_ = data;
|
_ = data;
|
||||||
@panic("TODO");
|
@panic("TODO implement netReadWindows");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn netSendPosix(
|
fn netSendPosix(
|
||||||
@ -3569,7 +3609,7 @@ fn netSendWindows(
|
|||||||
_ = handle;
|
_ = handle;
|
||||||
_ = messages;
|
_ = messages;
|
||||||
_ = flags;
|
_ = flags;
|
||||||
@panic("TODO");
|
@panic("TODO netSendWindows");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn netSendOne(
|
fn netSendOne(
|
||||||
@ -3872,7 +3912,7 @@ fn netReceiveWindows(
|
|||||||
_ = data_buffer;
|
_ = data_buffer;
|
||||||
_ = flags;
|
_ = flags;
|
||||||
_ = timeout;
|
_ = timeout;
|
||||||
@panic("TODO");
|
@panic("TODO implement netReceiveWindows");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn netWritePosix(
|
fn netWritePosix(
|
||||||
@ -3970,7 +4010,7 @@ fn netWriteWindows(
|
|||||||
_ = header;
|
_ = header;
|
||||||
_ = data;
|
_ = data;
|
||||||
_ = splat;
|
_ = splat;
|
||||||
@panic("TODO");
|
@panic("TODO implement netWriteWindows");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addBuf(v: []posix.iovec_const, i: *@FieldType(posix.msghdr_const, "iovlen"), bytes: []const u8) void {
|
fn addBuf(v: []posix.iovec_const, i: *@FieldType(posix.msghdr_const, "iovlen"), bytes: []const u8) void {
|
||||||
@ -4036,7 +4076,7 @@ fn netInterfaceNameResolve(
|
|||||||
|
|
||||||
if (native_os == .windows) {
|
if (native_os == .windows) {
|
||||||
try t.checkCancel();
|
try t.checkCancel();
|
||||||
@panic("TODO");
|
@panic("TODO implement netInterfaceNameResolve for Windows");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builtin.link_libc) {
|
if (builtin.link_libc) {
|
||||||
@ -4055,15 +4095,15 @@ fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interfa
|
|||||||
|
|
||||||
if (native_os == .linux) {
|
if (native_os == .linux) {
|
||||||
_ = interface;
|
_ = interface;
|
||||||
@panic("TODO");
|
@panic("TODO implement netInterfaceName for linux");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (native_os == .windows) {
|
if (native_os == .windows) {
|
||||||
@panic("TODO");
|
@panic("TODO implement netInterfaceName for windows");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builtin.link_libc) {
|
if (builtin.link_libc) {
|
||||||
@panic("TODO");
|
@panic("TODO implement netInterfaceName for libc");
|
||||||
}
|
}
|
||||||
|
|
||||||
@panic("unimplemented");
|
@panic("unimplemented");
|
||||||
|
|||||||
@ -312,50 +312,6 @@ pub const StatError = posix.FStatError;
|
|||||||
|
|
||||||
/// Returns `Stat` containing basic information about the `File`.
|
/// Returns `Stat` containing basic information about the `File`.
|
||||||
pub fn stat(self: File) StatError!Stat {
|
pub fn stat(self: File) StatError!Stat {
|
||||||
if (builtin.os.tag == .windows) {
|
|
||||||
var io_status_block: windows.IO_STATUS_BLOCK = undefined;
|
|
||||||
var info: windows.FILE_ALL_INFORMATION = undefined;
|
|
||||||
const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
|
|
||||||
switch (rc) {
|
|
||||||
.SUCCESS => {},
|
|
||||||
// Buffer overflow here indicates that there is more information available than was able to be stored in the buffer
|
|
||||||
// size provided. This is treated as success because the type of variable-length information that this would be relevant for
|
|
||||||
// (name, volume name, etc) we don't care about.
|
|
||||||
.BUFFER_OVERFLOW => {},
|
|
||||||
.INVALID_PARAMETER => unreachable,
|
|
||||||
.ACCESS_DENIED => return error.AccessDenied,
|
|
||||||
else => return windows.unexpectedStatus(rc),
|
|
||||||
}
|
|
||||||
return .{
|
|
||||||
.inode = info.InternalInformation.IndexNumber,
|
|
||||||
.size = @as(u64, @bitCast(info.StandardInformation.EndOfFile)),
|
|
||||||
.mode = 0,
|
|
||||||
.kind = if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_REPARSE_POINT != 0) reparse_point: {
|
|
||||||
var tag_info: windows.FILE_ATTRIBUTE_TAG_INFO = undefined;
|
|
||||||
const tag_rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &tag_info, @sizeOf(windows.FILE_ATTRIBUTE_TAG_INFO), .FileAttributeTagInformation);
|
|
||||||
switch (tag_rc) {
|
|
||||||
.SUCCESS => {},
|
|
||||||
// INFO_LENGTH_MISMATCH and ACCESS_DENIED are the only documented possible errors
|
|
||||||
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/d295752f-ce89-4b98-8553-266d37c84f0e
|
|
||||||
.INFO_LENGTH_MISMATCH => unreachable,
|
|
||||||
.ACCESS_DENIED => return error.AccessDenied,
|
|
||||||
else => return windows.unexpectedStatus(rc),
|
|
||||||
}
|
|
||||||
if (tag_info.ReparseTag & windows.reparse_tag_name_surrogate_bit != 0) {
|
|
||||||
break :reparse_point .sym_link;
|
|
||||||
}
|
|
||||||
// Unknown reparse point
|
|
||||||
break :reparse_point .unknown;
|
|
||||||
} else if (info.BasicInformation.FileAttributes & windows.FILE_ATTRIBUTE_DIRECTORY != 0)
|
|
||||||
.directory
|
|
||||||
else
|
|
||||||
.file,
|
|
||||||
.atime = windows.fromSysTime(info.BasicInformation.LastAccessTime),
|
|
||||||
.mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime),
|
|
||||||
.ctime = windows.fromSysTime(info.BasicInformation.ChangeTime),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var threaded: Io.Threaded = .init_single_threaded;
|
var threaded: Io.Threaded = .init_single_threaded;
|
||||||
const io = threaded.io();
|
const io = threaded.io();
|
||||||
return Io.File.stat(.{ .handle = self.handle }, io);
|
return Io.File.stat(.{ .handle = self.handle }, io);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user