feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.createFileMap
fn createFileMap(
file: File,
protection: std.process.MemoryProtection,
offset: u64,
populate: bool,
len: usize,
) CreateFileMapError!File.MemoryMap
File
Code
fn createFileMap(
file: File,
protection: std.process.MemoryProtection,
offset: u64,
populate: bool,
len: usize,
) CreateFileMapError!File.MemoryMap {
if (is_windows) {
try Thread.checkCancel();
var section = windows.INVALID_HANDLE_VALUE;
const section_size: windows.LARGE_INTEGER = @intCast(len);
const page = windows.PAGE.fromProtection(protection) orelse return error.AccessDenied;
switch (windows.ntdll.NtCreateSection(
§ion,
.{
.SPECIFIC = .{ .SECTION = .{
.QUERY = true,
.MAP_WRITE = protection.write,
.MAP_READ = protection.read,
.MAP_EXECUTE = protection.execute,
.EXTEND_SIZE = true,
} },
.STANDARD = .{ .RIGHTS = .REQUIRED },
},
null,
§ion_size,
page,
.{ .COMMIT = populate },
file.handle,
)) {
.SUCCESS => {},
.FILE_LOCK_CONFLICT => return error.LockViolation,
.INVALID_FILE_FOR_SECTION => return error.OperationUnsupported,
.ACCESS_DENIED => return error.AccessDenied,
.SECTION_TOO_BIG => return error.SectionOversize,
else => |status| return windows.unexpectedStatus(status),
}
var contents_ptr: ?[*]align(std.heap.page_size_min) u8 = null;
var contents_len = len;
switch (windows.ntdll.NtMapViewOfSection(
section,
windows.current_process,
@ptrCast(&contents_ptr),
null,
0,
null,
&contents_len,
.Unmap,
.{},
page,
)) {
.SUCCESS => {},
.CONFLICTING_ADDRESSES => return error.MappingAlreadyExists,
.SECTION_PROTECTION => return error.PermissionDenied,
.ACCESS_DENIED => return error.AccessDenied,
.INVALID_VIEW_SIZE => |status| return windows.statusBug(status),
else => |status| return windows.unexpectedStatus(status),
}
if (builtin.mode == .debug) {
const page_size = std.heap.pageSize();
const alignment: Alignment = .fromByteUnits(page_size);
assert(contents_len == alignment.forward(len));
}
return .{
.file = file,
.offset = offset,
.memory = contents_ptr.?[0..len],
.section = section,
};
} else if (have_mmap) {
const prot: posix.PROT = .{
.READ = protection.read,
.WRITE = protection.write,
.EXEC = protection.execute,
};
const flags: posix.MAP = switch (native_os) {
.linux => .{
.TYPE = .SHARED_VALIDATE,
.POPULATE = populate,
},
else => .{
.TYPE = .SHARED,
},
};
const page_align = std.heap.page_size_min;
const contents = while (true) {
const syscall: Syscall = try .start();
const casted_offset = std.math.cast(i64, offset) orelse return error.Unseekable;
const rc = mmap_sym(null, len, prot, flags, file.handle, casted_offset);
syscall.finish();
const err: posix.E = if (builtin.link_libc) e: {
if (rc != std.c.MAP_FAILED) {
break @as([*]align(page_align) u8, @ptrCast(@alignCast(rc)))[0..len];
}
break :e @fromBackingInt(@intCast(posix.system._errno().*));
} else e: {
const err = posix.errno(rc);
if (err == .SUCCESS) {
break @as([*]align(page_align) u8, @ptrFromInt(rc))[0..len];
}
break :e err;
};
switch (err) {
.SUCCESS => unreachable,
.INTR => continue,
.ACCES => return error.AccessDenied,
.AGAIN => return error.LockedMemoryLimitExceeded,
.EXIST => return error.MappingAlreadyExists,
.MFILE => return error.ProcessFdQuotaExceeded,
.NFILE => return error.SystemFdQuotaExceeded,
.NODEV => return error.OperationUnsupported,
.NOMEM => return error.OutOfMemory,
.PERM => return error.PermissionDenied,
.TXTBSY => return error.FileBusy,
.OVERFLOW => return error.Unseekable,
.BADF => return errnoBug(err),
.INVAL => return errnoBug(err),
.OPNOTSUPP => return errnoBug(err),
else => return posix.unexpectedErrno(err),
}
};
return .{
.file = file,
.offset = offset,
.memory = contents,
.section = {},
};
}
return error.OperationUnsupported;
}