go-tg-screenshot-bot
198 строк · 4.1 Кб
1// +build solaris
2
3package shm4
5// #include <sys/ipc.h>
6// #include <sys/shm.h>
7// #include <errno.h>
8import "C"9
10import (11"unsafe"12)
13
14// Perm is used to pass permission information to IPC operations.
15type Perm struct {16// Owner's user ID.17Uid uint3218// Owner's group ID.19Gid uint3220// Creator's user ID.21Cuid uint3222// Creator's group ID.23Cgid uint3224// Read/write permission.25Mode uint3226// Sequence number.27Seq uint3228// Key.29Key int3230}
31
32// IdDs describes shared memory segment.
33type IdDs struct {34// Operation permission struct.35Perm Perm
36// Padding.37PadCgo0 [4]byte38// Size of segment in bytes.39SegSz uint6440// Flags.41Flags uint6442// Internal.43Lkcnt uint1644// Padding.45PadCgo1 [2]byte46// Pid of last shmat/shmdt.47Lpid int3248// Pid of creator.49Cpid int3250// Padding.51PadCgo2 [4]byte52// Number of current attaches.53Nattch uint6454// Internal.55Cnattch uint6456// Last attach time.57Atime int6458// Last detach time.59Dtime int6460// Last change time.61Ctime int6462// Internal.63Amp *byte64// Internal.65Gransize uint6466// Internal.67Allocated uint6468// Padding.69Pad4 [1]int6470}
71
72// Constants.
73const (74// Mode bits for `shmget`.75
76// Create key if key does not exist.77IPC_CREAT = 0100078// Fail if key exists.79IPC_EXCL = 0200080// Return error on wait.81IPC_NOWAIT = 0400082
83// Special key values.84
85// Private key.86IPC_PRIVATE = 087
88// Flags for `shmat`.89
90// Attach read-only access.91SHM_RDONLY = 01000092// Round attach address to SHMLBA.93SHM_RND = 02000094// Take-over region on attach.95SHM_REMAP = 04000096// Execution access.97SHM_EXEC = 010000098
99// Commands for `shmctl`.100
101// Lock segment (root only).102SHM_LOCK = 1103// Unlock segment (root only).104SHM_UNLOCK = 12105
106// Control commands for `shmctl`.107
108// Remove identifier.109IPC_RMID = 10110// Set `ipc_perm` options.111IPC_SET = 11112// Get `ipc_perm' options.113IPC_STAT = 12114)
115
116// Get allocates a shared memory segment.
117//
118// Get() returns the identifier of the shared memory segment associated with the value of the argument key.
119// A new shared memory segment is created if key has the value IPC_PRIVATE or key isn't IPC_PRIVATE,
120// no shared memory segment corresponding to key exists, and IPC_CREAT is specified in shmFlg.
121//
122// If shmFlg specifies both IPC_CREAT and IPC_EXCL and a shared memory segment already exists for key,
123// then Get() fails with errno set to EEXIST.
124func Get(key int, size int, shmFlg int) (shmId int, err error) {125id, errno := C.shmget(C.key_t(key), C.size_t(size), C.int(shmFlg))126
127if int(id) == -1 {128return -1, errno129}130
131return int(id), nil132}
133
134// At attaches the shared memory segment identified by shmId.
135//
136// Using At() with shmAddr equal to NULL is the preferred, portable way of attaching a shared memory segment.
137func At(shmId int, shmAddr uintptr, shmFlg int) (data []byte, err error) {138addr, errno := C.shmat(C.int(shmId), unsafe.Pointer(shmAddr), C.int(shmFlg))139if int(uintptr(addr)) == -1 {140return nil, errno141}142
143length, err := Size(shmId)144if err != nil {145return nil, err146}147
148var b = struct {149addr uintptr150len int151cap int152}{uintptr(addr), int(length), int(length)}153
154data = *(*[]byte)(unsafe.Pointer(&b))155return data, nil156}
157
158// Dt detaches the shared memory segment.
159//
160// The to-be-detached segment must be currently attached with shmAddr equal to the value returned by the attaching At() call.
161func Dt(data []byte) error {162result, errno := C.shmdt(unsafe.Pointer(&data[0]))163if int(result) == -1 {164return errno165}166
167return nil168}
169
170// Ctl performs the control operation specified by cmd on the shared memory segment whose identifier is given in shmId.
171//
172// The buf argument is a pointer to a IdDs structure.
173func Ctl(shmId int, cmd int, buf *IdDs) (int, error) {174result, errno := C.shmctl(C.int(shmId), C.int(cmd), (*C.struct_shmid_ds)(unsafe.Pointer(buf)))175if int(result) == -1 {176return -1, errno177}178
179return int(result), nil180}
181
182// Rm removes the shared memory segment.
183func Rm(shmId int) error {184_, err := Ctl(shmId, IPC_RMID, nil)185return err186}
187
188// Size returns size of shared memory segment.
189func Size(shmId int) (int64, error) {190var idDs IdDs191
192_, err := Ctl(shmId, IPC_STAT, &idDs)193if err != nil {194return 0, err195}196
197return int64(idDs.SegSz), nil198}
199