| ... | @@ -1037,11 +1037,15 @@ pub const TruncateError = error{ | ... | @@ -1037,11 +1037,15 @@ pub const TruncateError = error{ |
| 1037 | PermissionDenied, | 1037 | PermissionDenied, |
| 1038 | } || UnexpectedError; | 1038 | } || UnexpectedError; |
| 1039 | | 1039 | |
| | 1040 | /// Length must be positive when treated as an i64. |
| 1040 | pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { | 1041 | pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| | 1042 | const signed_len: i64 = @bitCast(length); |
| | 1043 | if (signed_len < 0) return error.FileTooBig; // avoid ambiguous EINVAL errors |
| | 1044 | |
| 1041 | if (native_os == .windows) { | 1045 | if (native_os == .windows) { |
| 1042 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; | 1046 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; |
| 1043 | var eof_info = windows.FILE_END_OF_FILE_INFORMATION{ | 1047 | var eof_info = windows.FILE_END_OF_FILE_INFORMATION{ |
| 1044 | .EndOfFile = @bitCast(length), | 1048 | .EndOfFile = signed_len, |
| 1045 | }; | 1049 | }; |
| 1046 | | 1050 | |
| 1047 | const rc = windows.ntdll.NtSetInformationFile( | 1051 | const rc = windows.ntdll.NtSetInformationFile( |
| ... | @@ -1057,6 +1061,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { | ... | @@ -1057,6 +1061,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 1057 | .INVALID_HANDLE => unreachable, // Handle not open for writing | 1061 | .INVALID_HANDLE => unreachable, // Handle not open for writing |
| 1058 | .ACCESS_DENIED => return error.AccessDenied, | 1062 | .ACCESS_DENIED => return error.AccessDenied, |
| 1059 | .USER_MAPPED_FILE => return error.AccessDenied, | 1063 | .USER_MAPPED_FILE => return error.AccessDenied, |
| | 1064 | .INVALID_PARAMETER => return error.FileTooBig, |
| 1060 | else => return windows.unexpectedStatus(rc), | 1065 | else => return windows.unexpectedStatus(rc), |
| 1061 | } | 1066 | } |
| 1062 | } | 1067 | } |
| ... | @@ -1069,7 +1074,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { | ... | @@ -1069,7 +1074,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 1069 | .PERM => return error.PermissionDenied, | 1074 | .PERM => return error.PermissionDenied, |
| 1070 | .TXTBSY => return error.FileBusy, | 1075 | .TXTBSY => return error.FileBusy, |
| 1071 | .BADF => unreachable, // Handle not open for writing | 1076 | .BADF => unreachable, // Handle not open for writing |
| 1072 | .INVAL => unreachable, // Handle not open for writing | 1077 | .INVAL => unreachable, // Handle not open for writing, negative length, or non-resizable handle |
| 1073 | .NOTCAPABLE => return error.AccessDenied, | 1078 | .NOTCAPABLE => return error.AccessDenied, |
| 1074 | else => |err| return unexpectedErrno(err), | 1079 | else => |err| return unexpectedErrno(err), |
| 1075 | } | 1080 | } |
| ... | @@ -1077,7 +1082,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { | ... | @@ -1077,7 +1082,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 1077 | | 1082 | |
| 1078 | const ftruncate_sym = if (lfs64_abi) system.ftruncate64 else system.ftruncate; | 1083 | const ftruncate_sym = if (lfs64_abi) system.ftruncate64 else system.ftruncate; |
| 1079 | while (true) { | 1084 | while (true) { |
| 1080 | switch (errno(ftruncate_sym(fd, @bitCast(length)))) { | 1085 | switch (errno(ftruncate_sym(fd, signed_len))) { |
| 1081 | .SUCCESS => return, | 1086 | .SUCCESS => return, |
| 1082 | .INTR => continue, | 1087 | .INTR => continue, |
| 1083 | .FBIG => return error.FileTooBig, | 1088 | .FBIG => return error.FileTooBig, |
| ... | @@ -1085,7 +1090,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { | ... | @@ -1085,7 +1090,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void { |
| 1085 | .PERM => return error.PermissionDenied, | 1090 | .PERM => return error.PermissionDenied, |
| 1086 | .TXTBSY => return error.FileBusy, | 1091 | .TXTBSY => return error.FileBusy, |
| 1087 | .BADF => unreachable, // Handle not open for writing | 1092 | .BADF => unreachable, // Handle not open for writing |
| 1088 | .INVAL => unreachable, // Handle not open for writing | 1093 | .INVAL => unreachable, // Handle not open for writing, negative length, or non-resizable handle |
| 1089 | else => |err| return unexpectedErrno(err), | 1094 | else => |err| return unexpectedErrno(err), |
| 1090 | } | 1095 | } |
| 1091 | } | 1096 | } |