authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-10-09 22:29:11-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-10-09 23:35:36-07:00
log55d429e0ba37c0609f8c713952113078a11bb593
tree20aa4b61135986bef3d74458acecd35c529f2af5
parent1c6a9d75df27564387764ee178d48666156039d4

Threaded.fileStatWindows: disambiguate between files and named pipes


2 files changed, 41 insertions(+), 2 deletions(-)

lib/std/Io/Threaded.zig+4-2
......@@ -4221,8 +4221,10 @@ fn fileStatWindows(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
42214221 break :reparse_point .unknown;
42224222 } else if (info.BasicInformation.FileAttributes.DIRECTORY)
42234223 .directory
4224 else
4225 .file,
4224 else switch (try windowsGetFileDevice(file)) {
4225 .NAMED_PIPE => .named_pipe,
4226 else => .file,
4227 },
42264228 .atime = windows.fromSysTime(info.BasicInformation.LastAccessTime),
42274229 .mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime),
42284230 .ctime = windows.fromSysTime(info.BasicInformation.ChangeTime),
lib/std/fs/test.zig+37
......@@ -298,6 +298,43 @@ test "File.stat on a File that is a symlink returns Kind.sym_link" {
298298 }.impl);
299299}
300300
301test "File.stat on a File that is a named pipe returns Kind.named_pipe" {
302 // Creating pipes is Io.Threaded-specific
303 var threaded: std.Io.Threaded = .init(std.testing.allocator, .{
304 .argv0 = .empty,
305 .environ = .empty,
306 });
307 defer threaded.deinit();
308 const io = threaded.io();
309
310 var read_end: Io.File = undefined;
311 var write_end: Io.File = undefined;
312 switch (builtin.target.os.tag) {
313 .wasi => return error.SkipZigTest,
314 .windows => {
315 const pipe = try threaded.windowsCreatePipe(.{
316 .server = .{ .mode = .{ .IO = .SYNCHRONOUS_NONALERT } },
317 .client = .{ .mode = .{ .IO = .SYNCHRONOUS_NONALERT } },
318 .inbound = true,
319 });
320 read_end = .{ .handle = pipe[0], .flags = .{ .nonblocking = false } };
321 write_end = .{ .handle = pipe[1], .flags = .{ .nonblocking = false } };
322 },
323 else => {
324 const pipe = try std.Io.Threaded.pipe2(.{ .CLOEXEC = true });
325 read_end = .{ .handle = pipe[0], .flags = .{ .nonblocking = false } };
326 write_end = .{ .handle = pipe[1], .flags = .{ .nonblocking = false } };
327 },
328 }
329 defer {
330 read_end.close(io);
331 write_end.close(io);
332 }
333
334 try expectEqual(.named_pipe, (try read_end.stat(io)).kind);
335 try expectEqual(.named_pipe, (try write_end.stat(io)).kind);
336}
337
301338test "Dir.statFile on a symlink" {
302339 const io = testing.io;
303340