| 提交 | 用户 | 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 | } | |