60 lines
1.2 KiB
Go
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
|
||
|
}
|