25
25
#include "sysvmsg_arginfo.h"
26
26
#include "ext/standard/php_var.h"
27
27
#include "zend_smart_str.h"
28
+ #include "Zend/zend_interfaces.h"
28
29
29
30
#include <sys/types.h>
30
31
#include <sys/ipc.h>
@@ -36,6 +37,7 @@ PHP_MINFO_FUNCTION(sysvmsg);
36
37
typedef struct {
37
38
key_t key ;
38
39
zend_long id ;
40
+ zend_object std ;
39
41
} sysvmsg_queue_t ;
40
42
41
43
struct php_msgbuf {
@@ -50,9 +52,6 @@ struct php_msgbuf {
50
52
#define PHP_MSG_NOERROR 2
51
53
#define PHP_MSG_EXCEPT 4
52
54
53
- /* True global resources - no need for thread safety here */
54
- static int le_sysvmsg ;
55
-
56
55
/* {{{ sysvmsg_module_entry
57
56
*/
58
57
zend_module_entry sysvmsg_module_entry = {
@@ -73,17 +72,58 @@ zend_module_entry sysvmsg_module_entry = {
73
72
ZEND_GET_MODULE (sysvmsg )
74
73
#endif
75
74
76
- static void sysvmsg_release (zend_resource * rsrc )
75
+ /* SysvMessageQueue class */
76
+
77
+ zend_class_entry * sysvmsg_queue_ce ;
78
+ static zend_object_handlers sysvmsg_queue_object_handlers ;
79
+
80
+ static inline sysvmsg_queue_t * sysvmsg_queue_from_obj (zend_object * obj ) {
81
+ return (sysvmsg_queue_t * )((char * )(obj ) - XtOffsetOf (sysvmsg_queue_t , std ));
82
+ }
83
+
84
+ #define Z_SYSVMSG_QUEUE_P (zv ) sysvmsg_queue_from_obj(Z_OBJ_P(zv))
85
+
86
+ static zend_object * sysvmsg_queue_create_object (zend_class_entry * class_type ) {
87
+ sysvmsg_queue_t * intern = zend_object_alloc (sizeof (sysvmsg_queue_t ), class_type );
88
+
89
+ zend_object_std_init (& intern -> std , class_type );
90
+ object_properties_init (& intern -> std , class_type );
91
+ intern -> std .handlers = & sysvmsg_queue_object_handlers ;
92
+
93
+ return & intern -> std ;
94
+ }
95
+
96
+ static zend_function * sysvmsg_queue_get_constructor (zend_object * object ) {
97
+ zend_throw_error (NULL , "Cannot directly construct SysvMessageQueue, use msg_get_queue() instead" );
98
+ return NULL ;
99
+ }
100
+
101
+ static void sysvmsg_queue_free_obj (zend_object * object )
77
102
{
78
- sysvmsg_queue_t * mq = (sysvmsg_queue_t * ) rsrc -> ptr ;
79
- efree (mq );
103
+ sysvmsg_queue_t * sysvmsg_queue = sysvmsg_queue_from_obj (object );
104
+
105
+ zend_object_std_dtor (& sysvmsg_queue -> std );
80
106
}
107
+ /* }}} */
81
108
82
109
/* {{{ PHP_MINIT_FUNCTION
83
110
*/
84
111
PHP_MINIT_FUNCTION (sysvmsg )
85
112
{
86
- le_sysvmsg = zend_register_list_destructors_ex (sysvmsg_release , NULL , "sysvmsg queue" , module_number );
113
+ zend_class_entry ce ;
114
+ INIT_CLASS_ENTRY (ce , "SysvMessageQueue" , class_SysvMessageQueue_methods );
115
+ sysvmsg_queue_ce = zend_register_internal_class (& ce );
116
+ sysvmsg_queue_ce -> ce_flags |= ZEND_ACC_FINAL ;
117
+ sysvmsg_queue_ce -> create_object = sysvmsg_queue_create_object ;
118
+ sysvmsg_queue_ce -> serialize = zend_class_serialize_deny ;
119
+ sysvmsg_queue_ce -> unserialize = zend_class_unserialize_deny ;
120
+
121
+ memcpy (& sysvmsg_queue_object_handlers , & std_object_handlers , sizeof (zend_object_handlers ));
122
+ sysvmsg_queue_object_handlers .offset = XtOffsetOf (sysvmsg_queue_t , std );
123
+ sysvmsg_queue_object_handlers .free_obj = sysvmsg_queue_free_obj ;
124
+ sysvmsg_queue_object_handlers .get_constructor = sysvmsg_queue_get_constructor ;
125
+ sysvmsg_queue_object_handlers .clone_obj = NULL ;
126
+
87
127
REGISTER_LONG_CONSTANT ("MSG_IPC_NOWAIT" , PHP_MSG_IPC_NOWAIT , CONST_PERSISTENT |CONST_CS );
88
128
REGISTER_LONG_CONSTANT ("MSG_EAGAIN" , EAGAIN , CONST_PERSISTENT |CONST_CS );
89
129
REGISTER_LONG_CONSTANT ("MSG_ENOMSG" , ENOMSG , CONST_PERSISTENT |CONST_CS );
@@ -103,7 +143,7 @@ PHP_MINFO_FUNCTION(sysvmsg)
103
143
}
104
144
/* }}} */
105
145
106
- /* {{{ proto bool msg_set_queue(resource queue, array data)
146
+ /* {{{ proto bool msg_set_queue(SysvMessageQueue queue, array data)
107
147
Set information for a message queue */
108
148
PHP_FUNCTION (msg_set_queue )
109
149
{
@@ -113,13 +153,11 @@ PHP_FUNCTION(msg_set_queue)
113
153
114
154
RETVAL_FALSE ;
115
155
116
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "ra " , & queue , & data ) == FAILURE ) {
156
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "Oa " , & queue , sysvmsg_queue_ce , & data ) == FAILURE ) {
117
157
RETURN_THROWS ();
118
158
}
119
159
120
- if ((mq = (sysvmsg_queue_t * )zend_fetch_resource (Z_RES_P (queue ), "sysvmsg queue" , le_sysvmsg )) == NULL ) {
121
- RETURN_THROWS ();
122
- }
160
+ mq = Z_SYSVMSG_QUEUE_P (queue );
123
161
124
162
if (msgctl (mq -> id , IPC_STAT , & stat ) == 0 ) {
125
163
zval * item ;
@@ -144,7 +182,7 @@ PHP_FUNCTION(msg_set_queue)
144
182
}
145
183
/* }}} */
146
184
147
- /* {{{ proto array msg_stat_queue(resource queue)
185
+ /* {{{ proto array msg_stat_queue(SysvMessageQueue queue)
148
186
Returns information about a message queue */
149
187
PHP_FUNCTION (msg_stat_queue )
150
188
{
@@ -154,13 +192,11 @@ PHP_FUNCTION(msg_stat_queue)
154
192
155
193
RETVAL_FALSE ;
156
194
157
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "r " , & queue ) == FAILURE ) {
195
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "O " , & queue , sysvmsg_queue_ce ) == FAILURE ) {
158
196
RETURN_THROWS ();
159
197
}
160
198
161
- if ((mq = (sysvmsg_queue_t * )zend_fetch_resource (Z_RES_P (queue ), "sysvmsg queue" , le_sysvmsg )) == NULL ) {
162
- RETURN_THROWS ();
163
- }
199
+ mq = Z_SYSVMSG_QUEUE_P (queue );
164
200
165
201
if (msgctl (mq -> id , IPC_STAT , & stat ) == 0 ) {
166
202
array_init (return_value );
@@ -197,7 +233,7 @@ PHP_FUNCTION(msg_queue_exists)
197
233
}
198
234
/* }}} */
199
235
200
- /* {{{ proto resource msg_get_queue(int key [, int perms])
236
+ /* {{{ proto SysvMessageQueue msg_get_queue(int key [, int perms])
201
237
Attach to a message queue */
202
238
PHP_FUNCTION (msg_get_queue )
203
239
{
@@ -209,7 +245,8 @@ PHP_FUNCTION(msg_get_queue)
209
245
RETURN_THROWS ();
210
246
}
211
247
212
- mq = (sysvmsg_queue_t * ) emalloc (sizeof (sysvmsg_queue_t ));
248
+ object_init_ex (return_value , sysvmsg_queue_ce );
249
+ mq = Z_SYSVMSG_QUEUE_P (return_value );
213
250
214
251
mq -> key = key ;
215
252
mq -> id = msgget (key , 0 );
@@ -218,28 +255,25 @@ PHP_FUNCTION(msg_get_queue)
218
255
mq -> id = msgget (key , IPC_CREAT | IPC_EXCL | perms );
219
256
if (mq -> id < 0 ) {
220
257
php_error_docref (NULL , E_WARNING , "Failed for key 0x" ZEND_XLONG_FMT ": %s" , key , strerror (errno ));
221
- efree ( mq );
258
+ zval_ptr_dtor ( return_value );
222
259
RETURN_FALSE ;
223
260
}
224
261
}
225
- ZVAL_COPY_VALUE (return_value , zend_list_insert (mq , le_sysvmsg ));
226
262
}
227
263
/* }}} */
228
264
229
- /* {{{ proto bool msg_remove_queue(resource queue)
265
+ /* {{{ proto bool msg_remove_queue(SysvMessageQueue queue)
230
266
Destroy the queue */
231
267
PHP_FUNCTION (msg_remove_queue )
232
268
{
233
269
zval * queue ;
234
270
sysvmsg_queue_t * mq = NULL ;
235
271
236
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "r " , & queue ) == FAILURE ) {
272
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "O " , & queue , sysvmsg_queue_ce ) == FAILURE ) {
237
273
RETURN_THROWS ();
238
274
}
239
275
240
- if ((mq = (sysvmsg_queue_t * )zend_fetch_resource (Z_RES_P (queue ), "sysvmsg queue" , le_sysvmsg )) == NULL ) {
241
- RETURN_THROWS ();
242
- }
276
+ mq = Z_SYSVMSG_QUEUE_P (queue );
243
277
244
278
if (msgctl (mq -> id , IPC_RMID , NULL ) == 0 ) {
245
279
RETVAL_TRUE ;
@@ -249,7 +283,7 @@ PHP_FUNCTION(msg_remove_queue)
249
283
}
250
284
/* }}} */
251
285
252
- /* {{{ proto mixed msg_receive(resource queue, int desiredmsgtype, int &msgtype, int maxsize, mixed &message [, bool unserialize=true [, int flags=0 [, int &errorcode]]])
286
+ /* {{{ proto mixed msg_receive(SysvMessageQueue queue, int desiredmsgtype, int &msgtype, int maxsize, mixed &message [, bool unserialize=true [, int flags=0 [, int &errorcode]]])
253
287
Send a message of type msgtype (must be > 0) to a message queue */
254
288
PHP_FUNCTION (msg_receive )
255
289
{
@@ -263,8 +297,8 @@ PHP_FUNCTION(msg_receive)
263
297
264
298
RETVAL_FALSE ;
265
299
266
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "rlzlz |blz" ,
267
- & queue , & desiredmsgtype , & out_msgtype , & maxsize ,
300
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "Olzlz |blz" ,
301
+ & queue , sysvmsg_queue_ce , & desiredmsgtype , & out_msgtype , & maxsize ,
268
302
& out_message , & do_unserialize , & flags , & zerrcode ) == FAILURE ) {
269
303
RETURN_THROWS ();
270
304
}
@@ -291,9 +325,7 @@ PHP_FUNCTION(msg_receive)
291
325
}
292
326
}
293
327
294
- if ((mq = (sysvmsg_queue_t * )zend_fetch_resource (Z_RES_P (queue ), "sysvmsg queue" , le_sysvmsg )) == NULL ) {
295
- RETURN_THROWS ();
296
- }
328
+ mq = Z_SYSVMSG_QUEUE_P (queue );
297
329
298
330
messagebuffer = (struct php_msgbuf * ) safe_emalloc (maxsize , 1 , sizeof (struct php_msgbuf ));
299
331
@@ -335,7 +367,7 @@ PHP_FUNCTION(msg_receive)
335
367
}
336
368
/* }}} */
337
369
338
- /* {{{ proto bool msg_send(resource queue, int msgtype, mixed message [, bool serialize=true [, bool blocking=true [, int errorcode]]])
370
+ /* {{{ proto bool msg_send(SysvMessageQueue queue, int msgtype, mixed message [, bool serialize=true [, bool blocking=true [, int errorcode]]])
339
371
Send a message of type msgtype (must be > 0) to a message queue */
340
372
PHP_FUNCTION (msg_send )
341
373
{
@@ -349,14 +381,12 @@ PHP_FUNCTION(msg_send)
349
381
350
382
RETVAL_FALSE ;
351
383
352
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "rlz |bbz" ,
353
- & queue , & msgtype , & message , & do_serialize , & blocking , & zerror ) == FAILURE ) {
384
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "Olz |bbz" ,
385
+ & queue , sysvmsg_queue_ce , & msgtype , & message , & do_serialize , & blocking , & zerror ) == FAILURE ) {
354
386
RETURN_THROWS ();
355
387
}
356
388
357
- if ((mq = (sysvmsg_queue_t * )zend_fetch_resource (Z_RES_P (queue ), "sysvmsg queue" , le_sysvmsg )) == NULL ) {
358
- RETURN_THROWS ();
359
- }
389
+ mq = Z_SYSVMSG_QUEUE_P (queue );
360
390
361
391
if (do_serialize ) {
362
392
smart_str msg_var = {0 };
0 commit comments