Memory mapping adds a file-backed region to a process's virtual address space. Access can fault pages in on demand rather than copying the whole file up front. This does not make every workload faster: page-fault cost, access pattern, file changes and storage policy still matter. The lesson grades correctness, not a claim about hardware speed.
Map pages, expose bytes
mmap requires an aligned file offset. A caller's requested slice need not be
aligned. Compute the preceding page boundary, retain the difference as delta,
and map delta + requested_length bytes. The public span begins at base+delta,
but ownership remains the original base and mapping length.
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
int main() {
char name[]="/tmp/unix-check-XXXXXX"; int fd=::mkstemp(name); assert(fd>=0); ::unlink(name);
assert(::write(fd,"abcdef",6)==6); assert(::lseek(fd,0,SEEK_SET)==0);
auto* p=static_cast<char*>(::mmap(nullptr,6,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0));assert(p!=MAP_FAILED);
p[0]='X';char file=0;assert(::pread(fd,&file,1,0)==1);std::printf("%c %c\n",p[0],file);assert(::munmap(p,6)==0);::close(fd);
}The build queries _SC_PAGESIZE at runtime. Validate the requested range with fstat and subtraction, check length addition, and keep empty ranges separate: passing length zero to mmap is not how to represent an empty C++ view.
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <unistd.h>
int main() {
auto page=::sysconf(_SC_PAGESIZE);assert(page>0);long offset=page+7,length=5;
long aligned=offset/page*page,delta=offset-aligned;std::printf("%ld %ld\n",delta,length+delta);
}Ownership and borrowed spans
A successful mapping has a lifetime separate from the descriptor used to create it. Closing that descriptor is allowed. Destroying or resetting the mapping invalidates every borrowed span, so never return a view into a temporary owner. Move construction empties the source; move assignment first releases old state. munmap uses the original base, not the adjusted span pointer.
In this task .bytes() is read-only and the mapping is MAP_PRIVATE. The public
view exposes just the requested range, although the kernel manages whole pages.
The reference keeps the map base and the view offset as separate fields so
cleanup does not accidentally use the wrong address.
Visibility, copying and faults
MAP_PRIVATE uses copy-on-write for stores into a writable private mapping. Those private stores do not update the file. MAP_SHARED exposes shared file-backed pages; storage synchronization and inter-thread synchronization remain separate requirements. Private mapping alone is not a guarantee of an immutable snapshot if someone changes the underlying file.
A file descriptor can remain valid while the backing file is truncated. Access beyond the new backing range can deliver SIGBUS even though the virtual address was mapped earlier. The build explicitly requires the caller to keep file length stable; it does not deliberately fault the learner's process to demonstrate that case. A signal handler is not a substitute for a clear lifetime contract.
Before the fill, derive the map base, public-view pointer and unmap range for an unaligned slice crossing a page boundary. Tests compare bytes against a normal file read and keep a moved mapping alive after the file descriptor is closed. Continue with signals and events.