go-tg-screenshot-bot

Форк
0
198 строк · 4.1 Кб
1
// +build solaris
2

3
package shm
4

5
// #include <sys/ipc.h>
6
// #include <sys/shm.h>
7
// #include <errno.h>
8
import "C"
9

10
import (
11
	"unsafe"
12
)
13

14
// Perm is used to pass permission information to IPC operations.
15
type Perm struct {
16
	// Owner's user ID.
17
	Uid uint32
18
	// Owner's group ID.
19
	Gid uint32
20
	// Creator's user ID.
21
	Cuid uint32
22
	// Creator's group ID.
23
	Cgid uint32
24
	// Read/write permission.
25
	Mode uint32
26
	// Sequence number.
27
	Seq uint32
28
	// Key.
29
	Key int32
30
}
31

32
// IdDs describes shared memory segment.
33
type IdDs struct {
34
	// Operation permission struct.
35
	Perm Perm
36
	// Padding.
37
	PadCgo0 [4]byte
38
	// Size of segment in bytes.
39
	SegSz uint64
40
	// Flags.
41
	Flags uint64
42
	// Internal.
43
	Lkcnt uint16
44
	// Padding.
45
	PadCgo1 [2]byte
46
	// Pid of last shmat/shmdt.
47
	Lpid int32
48
	// Pid of creator.
49
	Cpid int32
50
	// Padding.
51
	PadCgo2 [4]byte
52
	// Number of current attaches.
53
	Nattch uint64
54
	// Internal.
55
	Cnattch uint64
56
	// Last attach time.
57
	Atime int64
58
	// Last detach time.
59
	Dtime int64
60
	// Last change time.
61
	Ctime int64
62
	// Internal.
63
	Amp *byte
64
	// Internal.
65
	Gransize uint64
66
	// Internal.
67
	Allocated uint64
68
	// Padding.
69
	Pad4 [1]int64
70
}
71

72
// Constants.
73
const (
74
	// Mode bits for `shmget`.
75

76
	// Create key if key does not exist.
77
	IPC_CREAT = 01000
78
	// Fail if key exists.
79
	IPC_EXCL = 02000
80
	// Return error on wait.
81
	IPC_NOWAIT = 04000
82

83
	// Special key values.
84

85
	// Private key.
86
	IPC_PRIVATE = 0
87

88
	// Flags for `shmat`.
89

90
	// Attach read-only access.
91
	SHM_RDONLY = 010000
92
	// Round attach address to SHMLBA.
93
	SHM_RND = 020000
94
	// Take-over region on attach.
95
	SHM_REMAP = 040000
96
	// Execution access.
97
	SHM_EXEC = 0100000
98

99
	// Commands for `shmctl`.
100

101
	// Lock segment (root only).
102
	SHM_LOCK = 1
103
	// Unlock segment (root only).
104
	SHM_UNLOCK = 12
105

106
	// Control commands for `shmctl`.
107

108
	// Remove identifier.
109
	IPC_RMID = 10
110
	// Set `ipc_perm` options.
111
	IPC_SET = 11
112
	// Get `ipc_perm' options.
113
	IPC_STAT = 12
114
)
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.
124
func Get(key int, size int, shmFlg int) (shmId int, err error) {
125
	id, errno := C.shmget(C.key_t(key), C.size_t(size), C.int(shmFlg))
126

127
	if int(id) == -1 {
128
		return -1, errno
129
	}
130

131
	return int(id), nil
132
}
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.
137
func At(shmId int, shmAddr uintptr, shmFlg int) (data []byte, err error) {
138
	addr, errno := C.shmat(C.int(shmId), unsafe.Pointer(shmAddr), C.int(shmFlg))
139
	if int(uintptr(addr)) == -1 {
140
		return nil, errno
141
	}
142

143
	length, err := Size(shmId)
144
	if err != nil {
145
		return nil, err
146
	}
147

148
	var b = struct {
149
		addr uintptr
150
		len  int
151
		cap  int
152
	}{uintptr(addr), int(length), int(length)}
153

154
	data = *(*[]byte)(unsafe.Pointer(&b))
155
	return data, nil
156
}
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.
161
func Dt(data []byte) error {
162
	result, errno := C.shmdt(unsafe.Pointer(&data[0]))
163
	if int(result) == -1 {
164
		return errno
165
	}
166

167
	return nil
168
}
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.
173
func Ctl(shmId int, cmd int, buf *IdDs) (int, error) {
174
	result, errno := C.shmctl(C.int(shmId), C.int(cmd), (*C.struct_shmid_ds)(unsafe.Pointer(buf)))
175
	if int(result) == -1 {
176
		return -1, errno
177
	}
178

179
	return int(result), nil
180
}
181

182
// Rm removes the shared memory segment.
183
func Rm(shmId int) error {
184
	_, err := Ctl(shmId, IPC_RMID, nil)
185
	return err
186
}
187

188
// Size returns size of shared memory segment.
189
func Size(shmId int) (int64, error) {
190
	var idDs IdDs
191

192
	_, err := Ctl(shmId, IPC_STAT, &idDs)
193
	if err != nil {
194
		return 0, err
195
	}
196

197
	return int64(idDs.SegSz), nil
198
}
199

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.