github.com/neonyo/sys@v0.0.0-20230720094341-b1ee14be3ce8/unix/mremap.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build linux || netbsd 6 // +build linux netbsd 7 8 package unix 9 10 import "unsafe" 11 12 type mremapMmapper struct { 13 mmapper 14 mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) 15 } 16 17 var mapper = &mremapMmapper{ 18 mmapper: mmapper{ 19 active: make(map[*byte][]byte), 20 mmap: mmap, 21 munmap: munmap, 22 }, 23 mremap: mremap, 24 } 25 26 func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { 27 if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&mremapFixed != 0 { 28 return nil, EINVAL 29 } 30 31 pOld := &oldData[cap(oldData)-1] 32 m.Lock() 33 defer m.Unlock() 34 bOld := m.active[pOld] 35 if bOld == nil || &bOld[0] != &oldData[0] { 36 return nil, EINVAL 37 } 38 newAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0) 39 if errno != nil { 40 return nil, errno 41 } 42 bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength) 43 pNew := &bNew[cap(bNew)-1] 44 if flags&mremapDontunmap == 0 { 45 delete(m.active, pOld) 46 } 47 m.active[pNew] = bNew 48 return bNew, nil 49 } 50 51 func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { 52 return mapper.Mremap(oldData, newLength, flags) 53 }