go/mmap/mmap.go
2024-11-11 06:36:55 +01:00

60 lines
1.2 KiB
Go

package mmap
import (
"os"
"syscall"
"unsafe"
)
const (
PROT_READ = syscall.PROT_READ
PROT_WRITE = syscall.PROT_WRITE
)
// Mmap creates a memory map of the given file. The flags argument should be a
// combination of PROT_READ and PROT_WRITE. The size of the map will be the
// file's size.
func Map(f *os.File, flags int) ([]byte, error) {
fi, err := f.Stat()
if err != nil {
return nil, err
}
size := fi.Size()
addr, _, errno := syscall.Syscall6(
syscall.SYS_MMAP,
0, // addr: 0 => allow kernel to choose
uintptr(size),
uintptr(flags),
uintptr(syscall.MAP_SHARED),
f.Fd(),
0) // offset: 0 => start of file
if errno != 0 {
return nil, syscall.Errno(errno)
}
return unsafe.Slice((*byte)(unsafe.Pointer(addr)), size), nil
}
// Munmap unmaps the data obtained by Map.
func Unmap(data []byte) error {
_, _, errno := syscall.Syscall(
syscall.SYS_MUNMAP,
uintptr(unsafe.Pointer(&data[:1][0])),
uintptr(cap(data)),
0)
if errno != 0 {
return syscall.Errno(errno)
}
return nil
}
func Sync(b []byte) (err error) {
_p0 := unsafe.Pointer(&b[0])
_, _, errno := syscall.Syscall(syscall.SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(syscall.MS_SYNC))
if errno != 0 {
err = syscall.Errno(errno)
}
return
}