1// Copyright 2021 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 (darwin && !ios) || linux 6// +build darwin,!ios linux 7 8package unix 9 10import ( 11 "unsafe" 12 13 "golang.org/x/sys/internal/unsafeheader" 14) 15 16// SysvShmAttach attaches the Sysv shared memory segment associated with the 17// shared memory identifier id. 18func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) { 19 addr, errno := shmat(id, addr, flag) 20 if errno != nil { 21 return nil, errno 22 } 23 24 // Retrieve the size of the shared memory to enable slice creation 25 var info SysvShmDesc 26 27 _, err := SysvShmCtl(id, IPC_STAT, &info) 28 if err != nil { 29 // release the shared memory if we can't find the size 30 31 // ignoring error from shmdt as there's nothing sensible to return here 32 shmdt(addr) 33 return nil, err 34 } 35 36 // Use unsafe to convert addr into a []byte. 37 // TODO: convert to unsafe.Slice once we can assume Go 1.17 38 var b []byte 39 hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b)) 40 hdr.Data = unsafe.Pointer(addr) 41 hdr.Cap = int(info.Segsz) 42 hdr.Len = int(info.Segsz) 43 return b, nil 44} 45 46// SysvShmDetach unmaps the shared memory slice returned from SysvShmAttach. 47// 48// It is not safe to use the slice after calling this function. 49func SysvShmDetach(data []byte) error { 50 if len(data) == 0 { 51 return EINVAL 52 } 53 54 return shmdt(uintptr(unsafe.Pointer(&data[0]))) 55} 56 57// SysvShmGet returns the Sysv shared memory identifier associated with key. 58// If the IPC_CREAT flag is specified a new segment is created. 59func SysvShmGet(key, size, flag int) (id int, err error) { 60 return shmget(key, size, flag) 61} 62