go-tg-screenshot-bot

Форк
0
137 строк · 3.4 Кб
1
// +build darwin dragonfly freebsd linux netbsd openbsd
2

3
// Package shm implements System V shared memory functions (shmctl, shmget, shmat, shmdt).
4
package shm
5

6
import (
7
	"syscall"
8
	"unsafe"
9
)
10

11
// Constants.
12
const (
13
	// Mode bits for `shmget`.
14

15
	// Create key if key does not exist.
16
	IPC_CREAT = 01000
17
	// Fail if key exists.
18
	IPC_EXCL = 02000
19
	// Return error on wait.
20
	IPC_NOWAIT = 04000
21

22
	// Special key values.
23

24
	// Private key.
25
	IPC_PRIVATE = 0
26

27
	// Flags for `shmat`.
28

29
	// Attach read-only access.
30
	SHM_RDONLY = 010000
31
	// Round attach address to SHMLBA.
32
	SHM_RND = 020000
33
	// Take-over region on attach.
34
	SHM_REMAP = 040000
35
	// Execution access.
36
	SHM_EXEC = 0100000
37

38
	// Commands for `shmctl`.
39

40
	// Lock segment (root only).
41
	SHM_LOCK = 1
42
	// Unlock segment (root only).
43
	SHM_UNLOCK = 12
44

45
	// Control commands for `shmctl`.
46

47
	// Remove identifier.
48
	IPC_RMID = 0
49
	// Set `ipc_perm` options.
50
	IPC_SET = 1
51
	// Get `ipc_perm' options.
52
	IPC_STAT = 2
53
)
54

55
// Get allocates a shared memory segment.
56
//
57
// Get() returns the identifier of the shared memory segment associated with the value of the argument key.
58
// A new shared memory segment is created if key has the value IPC_PRIVATE or key isn't IPC_PRIVATE,
59
// no shared memory segment corresponding to key exists, and IPC_CREAT is specified in shmFlg.
60
//
61
// If shmFlg specifies both IPC_CREAT and IPC_EXCL and a shared memory segment already exists for key,
62
// then Get() fails with errno set to EEXIST.
63
func Get(key int, size int, shmFlg int) (shmId int, err error) {
64
	id, _, errno := syscall.Syscall(sysShmGet, uintptr(int32(key)), uintptr(int32(size)), uintptr(int32(shmFlg)))
65
	if int(id) == -1 {
66
		return -1, errno
67
	}
68

69
	return int(id), nil
70
}
71

72
// At attaches the shared memory segment identified by shmId.
73
//
74
// Using At() with shmAddr equal to NULL is the preferred, portable way of attaching a shared memory segment.
75
func At(shmId int, shmAddr uintptr, shmFlg int) (data []byte, err error) {
76
	addr, _, errno := syscall.Syscall(sysShmAt, uintptr(int32(shmId)), shmAddr, uintptr(int32(shmFlg)))
77
	if int(addr) == -1 {
78
		return nil, errno
79
	}
80

81
	length, err := Size(shmId)
82
	if err != nil {
83
		syscall.Syscall(sysShmDt, addr, 0, 0)
84
		return nil, err
85
	}
86

87
	var b = struct {
88
		addr uintptr
89
		len  int
90
		cap  int
91
	}{addr, int(length), int(length)}
92

93
	data = *(*[]byte)(unsafe.Pointer(&b))
94
	return data, nil
95
}
96

97
// Dt detaches the shared memory segment.
98
//
99
// The to-be-detached segment must be currently attached with shmAddr equal to the value returned by the attaching At() call.
100
func Dt(data []byte) error {
101
	result, _, errno := syscall.Syscall(sysShmDt, uintptr(unsafe.Pointer(&data[0])), 0, 0)
102
	if int(result) == -1 {
103
		return errno
104
	}
105

106
	return nil
107
}
108

109
// Ctl performs the control operation specified by cmd on the shared memory segment whose identifier is given in shmId.
110
//
111
// The buf argument is a pointer to a IdDs structure.
112
func Ctl(shmId int, cmd int, buf *IdDs) (int, error) {
113
	result, _, errno := syscall.Syscall(sysShmCtl, uintptr(int32(shmId)), uintptr(int32(cmd)), uintptr(unsafe.Pointer(buf)))
114
	if int(result) == -1 {
115
		return -1, errno
116
	}
117

118
	return int(result), nil
119
}
120

121
// Rm removes the shared memory segment.
122
func Rm(shmId int) error {
123
	_, err := Ctl(shmId, IPC_RMID, nil)
124
	return err
125
}
126

127
// Size returns size of shared memory segment.
128
func Size(shmId int) (int64, error) {
129
	var idDs IdDs
130

131
	_, err := Ctl(shmId, IPC_STAT, &idDs)
132
	if err != nil {
133
		return 0, err
134
	}
135

136
	return int64(idDs.SegSz), nil
137
}
138

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

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

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

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