zhangmeng
2019-08-26 a0123f163eddcea3e6b9f9d36f1f3fb3aa2c835a
提交 | 用户 | 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 }