| author | |
| committer | |
| log | de53537f10e22cc003cfbc77468349b758470f24 |
| tree | 8d8685fa2ec6d44ea0b73be7a719da990a7f5663 |
| parent | bd0b51477a6cb0dc7ea7739f61a70110d39ba601 |
5 files changed, 40 insertions(+), 7 deletions(-)
lib/std/fs/file.zig+1-1| ... | ... | @@ -102,7 +102,7 @@ pub const File = struct { |
| 102 | 102 | pub const SetEndPosError = os.TruncateError; |
| 103 | 103 | |
| 104 | 104 | /// Shrinks or expands the file. |
| 105 | /// The file offset after this call is undefined. | |
| 105 | /// The file offset after this call is left unchanged. | |
| 106 | 106 | pub fn setEndPos(self: File, length: u64) SetEndPosError!void { |
| 107 | 107 | try os.ftruncate(self.handle, length); |
| 108 | 108 | } |
lib/std/io/test.zig+8-2| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("../std.zig"); | |
| 1 | const std = @import("std"); | |
| 2 | const builtin = std.builtin; | |
| 3 | 3 | const io = std.io; |
| 4 | 4 | const meta = std.meta; |
| 5 | 5 | const trait = std.trait; |
| ... | ... | @@ -133,13 +133,19 @@ test "setEndPos" { |
| 133 | 133 | fs.cwd().deleteFile(tmp_file_name) catch {}; |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | // Verify that the file size changes and the file offset is not moved | |
| 136 | 137 | std.testing.expect((try file.getEndPos()) == 0); |
| 138 | std.testing.expect((try file.getPos()) == 0); | |
| 137 | 139 | try file.setEndPos(8192); |
| 138 | 140 | std.testing.expect((try file.getEndPos()) == 8192); |
| 141 | std.testing.expect((try file.getPos()) == 0); | |
| 142 | try file.seekTo(100); | |
| 139 | 143 | try file.setEndPos(4096); |
| 140 | 144 | std.testing.expect((try file.getEndPos()) == 4096); |
| 145 | std.testing.expect((try file.getPos()) == 100); | |
| 141 | 146 | try file.setEndPos(0); |
| 142 | 147 | std.testing.expect((try file.getEndPos()) == 0); |
| 148 | std.testing.expect((try file.getPos()) == 100); | |
| 143 | 149 | } |
| 144 | 150 | |
| 145 | 151 | test "updateTimes" { |
lib/std/os.zig+20-4| ... | ... | @@ -447,10 +447,25 @@ pub const TruncateError = error{ |
| 447 | 447 | |
| 448 | 448 | pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 449 | 449 | 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 | ); | |
| 451 | 462 | |
| 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 | } | |
| 454 | 469 | |
| 455 | 470 | return; |
| 456 | 471 | } |
| ... | ... | @@ -471,7 +486,8 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 471 | 486 | EIO => return error.InputOutput, |
| 472 | 487 | EPERM => return error.CannotTruncate, |
| 473 | 488 | ETXTBSY => return error.FileBusy, |
| 474 | EBADF, EINVAL => unreachable, | |
| 489 | EBADF => unreachable, // Handle not open for writing | |
| 490 | EINVAL => unreachable, // Handle not open for writing | |
| 475 | 491 | else => |err| return unexpectedErrno(err), |
| 476 | 492 | } |
| 477 | 493 | } |
lib/std/os/windows/bits.zig+4| ... | ... | @@ -225,6 +225,10 @@ pub const FILE_POSITION_INFORMATION = extern struct { |
| 225 | 225 | CurrentByteOffset: LARGE_INTEGER, |
| 226 | 226 | }; |
| 227 | 227 | |
| 228 | pub const FILE_END_OF_FILE_INFORMATION = extern struct { | |
| 229 | EndOfFile: LARGE_INTEGER, | |
| 230 | }; | |
| 231 | ||
| 228 | 232 | pub const FILE_MODE_INFORMATION = extern struct { |
| 229 | 233 | Mode: ULONG, |
| 230 | 234 | }; |
lib/std/os/windows/ntdll.zig+7| ... | ... | @@ -16,6 +16,13 @@ pub extern "NtDll" fn NtQueryInformationFile( |
| 16 | 16 | Length: ULONG, |
| 17 | 17 | FileInformationClass: FILE_INFORMATION_CLASS, |
| 18 | 18 | ) callconv(.Stdcall) NTSTATUS; |
| 19 | pub 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; | |
| 19 | 26 | |
| 20 | 27 | pub extern "NtDll" fn NtQueryAttributesFile( |
| 21 | 28 | ObjectAttributes: *OBJECT_ATTRIBUTES, |