mmap
: File Mappings, Basics¶
Reading A File, Not Using File I/O¶
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
if (argc != 2) {
cerr << "Usage: " << argv[0] << " FILENAME\n";
return 1;
}
const char* filename = argv[1];
int fd = open(filename, O_RDONLY); // <-- O_RDONLY
if (fd == -1) {
perror("open");
return 1;
}
struct stat stat;
int error = fstat(fd, &stat); // <-- determine file size (stat.st_size)
if (error) {
perror("fstat");
return 1;
}
void* content = mmap(
NULL, // <-- (addr) let kernel choose address
stat.st_size, // <-- (length) extending from offset (0)
PROT_READ, // <-- (prot) memory access protection
MAP_PRIVATE, // <-- (flags) copy-on-write (read-only anyway)
fd, // <-- (fd) file mapping (as opposed to "anonymous")
0 // <-- (offset) offset; map from beginning of file
);
if (content == MAP_FAILED) {
perror("mmap");
return 1;
}
close(fd); // <-- abandon; mapping keeps a reference
write(STDOUT_FILENO, content, stat.st_size);
munmap(content, stat.st_size); // <-- (done anyway at exit)
return 0;
}
Open file
O_RDONLY
Create mapping
PROT_READ
: memory protection read onlyMAP_PRIVATE
: private mappingpointless as we don’t write to it, but we have to say something
Copy on write otherwise ⟶ private to each address space (later)
offset
andlength
span entire fileoffset
must start at a page boundary. 4096 on many systems; determined exactly bysysconf(_SC_PAGE_SIZE)
$ echo 0123456789 > /tmp/a-file
$ ./file-mapping-ro /tmp/a-file
0123456789
Read-Only, Basic¶
file ro
map ro, private
error MAP_FAILED
Wait, /proc/PID/maps¶
Error Cases¶
file ro, map rw
file ro, map ro, write byte -> segfault
file rw, map ro, write byte -> segfault
read beyond eof
offset not multiple of pagae size