golang.org/x/sys@v0.20.1-0.20240517151509-673e0f94c16d/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 7 package unix 8 9 import "unsafe" 10 11 type mremapMmapper struct { 12 mmapper 13 mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) 14 } 15 16 var mapper = &mremapMmapper{ 17 mmapper: mmapper{ 18 active: make(map[*byte][]byte), 19 mmap: mmap, 20 munmap: munmap, 21 }, 22 mremap: mremap, 23 } 24 25 func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { 26 if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&mremapFixed != 0 { 27 return nil, EINVAL 28 } 29 30 pOld := &oldData[cap(oldData)-1] 31 m.Lock() 32 defer m.Unlock() 33 bOld := m.active[pOld] 34 if bOld == nil || &bOld[0] != &oldData[0] { 35 return nil, EINVAL 36 } 37 newAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0) 38 if errno != nil { 39 return nil, errno 40 } 41 bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength) 42 pNew := &bNew[cap(bNew)-1] 43 if flags&mremapDontunmap == 0 { 44 delete(m.active, pOld) 45 } 46 m.active[pNew] = bNew 47 return bNew, nil 48 } 49 50 func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { 51 return mapper.Mremap(oldData, newLength, flags) 52 }