提交 | 用户 | age
|
a0123f
|
1 |
// Copyright 2016 Tom Thorogood. All rights reserved. |
Z |
2 |
// Use of this source code is governed by a |
|
3 |
// Modified BSD License license that can be found in |
|
4 |
// the LICENSE file. |
|
5 |
|
|
6 |
// Package shm provides functions to open and unlink shared memory. |
|
7 |
package shm |
|
8 |
|
|
9 |
import ( |
|
10 |
"os" |
|
11 |
|
|
12 |
"golang.org/x/sys/unix" |
|
13 |
) |
|
14 |
|
|
15 |
const devShm = "/dev/shm/" |
|
16 |
|
|
17 |
// Taken from shm_open(3): |
|
18 |
// shm_open() creates and opens a new, or opens an existing, POSIX shared |
|
19 |
// memory object. A POSIX shared memory object is in effect a handle which |
|
20 |
// can be used by unrelated processes to mmap(2) the same region of shared |
|
21 |
// memory. The shm_unlink() function performs the converse operation, |
|
22 |
// removing an object previously created by shm_open(). |
|
23 |
// |
|
24 |
// The operation of shm_open() is analogous to that of open(2). name |
|
25 |
// specifies the shared memory object to be created or opened. For |
|
26 |
// portable use, a shared memory object should be identified by a name of |
|
27 |
// the form /somename; that is, a null-terminated string of up to NAME_MAX |
|
28 |
// (i.e., 255) characters consisting of an initial slash, followed by one |
|
29 |
// or more characters, none of which are slashes. |
|
30 |
func Open(name string, flag int, perm os.FileMode) (*os.File, error) { |
|
31 |
fileName := name |
|
32 |
|
|
33 |
for len(name) != 0 && name[0] == '/' { |
|
34 |
name = name[1:] |
|
35 |
} |
|
36 |
|
|
37 |
if len(name) == 0 { |
|
38 |
return nil, &os.PathError{Op: "open", Path: fileName, Err: unix.EINVAL} |
|
39 |
} |
|
40 |
|
|
41 |
o := uint32(perm.Perm()) |
|
42 |
if perm&os.ModeSetuid != 0 { |
|
43 |
o |= unix.S_ISUID |
|
44 |
} |
|
45 |
if perm&os.ModeSetgid != 0 { |
|
46 |
o |= unix.S_ISGID |
|
47 |
} |
|
48 |
if perm&os.ModeSticky != 0 { |
|
49 |
o |= unix.S_ISVTX |
|
50 |
} |
|
51 |
|
|
52 |
fd, err := unix.Open(devShm+name, flag|unix.O_CLOEXEC, o) |
|
53 |
if err != nil { |
|
54 |
return nil, &os.PathError{Op: "open", Path: fileName, Err: err} |
|
55 |
} |
|
56 |
|
|
57 |
return os.NewFile(uintptr(fd), fileName), nil |
|
58 |
} |
|
59 |
|
|
60 |
// Taken from shm_unlink(3): |
|
61 |
// The operation of shm_unlink() is analogous to unlink(2): it removes a |
|
62 |
// shared memory object name, and, once all processes have unmapped the |
|
63 |
// object, de-allocates and destroys the contents of the associated memory |
|
64 |
// region. After a successful shm_unlink(), attempts to shm_open() an |
|
65 |
// object with the same name will fail (unless O_CREAT was specified, in |
|
66 |
// which case a new, distinct object is created). |
|
67 |
func Unlink(name string) error { |
|
68 |
fileName := name |
|
69 |
|
|
70 |
for len(name) != 0 && name[0] == '/' { |
|
71 |
name = name[1:] |
|
72 |
} |
|
73 |
|
|
74 |
if len(name) == 0 { |
|
75 |
return &os.PathError{Op: "unlink", Path: fileName, Err: unix.EINVAL} |
|
76 |
} |
|
77 |
|
|
78 |
if err := unix.Unlink(devShm + name); err != nil { |
|
79 |
return &os.PathError{Op: "unlink", Path: fileName, Err: err} |
|
80 |
} |
|
81 |
|
|
82 |
return nil |
|
83 |
} |