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 "unsafe"
11
12// SysvShmAttach attaches the Sysv shared memory segment associated with the
13// shared memory identifier id.
14func SysvShmAttach(id int, addr uintptr, flag int) ([]byte, error) {
15	addr, errno := shmat(id, addr, flag)
16	if errno != nil {
17		return nil, errno
18	}
19
20	// Retrieve the size of the shared memory to enable slice creation
21	var info SysvShmDesc
22
23	_, err := SysvShmCtl(id, IPC_STAT, &info)
24	if err != nil {
25		// release the shared memory if we can't find the size
26
27		// ignoring error from shmdt as there's nothing sensible to return here
28		shmdt(addr)
29		return nil, err
30	}
31
32	// Use unsafe to convert addr into a []byte.
33	b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.Segsz))
34	return b, nil
35}
36
37// SysvShmDetach unmaps the shared memory slice returned from SysvShmAttach.
38//
39// It is not safe to use the slice after calling this function.
40func SysvShmDetach(data []byte) error {
41	if len(data) == 0 {
42		return EINVAL
43	}
44
45	return shmdt(uintptr(unsafe.Pointer(&data[0])))
46}
47
48// SysvShmGet returns the Sysv shared memory identifier associated with key.
49// If the IPC_CREAT flag is specified a new segment is created.
50func SysvShmGet(key, size, flag int) (id int, err error) {
51	return shmget(key, size, flag)
52}