|
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 } |