1
2
3
4
5 package mmap
6
7 import (
8 "fmt"
9 "os"
10 "syscall"
11 "unsafe"
12
13 "golang.org/x/sys/windows"
14 )
15
16 func mmapFile(f *os.File) (*Data, error) {
17 st, err := f.Stat()
18 if err != nil {
19 return nil, err
20 }
21 size := st.Size()
22 if size == 0 {
23 return &Data{f, nil, nil}, nil
24 }
25
26
27 h, err := windows.CreateFileMapping(windows.Handle(f.Fd()), nil, syscall.PAGE_READWRITE, 0, 0, nil)
28 if err != nil {
29 return nil, fmt.Errorf("CreateFileMapping %s: %w", f.Name(), err)
30 }
31
32
33 addr, err := windows.MapViewOfFile(h, syscall.FILE_MAP_READ|syscall.FILE_MAP_WRITE, 0, 0, 0)
34 if err != nil {
35 return nil, fmt.Errorf("MapViewOfFile %s: %w", f.Name(), err)
36 }
37
38
39
40
41 return &Data{f, unsafe.Slice((*byte)(unsafe.Pointer(addr)), size), h}, nil
42 }
43
44 func munmapFile(d *Data) error {
45 err := windows.UnmapViewOfFile(uintptr(unsafe.Pointer(&d.Data[0])))
46 x, ok := d.Windows.(windows.Handle)
47 if ok {
48 windows.CloseHandle(x)
49 }
50 d.f.Close()
51 return err
52 }
53
View as plain text