1
2
3
4
5
6
7 package mmap
8
9 import (
10 "fmt"
11 "io/fs"
12 "os"
13 "syscall"
14 )
15
16 func mmapFile(f *os.File) (Data, error) {
17 st, err := f.Stat()
18 if err != nil {
19 return Data{}, err
20 }
21 size := st.Size()
22 pagesize := int64(os.Getpagesize())
23 if int64(int(size+(pagesize-1))) != size+(pagesize-1) {
24 return Data{}, fmt.Errorf("%s: too large for mmap", f.Name())
25 }
26 n := int(size)
27 if n == 0 {
28 return Data{f, nil}, nil
29 }
30 mmapLength := int(((size + pagesize - 1) / pagesize) * pagesize)
31 data, err := syscall.Mmap(int(f.Fd()), 0, mmapLength, syscall.PROT_READ, syscall.MAP_SHARED)
32 if err != nil {
33 return Data{}, &fs.PathError{Op: "mmap", Path: f.Name(), Err: err}
34 }
35 return Data{f, data[:n]}, nil
36 }
37
View as plain text