This source file includes following definitions.
- ZEND_GET_MODULE
- PHP_MINIT_FUNCTION
- PHP_MINFO_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
- PHP_FUNCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "php.h"
26 #include "php_ini.h"
27 #include "php_shmop.h"
28 # ifndef PHP_WIN32
29 # include <sys/ipc.h>
30 # include <sys/shm.h>
31 #else
32 #include "tsrm_win32.h"
33 #endif
34
35
36 #if HAVE_SHMOP
37
38 #include "ext/standard/info.h"
39
40 #ifdef ZTS
41 int shmop_globals_id;
42 #else
43 php_shmop_globals shmop_globals;
44 #endif
45
46 int shm_type;
47
48
49 ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_open, 0, 0, 4)
50 ZEND_ARG_INFO(0, key)
51 ZEND_ARG_INFO(0, flags)
52 ZEND_ARG_INFO(0, mode)
53 ZEND_ARG_INFO(0, size)
54 ZEND_END_ARG_INFO()
55
56 ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_read, 0, 0, 3)
57 ZEND_ARG_INFO(0, shmid)
58 ZEND_ARG_INFO(0, start)
59 ZEND_ARG_INFO(0, count)
60 ZEND_END_ARG_INFO()
61
62 ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_close, 0, 0, 1)
63 ZEND_ARG_INFO(0, shmid)
64 ZEND_END_ARG_INFO()
65
66 ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_size, 0, 0, 1)
67 ZEND_ARG_INFO(0, shmid)
68 ZEND_END_ARG_INFO()
69
70 ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_write, 0, 0, 3)
71 ZEND_ARG_INFO(0, shmid)
72 ZEND_ARG_INFO(0, data)
73 ZEND_ARG_INFO(0, offset)
74 ZEND_END_ARG_INFO()
75
76 ZEND_BEGIN_ARG_INFO_EX(arginfo_shmop_delete, 0, 0, 1)
77 ZEND_ARG_INFO(0, shmid)
78 ZEND_END_ARG_INFO()
79
80
81
82
83 const zend_function_entry shmop_functions[] = {
84 PHP_FE(shmop_open, arginfo_shmop_open)
85 PHP_FE(shmop_read, arginfo_shmop_read)
86 PHP_FE(shmop_close, arginfo_shmop_close)
87 PHP_FE(shmop_size, arginfo_shmop_size)
88 PHP_FE(shmop_write, arginfo_shmop_write)
89 PHP_FE(shmop_delete, arginfo_shmop_delete)
90 PHP_FE_END
91 };
92
93
94
95
96 zend_module_entry shmop_module_entry = {
97 STANDARD_MODULE_HEADER,
98 "shmop",
99 shmop_functions,
100 PHP_MINIT(shmop),
101 NULL,
102 NULL,
103 NULL,
104 PHP_MINFO(shmop),
105 PHP_SHMOP_VERSION,
106 STANDARD_MODULE_PROPERTIES
107 };
108
109
110 #ifdef COMPILE_DL_SHMOP
111 ZEND_GET_MODULE(shmop)
112 #endif
113
114
115
116 static void rsclean(zend_resource *rsrc)
117 {
118 struct php_shmop *shmop = (struct php_shmop *)rsrc->ptr;
119
120 shmdt(shmop->addr);
121 efree(shmop);
122 }
123
124
125
126
127 PHP_MINIT_FUNCTION(shmop)
128 {
129 shm_type = zend_register_list_destructors_ex(rsclean, NULL, "shmop", module_number);
130
131 return SUCCESS;
132 }
133
134
135
136
137 PHP_MINFO_FUNCTION(shmop)
138 {
139 php_info_print_table_start();
140 php_info_print_table_row(2, "shmop support", "enabled");
141 php_info_print_table_end();
142 }
143
144
145
146
147 PHP_FUNCTION(shmop_open)
148 {
149 zend_long key, mode, size;
150 struct php_shmop *shmop;
151 struct shmid_ds shm;
152 char *flags;
153 size_t flags_len;
154
155 if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsll", &key, &flags, &flags_len, &mode, &size) == FAILURE) {
156 return;
157 }
158
159 if (flags_len != 1) {
160 php_error_docref(NULL, E_WARNING, "%s is not a valid flag", flags);
161 RETURN_FALSE;
162 }
163
164 shmop = emalloc(sizeof(struct php_shmop));
165 memset(shmop, 0, sizeof(struct php_shmop));
166
167 shmop->key = key;
168 shmop->shmflg |= mode;
169
170 switch (flags[0])
171 {
172 case 'a':
173 shmop->shmatflg |= SHM_RDONLY;
174 break;
175 case 'c':
176 shmop->shmflg |= IPC_CREAT;
177 shmop->size = size;
178 break;
179 case 'n':
180 shmop->shmflg |= (IPC_CREAT | IPC_EXCL);
181 shmop->size = size;
182 break;
183 case 'w':
184
185
186
187
188 break;
189 default:
190 php_error_docref(NULL, E_WARNING, "invalid access mode");
191 goto err;
192 }
193
194 if (shmop->shmflg & IPC_CREAT && shmop->size < 1) {
195 php_error_docref(NULL, E_WARNING, "Shared memory segment size must be greater than zero");
196 goto err;
197 }
198
199 shmop->shmid = shmget(shmop->key, shmop->size, shmop->shmflg);
200 if (shmop->shmid == -1) {
201 php_error_docref(NULL, E_WARNING, "unable to attach or create shared memory segment '%s'", strerror(errno));
202 goto err;
203 }
204
205 if (shmctl(shmop->shmid, IPC_STAT, &shm)) {
206 php_error_docref(NULL, E_WARNING, "unable to get shared memory segment information '%s'", strerror(errno));
207 goto err;
208 }
209
210 shmop->addr = shmat(shmop->shmid, 0, shmop->shmatflg);
211 if (shmop->addr == (char*) -1) {
212 php_error_docref(NULL, E_WARNING, "unable to attach to shared memory segment '%s'", strerror(errno));
213 goto err;
214 }
215
216 shmop->size = shm.shm_segsz;
217
218 RETURN_RES(zend_register_resource(shmop, shm_type));
219 err:
220 efree(shmop);
221 RETURN_FALSE;
222 }
223
224
225
226
227 PHP_FUNCTION(shmop_read)
228 {
229 zval *shmid;
230 zend_long start, count;
231 struct php_shmop *shmop;
232 char *startaddr;
233 int bytes;
234 zend_string *return_string;
235
236 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rll", &shmid, &start, &count) == FAILURE) {
237 return;
238 }
239
240 if ((shmop = (struct php_shmop *)zend_fetch_resource(Z_RES_P(shmid), "shmop", shm_type)) == NULL) {
241 RETURN_FALSE;
242 }
243
244 if (start < 0 || start > shmop->size) {
245 php_error_docref(NULL, E_WARNING, "start is out of range");
246 RETURN_FALSE;
247 }
248
249 if (count < 0 || start > (INT_MAX - count) || start + count > shmop->size) {
250 php_error_docref(NULL, E_WARNING, "count is out of range");
251 RETURN_FALSE;
252 }
253
254 startaddr = shmop->addr + start;
255 bytes = count ? count : shmop->size - start;
256
257 return_string = zend_string_init(startaddr, bytes, 0);
258
259 RETURN_NEW_STR(return_string);
260 }
261
262
263
264
265 PHP_FUNCTION(shmop_close)
266 {
267 zval *shmid;
268 struct php_shmop *shmop;
269
270 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &shmid) == FAILURE) {
271 return;
272 }
273
274
275 if ((shmop = (struct php_shmop *)zend_fetch_resource(Z_RES_P(shmid), "shmop", shm_type)) == NULL) {
276 RETURN_FALSE;
277 }
278
279 zend_list_close(Z_RES_P(shmid));
280 }
281
282
283
284
285 PHP_FUNCTION(shmop_size)
286 {
287 zval *shmid;
288 struct php_shmop *shmop;
289
290 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &shmid) == FAILURE) {
291 return;
292 }
293
294 if ((shmop = (struct php_shmop *)zend_fetch_resource(Z_RES_P(shmid), "shmop", shm_type)) == NULL) {
295 RETURN_FALSE;
296 }
297
298 RETURN_LONG(shmop->size);
299 }
300
301
302
303
304 PHP_FUNCTION(shmop_write)
305 {
306 struct php_shmop *shmop;
307 int writesize;
308 zend_long offset;
309 zend_string *data;
310 zval *shmid;
311
312 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rSl", &shmid, &data, &offset) == FAILURE) {
313 return;
314 }
315
316 if ((shmop = (struct php_shmop *)zend_fetch_resource(Z_RES_P(shmid), "shmop", shm_type)) == NULL) {
317 RETURN_FALSE;
318 }
319
320 if ((shmop->shmatflg & SHM_RDONLY) == SHM_RDONLY) {
321 php_error_docref(NULL, E_WARNING, "trying to write to a read only segment");
322 RETURN_FALSE;
323 }
324
325 if (offset < 0 || offset > shmop->size) {
326 php_error_docref(NULL, E_WARNING, "offset out of range");
327 RETURN_FALSE;
328 }
329
330 writesize = (ZSTR_LEN(data) < shmop->size - offset) ? ZSTR_LEN(data) : shmop->size - offset;
331 memcpy(shmop->addr + offset, ZSTR_VAL(data), writesize);
332
333 RETURN_LONG(writesize);
334 }
335
336
337
338
339 PHP_FUNCTION(shmop_delete)
340 {
341 zval *shmid;
342 struct php_shmop *shmop;
343
344 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &shmid) == FAILURE) {
345 return;
346 }
347
348 if ((shmop = (struct php_shmop *)zend_fetch_resource(Z_RES_P(shmid), "shmop", shm_type)) == NULL) {
349 RETURN_FALSE;
350 }
351
352 if (shmctl(shmop->shmid, IPC_RMID, NULL)) {
353 php_error_docref(NULL, E_WARNING, "can't mark segment for deletion (are you the owner?)");
354 RETURN_FALSE;
355 }
356
357 RETURN_TRUE;
358 }
359
360
361 #endif
362
363
364
365
366
367
368
369
370