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