chenshijun
2020-06-04 e43f714b49efafd1724b32edb1b09d57ce90f416
https://github.com/gen2brain/shm
修改arm和arm64的接口号
17个文件已添加
1个文件已修改
960 ■■■■■ 已修改文件
.idea/.gitignore 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/goshm.iml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/misc.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/modules.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/vcs.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm.go 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_darwin.go 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_dragonfly.go 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_freebsd.go 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_linux_386.go 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_linux_amd64.go 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_linux_arm.go 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_linux_arm64.go 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_netbsd.go 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_openbsd.go 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_solaris.go 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
shm_test.go 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.idea/.gitignore
New file
@@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml
.idea/goshm.iml
New file
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
  <component name="NewModuleRootManager" inherit-compiler-output="true">
    <exclude-output />
    <content url="file://$MODULE_DIR$" />
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
</module>
.idea/misc.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="JavaScriptSettings">
    <option name="languageLevel" value="ES6" />
  </component>
</project>
.idea/modules.xml
New file
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/.idea/goshm.iml" filepath="$PROJECT_DIR$/.idea/goshm.iml" />
    </modules>
  </component>
</project>
.idea/vcs.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="" vcs="Git" />
  </component>
</project>
README.md
@@ -1,4 +1,14 @@
## goshm
## go shm
[![TravisCI Build Status](https://travis-ci.org/gen2brain/shm.svg?branch=master)](https://travis-ci.org/gen2brain/shm)
[![GoDoc](https://godoc.org/github.com/gen2brain/shm?status.svg)](https://godoc.org/github.com/gen2brain/shm)
[![Go Report Card](https://goreportcard.com/badge/github.com/gen2brain/shm?branch=master)](https://goreportcard.com/report/github.com/gen2brain/shm)
go
`shm` implements System V shared memory functions (`shmctl`, `shmget`, `shmat`, `shmdt`) in pure Go (except `solaris`, see [#24357](https://github.com/golang/go/issues/24357)).
### Installation
    go get -u github.com/gen2brain/shm
### More
For System V Message Queue IPC (i.e. `msgctl`, `msgget`, `msgrcv`, `msgsnd`) see [ipc](https://github.com/siadat/ipc).
shm.go
New file
@@ -0,0 +1,136 @@
// +build darwin dragonfly freebsd linux netbsd openbsd
// Package shm implements System V shared memory functions (shmctl, shmget, shmat, shmdt).
package shm
import (
    "syscall"
    "unsafe"
)
// Constants.
const (
    // Mode bits for `shmget`.
    // Create key if key does not exist.
    IPC_CREAT = 01000
    // Fail if key exists.
    IPC_EXCL = 02000
    // Return error on wait.
    IPC_NOWAIT = 04000
    // Special key values.
    // Private key.
    IPC_PRIVATE = 0
    // Flags for `shmat`.
    // Attach read-only access.
    SHM_RDONLY = 010000
    // Round attach address to SHMLBA.
    SHM_RND = 020000
    // Take-over region on attach.
    SHM_REMAP = 040000
    // Execution access.
    SHM_EXEC = 0100000
    // Commands for `shmctl`.
    // Lock segment (root only).
    SHM_LOCK = 1
    // Unlock segment (root only).
    SHM_UNLOCK = 12
    // Control commands for `shmctl`.
    // Remove identifier.
    IPC_RMID = 0
    // Set `ipc_perm` options.
    IPC_SET = 1
    // Get `ipc_perm' options.
    IPC_STAT = 2
)
// Get allocates a shared memory segment.
//
// Get() returns the identifier of the shared memory segment associated with the value of the argument key.
// A new shared memory segment is created if key has the value IPC_PRIVATE or key isn't IPC_PRIVATE,
// no shared memory segment corresponding to key exists, and IPC_CREAT is specified in shmFlg.
//
// If shmFlg specifies both IPC_CREAT and IPC_EXCL and a shared memory segment already exists for key,
// then Get() fails with errno set to EEXIST.
func Get(key int, size int, shmFlg int) (shmId int, err error) {
    id, _, errno := syscall.Syscall(sysShmGet, uintptr(int32(key)), uintptr(int32(size)), uintptr(int32(shmFlg)))
    if int(id) == -1 {
        return -1, errno
    }
    return int(id), nil
}
// At attaches the shared memory segment identified by shmId.
//
// Using At() with shmAddr equal to NULL is the preferred, portable way of attaching a shared memory segment.
func At(shmId int, shmAddr uintptr, shmFlg int) (data []byte, err error) {
    addr, _, errno := syscall.Syscall(sysShmAt, uintptr(int32(shmId)), shmAddr, uintptr(int32(shmFlg)))
    if int(addr) == -1 {
        return nil, errno
    }
    length, err := Size(shmId)
    if err != nil {
        return nil, err
    }
    var b = struct {
        addr uintptr
        len  int
        cap  int
    }{addr, int(length), int(length)}
    data = *(*[]byte)(unsafe.Pointer(&b))
    return data, nil
}
// Dt detaches the shared memory segment.
//
// The to-be-detached segment must be currently attached with shmAddr equal to the value returned by the attaching At() call.
func Dt(data []byte) error {
    result, _, errno := syscall.Syscall(sysShmDt, uintptr(unsafe.Pointer(&data[0])), 0, 0)
    if int(result) == -1 {
        return errno
    }
    return nil
}
// Ctl performs the control operation specified by cmd on the shared memory segment whose identifier is given in shmId.
//
// The buf argument is a pointer to a IdDs structure.
func Ctl(shmId int, cmd int, buf *IdDs) (int, error) {
    result, _, errno := syscall.Syscall(sysShmCtl, uintptr(int32(shmId)), uintptr(int32(cmd)), uintptr(unsafe.Pointer(buf)))
    if int(result) == -1 {
        return -1, errno
    }
    return int(result), nil
}
// Rm removes the shared memory segment.
func Rm(shmId int) error {
    _, err := Ctl(shmId, IPC_RMID, nil)
    return err
}
// Size returns size of shared memory segment.
func Size(shmId int) (int64, error) {
    var idDs IdDs
    _, err := Ctl(shmId, IPC_STAT, &idDs)
    if err != nil {
        return 0, err
    }
    return int64(idDs.SegSz), nil
}
shm_darwin.go
New file
@@ -0,0 +1,55 @@
package shm
import (
    "syscall"
)
// System call constants.
const (
    sysShmAt  = syscall.SYS_SHMAT
    sysShmCtl = syscall.SYS_SHMCTL
    sysShmDt  = syscall.SYS_SHMDT
    sysShmGet = syscall.SYS_SHMGET
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Owner's user ID.
    Uid uint32
    // Owner's group ID.
    Gid uint32
    // Creator's user ID.
    Cuid uint32
    // Creator's group ID.
    Cgid uint32
    // Read/write permission.
    Mode uint16
    // Sequence number.
    Seq uint16
    // Key.
    Key int32
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Size of segment in bytes.
    SegSz uint64
    // Pid of last shmat/shmdt.
    Lpid int32
    // Pid of creator.
    Cpid int32
    // Number of current attaches.
    Nattch uint16
    // Padding.
    PadCgo0 [2]byte
    // Padding.
    PadCgo1 [8]byte
    // Padding.
    PadCgo2 [8]byte
    // Padding.
    PadCgo3 [8]byte
    // Padding.
    PadCgo4 [8]byte
}
shm_dragonfly.go
New file
@@ -0,0 +1,57 @@
package shm
import (
    "syscall"
)
// System call constants.
const (
    sysShmAt  = syscall.SYS_SHMAT
    sysShmCtl = syscall.SYS_SHMCTL
    sysShmDt  = syscall.SYS_SHMDT
    sysShmGet = syscall.SYS_SHMGET
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Creator's user ID.
    Cuid uint16
    // Creator's group ID.
    Cgid uint16
    // Owner's user ID.
    Uid uint16
    // Owner's group ID.
    Gid uint16
    // Read/write permission.
    Mode uint16
    // Sequence number.
    Seq uint16
    // Padding.
    PadCgo0 [4]byte
    // Key.
    Key int64
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Size of segment in bytes.
    SegSz uint64
    // Pid of last shmat/shmdt.
    Lpid int32
    // Pid of creator.
    Cpid int32
    // Number of current attaches.
    Nattch uint32
    // Padding.
    PadCgo0 [4]byte
    // Last attach time.
    Atime int64
    // Last detach time.
    Dtime int64
    // Last change time.
    Ctime int64
    // Internal.
    Internal *byte
}
shm_freebsd.go
New file
@@ -0,0 +1,51 @@
package shm
// System call constants.
const (
    sysShmAt  = 228
    sysShmCtl = 229
    sysShmDt  = 230
    sysShmGet = 231
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Creator's user ID.
    Cuid uint32
    // Creator's group ID.
    Cgid uint32
    // Owner's user ID.
    Uid uint32
    // Owner's group ID.
    Gid uint32
    // Read/write permission.
    Mode uint16
    // Sequence number.
    Seq uint16
    // Padding.
    PadCgo0 [4]byte
    // Key.
    Key int64
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Size of segment in bytes.
    SegSz uint64
    // Pid of last shmat/shmdt.
    Lpid int32
    // Pid of creator.
    Cpid int32
    // Number of current attaches.
    Nattch int32
    // Padding.
    PadCgo0 [4]byte
    // Last attach time.
    Atime int64
    // Last detach time.
    Dtime int64
    // Last change time.
    Ctime int64
}
shm_linux_386.go
New file
@@ -0,0 +1,65 @@
package shm
// System call constants.
const (
    sysShmAt  = 30
    sysShmCtl = 31
    sysShmDt  = 67
    sysShmGet = 29
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Key.
    Key int32
    // Owner's user ID.
    Uid uint32
    // Owner's group ID.
    Gid uint32
    // Creator's user ID.
    Cuid uint32
    // Creator's group ID.
    Cgid uint32
    // Read/write permission.
    Mode uint16
    // Padding.
    Pad1 uint16
    // Sequence number.
    Seq uint16
    // Padding.
    Pad2 uint16
    // Reserved.
    GlibcReserved1 uint32
    // Reserved.
    GlibcReserved2 uint32
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Size of segment in bytes.
    SegSz uint32
    // Last attach time.
    Atime int32
    // Reserved.
    GlibcReserved1 uint32
    // Last detach time.
    Dtime int32
    // Reserved.
    GlibcReserved2 uint32
    // Last change time.
    Ctime int32
    // Reserved.
    GlibcReserved3 uint32
    // Pid of creator.
    Cpid int32
    // Pid of last shmat/shmdt.
    Lpid int32
    // Number of current attaches.
    Nattch uint32
    // Reserved.
    GlibcReserved4 uint32
    // Reserved.
    GlibcReserved5 uint32
}
shm_linux_amd64.go
New file
@@ -0,0 +1,65 @@
package shm
import (
    "syscall"
)
// System call constants.
const (
    sysShmAt  = syscall.SYS_SHMAT
    sysShmCtl = syscall.SYS_SHMCTL
    sysShmDt  = syscall.SYS_SHMDT
    sysShmGet = syscall.SYS_SHMGET
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Key.
    Key int32
    // Owner's user ID.
    Uid uint32
    // Owner's group ID.
    Gid uint32
    // Creator's user ID.
    Cuid uint32
    // Creator's group ID.
    Cgid uint32
    // Read/write permission.
    Mode uint16
    // Padding.
    Pad1 uint16
    // Sequence number.
    Seq uint16
    // Padding.
    Pad2 uint16
    // Padding.
    PadCgo0 [4]byte
    // Reserved.
    GlibcReserved1 uint64
    // Reserved.
    GlibcReserved2 uint64
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Size of segment in bytes.
    SegSz uint64
    // Last attach time.
    Atime int64
    // Last detach time.
    Dtime int64
    // Last change time.
    Ctime int64
    // Pid of creator.
    Cpid int32
    // Pid of last shmat/shmdt.
    Lpid int32
    // Number of current attaches.
    Nattch uint64
    // Reserved.
    GlibcReserved4 uint64
    // Reserved.
    GlibcReserved5 uint64
}
shm_linux_arm.go
New file
@@ -0,0 +1,69 @@
package shm
// System call constants.
const (
    //sysShmAt  = 21
    //sysShmCtl = 24
    //sysShmDt  = 22
    //sysShmGet = 23
    sysShmAt                  = 305
    sysShmDt                  = 306
    sysShmGet                 = 307
    sysShmCtl                 = 308
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Key.
    Key int32
    // Owner's user ID.
    Uid uint32
    // Owner's group ID.
    Gid uint32
    // Creator's user ID.
    Cuid uint32
    // Creator's group ID.
    Cgid uint32
    // Read/write permission.
    Mode uint16
    // Padding.
    Pad1 uint16
    // Sequence number.
    Seq uint16
    // Padding.
    Pad2 uint16
    // Reserved.
    GlibcReserved1 uint32
    // Reserved.
    GlibcReserved2 uint32
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Size of segment in bytes.
    SegSz uint32
    // Last attach time.
    Atime int32
    // Reserved.
    GlibcReserved1 uint32
    // Last detach time.
    Dtime int32
    // Reserved.
    GlibcReserved2 uint32
    // Last change time.
    Ctime int32
    // Reserved.
    GlibcReserved3 uint32
    // Pid of creator.
    Cpid int32
    // Pid of last shmat/shmdt.
    Lpid int32
    // Number of current attaches.
    Nattch uint32
    // Reserved.
    GlibcReserved4 uint32
    // Reserved.
    GlibcReserved5 uint32
}
shm_linux_arm64.go
New file
@@ -0,0 +1,61 @@
package shm
// System call constants.
const (
    //sysShmAt  = 21
    //sysShmCtl = 24
    //sysShmDt  = 22
    //sysShmGet = 23
    sysShmGet                 = 194
    sysShmCtl                 = 195
    sysShmAt                  = 196
    sysShmDt                  = 197
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Key.
    Key int32
    // Owner's user ID.
    Uid uint32
    // Owner's group ID.
    Gid uint32
    // Creator's user ID.
    Cuid uint32
    // Creator's group ID.
    Cgid uint32
    // Read/write permission.
    Mode uint32
    // Sequence number.
    Seq uint16
    // Padding.
    Pad1 uint16
    // Reserved.
    GlibcReserved1 uint64
    // Reserved.
    GlibcReserved2 uint64
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Size of segment in bytes.
    SegSz uint64
    // Last attach time.
    Atime int64
    // Last detach time.
    Dtime int64
    // Last change time.
    Ctime int64
    // Pid of creator.
    Cpid int32
    // Pid of last shmat/shmdt.
    Lpid int32
    // Number of current attaches.
    Nattch uint64
    // Reserved.
    GlibcReserved5 uint64
    // Reserved.
    GlibcReserved6 uint64
}
shm_netbsd.go
New file
@@ -0,0 +1,57 @@
package shm
import (
    "syscall"
)
// System call constants.
const (
    sysShmAt  = syscall.SYS_SHMAT
    sysShmCtl = syscall.SYS_SHMCTL
    sysShmDt  = syscall.SYS_SHMDT
    sysShmGet = syscall.SYS_SHMGET
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Owner's user ID.
    Uid uint32
    // Owner's group ID.
    Gid uint32
    // Creator's user ID.
    Cuid uint32
    // Creator's group ID.
    Cgid uint32
    // Read/write permission.
    Mode uint32
    // Sequence number.
    Seq uint16
    // Padding.
    PadCgo0 [2]byte
    // Key.
    Key int64
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Size of segment in bytes.
    SegSz uint64
    // Pid of last shmat/shmdt.
    Lpid int32
    // Pid of creator.
    Cpid int32
    // Number of current attaches.
    Nattch uint32
    // Padding.
    PadCgo0 [4]byte
    // Last attach time.
    Atime int64
    // Last detach time.
    Dtime int64
    // Last change time.
    Ctime int64
    // SysV stupidity
    XShmInternal *byte
}
shm_openbsd.go
New file
@@ -0,0 +1,63 @@
package shm
import (
    "syscall"
)
// System call constants.
const (
    sysShmAt  = syscall.SYS_SHMAT
    sysShmCtl = syscall.SYS_SHMCTL
    sysShmDt  = syscall.SYS_SHMDT
    sysShmGet = syscall.SYS_SHMGET
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Owner's user ID.
    Cuid uint32
    // Owner's group ID.
    Cgid uint32
    // Creator's user ID.
    Uid uint32
    // Creator's group ID.
    Gid uint32
    // Read/write permission.
    Mode uint32
    // Sequence number.
    Seq uint16
    // Padding.
    PadCgo0 [2]byte
    // Key.
    Key int64
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Size of segment in bytes.
    SegSz int32
    // Pid of last shmat/shmdt.
    Lpid int32
    // Pid of creator.
    Cpid int32
    // Number of current attaches.
    Nattch int16
    // Padding.
    PadCgo0 [2]byte
    // Last attach time.
    Atime int64
    // Internal.
    XShmAtimensec int64
    // Last detach time.
    Dtime int64
    // Internal.
    XShmDtimensec int64
    // Last change time.
    Ctime int64
    // Internal.
    XShmCtimensec int64
    // Internal.
    XShmInternal *byte
}
shm_solaris.go
New file
@@ -0,0 +1,198 @@
// +build solaris
package shm
// #include <sys/ipc.h>
// #include <sys/shm.h>
// #include <errno.h>
import "C"
import (
    "unsafe"
)
// Perm is used to pass permission information to IPC operations.
type Perm struct {
    // Owner's user ID.
    Uid uint32
    // Owner's group ID.
    Gid uint32
    // Creator's user ID.
    Cuid uint32
    // Creator's group ID.
    Cgid uint32
    // Read/write permission.
    Mode uint32
    // Sequence number.
    Seq uint32
    // Key.
    Key int32
}
// IdDs describes shared memory segment.
type IdDs struct {
    // Operation permission struct.
    Perm Perm
    // Padding.
    PadCgo0 [4]byte
    // Size of segment in bytes.
    SegSz uint64
    // Flags.
    Flags uint64
    // Internal.
    Lkcnt uint16
    // Padding.
    PadCgo1 [2]byte
    // Pid of last shmat/shmdt.
    Lpid int32
    // Pid of creator.
    Cpid int32
    // Padding.
    PadCgo2 [4]byte
    // Number of current attaches.
    Nattch uint64
    // Internal.
    Cnattch uint64
    // Last attach time.
    Atime int64
    // Last detach time.
    Dtime int64
    // Last change time.
    Ctime int64
    // Internal.
    Amp *byte
    // Internal.
    Gransize uint64
    // Internal.
    Allocated uint64
    // Padding.
    Pad4 [1]int64
}
// Constants.
const (
    // Mode bits for `shmget`.
    // Create key if key does not exist.
    IPC_CREAT = 01000
    // Fail if key exists.
    IPC_EXCL = 02000
    // Return error on wait.
    IPC_NOWAIT = 04000
    // Special key values.
    // Private key.
    IPC_PRIVATE = 0
    // Flags for `shmat`.
    // Attach read-only access.
    SHM_RDONLY = 010000
    // Round attach address to SHMLBA.
    SHM_RND = 020000
    // Take-over region on attach.
    SHM_REMAP = 040000
    // Execution access.
    SHM_EXEC = 0100000
    // Commands for `shmctl`.
    // Lock segment (root only).
    SHM_LOCK = 1
    // Unlock segment (root only).
    SHM_UNLOCK = 12
    // Control commands for `shmctl`.
    // Remove identifier.
    IPC_RMID = 10
    // Set `ipc_perm` options.
    IPC_SET = 11
    // Get `ipc_perm' options.
    IPC_STAT = 12
)
// Get allocates a shared memory segment.
//
// Get() returns the identifier of the shared memory segment associated with the value of the argument key.
// A new shared memory segment is created if key has the value IPC_PRIVATE or key isn't IPC_PRIVATE,
// no shared memory segment corresponding to key exists, and IPC_CREAT is specified in shmFlg.
//
// If shmFlg specifies both IPC_CREAT and IPC_EXCL and a shared memory segment already exists for key,
// then Get() fails with errno set to EEXIST.
func Get(key int, size int, shmFlg int) (shmId int, err error) {
    id, errno := C.shmget(C.key_t(key), C.size_t(size), C.int(shmFlg))
    if int(id) == -1 {
        return -1, errno
    }
    return int(id), nil
}
// At attaches the shared memory segment identified by shmId.
//
// Using At() with shmAddr equal to NULL is the preferred, portable way of attaching a shared memory segment.
func At(shmId int, shmAddr uintptr, shmFlg int) (data []byte, err error) {
    addr, errno := C.shmat(C.int(shmId), unsafe.Pointer(shmAddr), C.int(shmFlg))
    if int(uintptr(addr)) == -1 {
        return nil, errno
    }
    length, err := Size(shmId)
    if err != nil {
        return nil, err
    }
    var b = struct {
        addr uintptr
        len  int
        cap  int
    }{uintptr(addr), int(length), int(length)}
    data = *(*[]byte)(unsafe.Pointer(&b))
    return data, nil
}
// Dt detaches the shared memory segment.
//
// The to-be-detached segment must be currently attached with shmAddr equal to the value returned by the attaching At() call.
func Dt(data []byte) error {
    result, errno := C.shmdt(unsafe.Pointer(&data[0]))
    if int(result) == -1 {
        return errno
    }
    return nil
}
// Ctl performs the control operation specified by cmd on the shared memory segment whose identifier is given in shmId.
//
// The buf argument is a pointer to a IdDs structure.
func Ctl(shmId int, cmd int, buf *IdDs) (int, error) {
    result, errno := C.shmctl(C.int(shmId), C.int(cmd), (*C.struct_shmid_ds)(unsafe.Pointer(buf)))
    if int(result) == -1 {
        return -1, errno
    }
    return int(result), nil
}
// Rm removes the shared memory segment.
func Rm(shmId int) error {
    _, err := Ctl(shmId, IPC_RMID, nil)
    return err
}
// Size returns size of shared memory segment.
func Size(shmId int) (int64, error) {
    var idDs IdDs
    _, err := Ctl(shmId, IPC_STAT, &idDs)
    if err != nil {
        return 0, err
    }
    return int64(idDs.SegSz), nil
}
shm_test.go
New file
@@ -0,0 +1,38 @@
package shm
import (
    "testing"
)
func TestShm(t *testing.T) {
    shmSize := 65536
    shmId, err := Get(IPC_PRIVATE, shmSize, IPC_CREAT|0777)
    if err != nil {
        t.Errorf("Get: %v", err)
    }
    data, err := At(shmId, 0, 0)
    if err != nil {
        t.Errorf("At: %v", err)
    }
    size, err := Size(shmId)
    if err != nil {
        t.Errorf("Size: %v", err)
    }
    if int(size) != shmSize {
        t.Errorf("Wrong size got %d expected %d", size, shmSize)
    }
    err = Rm(shmId)
    if err != nil {
        t.Errorf("Rm: %v", err)
    }
    err = Dt(data)
    if err != nil {
        t.Errorf("Dt: %v", err)
    }
}