| ... | ... | @@ -7998,7 +7998,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8) |
| 7998 | 7998 | .FAULT => |err| return errnoBug(err), |
| 7999 | 7999 | .AGAIN => return error.WouldBlock, |
| 8000 | 8000 | .BADF => |err| { |
| 8001 | | if (native_os == .wasi) return error.NotOpenForReading; // File operation on directory. |
| 8001 | if (native_os == .wasi) return error.IsDir; // File operation on directory. |
| 8002 | 8002 | return errnoBug(err); // File descriptor used after closed. |
| 8003 | 8003 | }, |
| 8004 | 8004 | .IO => return error.InputOutput, |
| ... | ... | @@ -8089,7 +8089,7 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8 |
| 8089 | 8089 | syscall.finish(); |
| 8090 | 8090 | return nread; |
| 8091 | 8091 | }, |
| 8092 | | .INTR => { |
| 8092 | .INTR, .TIMEDOUT => { |
| 8093 | 8093 | try syscall.checkCancel(); |
| 8094 | 8094 | continue; |
| 8095 | 8095 | }, |
| ... | ... | @@ -8103,7 +8103,6 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8 |
| 8103 | 8103 | .ISDIR => return syscall.fail(error.IsDir), |
| 8104 | 8104 | .NOBUFS => return syscall.fail(error.SystemResources), |
| 8105 | 8105 | .NOMEM => return syscall.fail(error.SystemResources), |
| 8106 | | .TIMEDOUT => return syscall.fail(error.Timeout), |
| 8107 | 8106 | .NXIO => return syscall.fail(error.Unseekable), |
| 8108 | 8107 | .SPIPE => return syscall.fail(error.Unseekable), |
| 8109 | 8108 | .OVERFLOW => return syscall.fail(error.Unseekable), |
| ... | ... | @@ -12588,7 +12587,7 @@ fn statFromPosix(st: *const posix.Stat) File.Stat { |
| 12588 | 12587 | .atime = timestampFromPosix(&atime), |
| 12589 | 12588 | .mtime = timestampFromPosix(&mtime), |
| 12590 | 12589 | .ctime = timestampFromPosix(&ctime), |
| 12591 | | .block_size = st.blksize, |
| 12590 | .block_size = @intCast(st.blksize), |
| 12592 | 12591 | }; |
| 12593 | 12592 | } |
| 12594 | 12593 | |
| ... | ... | @@ -16292,9 +16291,14 @@ fn createFileMap( |
| 16292 | 16291 | .WRITE = protection.write, |
| 16293 | 16292 | .EXEC = protection.execute, |
| 16294 | 16293 | }; |
| 16295 | | const flags: posix.MAP = .{ |
| 16296 | | .TYPE = if (native_os == .linux) .SHARED_VALIDATE else .SHARED, |
| 16297 | | .POPULATE = populate, |
| 16294 | const flags: posix.MAP = switch (native_os) { |
| 16295 | .linux => .{ |
| 16296 | .TYPE = .SHARED_VALIDATE, |
| 16297 | .POPULATE = populate, |
| 16298 | }, |
| 16299 | else => .{ |
| 16300 | .TYPE = .SHARED, |
| 16301 | }, |
| 16298 | 16302 | }; |
| 16299 | 16303 | |
| 16300 | 16304 | const page_align = std.heap.page_size_min; |
| ... | ... | @@ -16348,20 +16352,20 @@ fn createFileMap( |
| 16348 | 16352 | fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { |
| 16349 | 16353 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 16350 | 16354 | const memory = mm.memory; |
| 16351 | | if (mm.section) |section| { |
| 16352 | | if (is_windows) { |
| 16355 | if (mm.section) |section| switch (native_os) { |
| 16356 | .windows => { |
| 16353 | 16357 | const current_process: windows.HANDLE = @ptrFromInt(@as(usize, @bitCast(@as(isize, -1)))); |
| 16354 | 16358 | _ = windows.ntdll.NtUnmapViewOfSection(current_process, memory.ptr); |
| 16355 | 16359 | windows.CloseHandle(section); |
| 16356 | | } else { |
| 16357 | | switch (posix.errno(posix.system.munmap(memory.ptr, memory.len))) { |
| 16358 | | .SUCCESS => {}, |
| 16359 | | else => |e| { |
| 16360 | | if (builtin.mode == .Debug) |
| 16361 | | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, e }); |
| 16362 | | }, |
| 16363 | | } |
| 16364 | | } |
| 16360 | }, |
| 16361 | .wasi => unreachable, |
| 16362 | else => switch (posix.errno(posix.system.munmap(memory.ptr, memory.len))) { |
| 16363 | .SUCCESS => {}, |
| 16364 | else => |e| { |
| 16365 | if (builtin.mode == .Debug) |
| 16366 | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, e }); |
| 16367 | }, |
| 16368 | }, |
| 16365 | 16369 | } else { |
| 16366 | 16370 | const gpa = t.allocator; |
| 16367 | 16371 | gpa.rawFree(memory, .fromByteUnits(std.heap.pageSize()), @returnAddress()); |
| ... | ... | @@ -16372,15 +16376,17 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { |
| 16372 | 16376 | fn fileMemoryMapSetLength( |
| 16373 | 16377 | userdata: ?*anyopaque, |
| 16374 | 16378 | mm: *File.MemoryMap, |
| 16375 | | new_len: usize, |
| 16379 | options: File.MemoryMap.CreateOptions, |
| 16376 | 16380 | ) File.MemoryMap.SetLengthError!void { |
| 16377 | 16381 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 16378 | 16382 | const page_size = std.heap.pageSize(); |
| 16379 | 16383 | const alignment: Alignment = .fromByteUnits(page_size); |
| 16380 | 16384 | const page_align = std.heap.page_size_min; |
| 16385 | const old_memory = mm.memory; |
| 16386 | const new_len = options.len; |
| 16381 | 16387 | |
| 16382 | 16388 | if (mm.section) |section| { |
| 16383 | | if (alignment.forward(new_len) == alignment.forward(mm.memory.len)) { |
| 16389 | if (alignment.forward(new_len) == alignment.forward(old_memory.len)) { |
| 16384 | 16390 | mm.memory.len = new_len; |
| 16385 | 16391 | return; |
| 16386 | 16392 | } |
| ... | ... | @@ -16390,12 +16396,12 @@ fn fileMemoryMapSetLength( |
| 16390 | 16396 | @panic("TODO"); |
| 16391 | 16397 | }, |
| 16392 | 16398 | .wasi => unreachable, |
| 16393 | | else => { |
| 16399 | .linux => { |
| 16394 | 16400 | const flags: posix.MREMAP = .{ .MAYMOVE = true }; |
| 16395 | 16401 | const addr_hint: ?[*]const u8 = null; |
| 16396 | 16402 | const new_memory = while (true) { |
| 16397 | 16403 | const syscall: Syscall = try .start(); |
| 16398 | | const rc = posix.system.mremap(mm.memory.ptr, mm.memory.len, new_len, flags, addr_hint); |
| 16404 | const rc = posix.system.mremap(old_memory.ptr, old_memory.len, new_len, flags, addr_hint); |
| 16399 | 16405 | syscall.finish(); |
| 16400 | 16406 | const err: posix.E = if (builtin.link_libc) e: { |
| 16401 | 16407 | if (rc != std.c.MAP_FAILED) break @as([*]align(page_align) u8, @ptrCast(@alignCast(rc)))[0..new_len]; |
| ... | ... | @@ -16417,6 +16423,30 @@ fn fileMemoryMapSetLength( |
| 16417 | 16423 | }; |
| 16418 | 16424 | mm.memory = new_memory; |
| 16419 | 16425 | }, |
| 16426 | else => { |
| 16427 | switch (posix.errno(posix.system.munmap(old_memory.ptr, old_memory.len))) { |
| 16428 | .SUCCESS => {}, |
| 16429 | else => |e| { |
| 16430 | if (builtin.mode == .Debug) std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ |
| 16431 | old_memory.len, old_memory.ptr, e, |
| 16432 | }); |
| 16433 | // munmap must be infallible, or we cannot design reliable software. |
| 16434 | return error.Unexpected; |
| 16435 | }, |
| 16436 | } |
| 16437 | if (createFileMap(mm.file, options.protection, mm.offset, options.populate, new_len)) |result| { |
| 16438 | mm.* = result; |
| 16439 | return; |
| 16440 | } else |err| switch (err) { |
| 16441 | error.OperationUnsupported, |
| 16442 | error.Unseekable, |
| 16443 | error.SectionOversize, |
| 16444 | error.MappingAlreadyExists, |
| 16445 | error.FileLockConflict, |
| 16446 | => return error.Unexpected, // It worked before on the same open file. |
| 16447 | else => |e| return e, |
| 16448 | } |
| 16449 | }, |
| 16420 | 16450 | } |
| 16421 | 16451 | } else { |
| 16422 | 16452 | const gpa = t.allocator; |