authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-03-12 22:46:12+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-03-13 08:45:37+01:00
logde53537f10e22cc003cfbc77468349b758470f24
tree8d8685fa2ec6d44ea0b73be7a719da990a7f5663
parentbd0b51477a6cb0dc7ea7739f61a70110d39ba601

Add NtDll-based ftruncate implementation


5 files changed, 40 insertions(+), 7 deletions(-)

lib/std/fs/file.zig+1-1
......@@ -102,7 +102,7 @@ pub const File = struct {
102102 pub const SetEndPosError = os.TruncateError;
103103
104104 /// Shrinks or expands the file.
105 /// The file offset after this call is undefined.
105 /// The file offset after this call is left unchanged.
106106 pub fn setEndPos(self: File, length: u64) SetEndPosError!void {
107107 try os.ftruncate(self.handle, length);
108108 }
lib/std/io/test.zig+8-2
......@@ -1,5 +1,5 @@
1const builtin = @import("builtin");
2const std = @import("../std.zig");
1const std = @import("std");
2const builtin = std.builtin;
33const io = std.io;
44const meta = std.meta;
55const trait = std.trait;
......@@ -133,13 +133,19 @@ test "setEndPos" {
133133 fs.cwd().deleteFile(tmp_file_name) catch {};
134134 }
135135
136 // Verify that the file size changes and the file offset is not moved
136137 std.testing.expect((try file.getEndPos()) == 0);
138 std.testing.expect((try file.getPos()) == 0);
137139 try file.setEndPos(8192);
138140 std.testing.expect((try file.getEndPos()) == 8192);
141 std.testing.expect((try file.getPos()) == 0);
142 try file.seekTo(100);
139143 try file.setEndPos(4096);
140144 std.testing.expect((try file.getEndPos()) == 4096);
145 std.testing.expect((try file.getPos()) == 100);
141146 try file.setEndPos(0);
142147 std.testing.expect((try file.getEndPos()) == 0);
148 std.testing.expect((try file.getPos()) == 100);
143149}
144150
145151test "updateTimes" {
lib/std/os.zig+20-4
......@@ -447,10 +447,25 @@ pub const TruncateError = error{
447447
448448pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
449449 if (std.Target.current.os.tag == .windows) {
450 try windows.SetFilePointerEx_BEGIN(fd, length);
450 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
451 var eof_info = windows.FILE_END_OF_FILE_INFORMATION{
452 .EndOfFile = @bitCast(windows.LARGE_INTEGER, length),
453 };
454
455 const rc = windows.ntdll.NtSetInformationFile(
456 fd,
457 &io_status_block,
458 &eof_info,
459 @sizeOf(windows.FILE_END_OF_FILE_INFORMATION),
460 .FileEndOfFileInformation,
461 );
451462
452 if (windows.kernel32.SetEndOfFile(fd) == 0)
453 return TruncateError.Unexpected;
463 switch (rc) {
464 .SUCCESS => {},
465 .INVALID_HANDLE => unreachable, // Handle not open for writing
466 .ACCESS_DENIED => return error.CannotTruncate,
467 else => return windows.unexpectedStatus(rc),
468 }
454469
455470 return;
456471 }
......@@ -471,7 +486,8 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
471486 EIO => return error.InputOutput,
472487 EPERM => return error.CannotTruncate,
473488 ETXTBSY => return error.FileBusy,
474 EBADF, EINVAL => unreachable,
489 EBADF => unreachable, // Handle not open for writing
490 EINVAL => unreachable, // Handle not open for writing
475491 else => |err| return unexpectedErrno(err),
476492 }
477493 }
lib/std/os/windows/bits.zig+4
......@@ -225,6 +225,10 @@ pub const FILE_POSITION_INFORMATION = extern struct {
225225 CurrentByteOffset: LARGE_INTEGER,
226226};
227227
228pub const FILE_END_OF_FILE_INFORMATION = extern struct {
229 EndOfFile: LARGE_INTEGER,
230};
231
228232pub const FILE_MODE_INFORMATION = extern struct {
229233 Mode: ULONG,
230234};
lib/std/os/windows/ntdll.zig+7
......@@ -16,6 +16,13 @@ pub extern "NtDll" fn NtQueryInformationFile(
1616 Length: ULONG,
1717 FileInformationClass: FILE_INFORMATION_CLASS,
1818) callconv(.Stdcall) NTSTATUS;
19pub extern "NtDll" fn NtSetInformationFile(
20 FileHandle: HANDLE,
21 IoStatusBlock: *IO_STATUS_BLOCK,
22 FileInformation: PVOID,
23 Length: ULONG,
24 FileInformationClass: FILE_INFORMATION_CLASS,
25) callconv(.Stdcall) NTSTATUS;
1926
2027pub extern "NtDll" fn NtQueryAttributesFile(
2128 ObjectAttributes: *OBJECT_ATTRIBUTES,