260
|
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 |
|
|
8 |
package unix |
|
9 |
|
|
10 |
import ( |
|
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. |
|
18 |
func 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. |
|
49 |
func 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. |
|
59 |
func SysvShmGet(key, size, flag int) (id int, err error) { |
|
60 |
return shmget(key, size, flag) |
|
61 |
} |