1 /*
2 +-----------------------------------------------------------------------------------+
3 | ZMQ extension for PHP |
4 | Copyright (c) 2010-2013, Mikko Koppanen <mkoppanen@php.net> |
5 | All rights reserved. |
6 +-----------------------------------------------------------------------------------+
7 | Redistribution and use in source and binary forms, with or without |
8 | modification, are permitted provided that the following conditions are met: |
9 | * Redistributions of source code must retain the above copyright |
10 | notice, this list of conditions and the following disclaimer. |
11 | * Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | * Neither the name of the copyright holder nor the |
15 | names of its contributors may be used to endorse or promote products |
16 | derived from this software without specific prior written permission. |
17 +-----------------------------------------------------------------------------------+
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
21 | DISCLAIMED. IN NO EVENT SHALL MIKKO KOPPANEN BE LIABLE FOR ANY |
22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 +-----------------------------------------------------------------------------------+
29 */
30
31 #include "php_zmq.h"
32 #include "php_zmq_private.h"
33 #include "php_zmq_pollset.h"
34
35 ZEND_DECLARE_MODULE_GLOBALS(php_zmq);
36
37 static zend_class_entry *php_zmq_sc_entry;
38 static zend_class_entry *php_zmq_context_sc_entry;
39 static zend_class_entry *php_zmq_socket_sc_entry;
40 static zend_class_entry *php_zmq_poll_sc_entry;
41 static zend_class_entry *php_zmq_device_sc_entry;
42
43 static zend_class_entry *php_zmq_exception_sc_entry;
44 static zend_class_entry *php_zmq_context_exception_sc_entry;
45 static zend_class_entry *php_zmq_socket_exception_sc_entry;
46 static zend_class_entry *php_zmq_poll_exception_sc_entry;
47 static zend_class_entry *php_zmq_device_exception_sc_entry;
48
49 static zend_object_handlers zmq_object_handlers;
50 static zend_object_handlers zmq_socket_object_handlers;
51 static zend_object_handlers zmq_context_object_handlers;
52 static zend_object_handlers zmq_poll_object_handlers;
53 static zend_object_handlers zmq_device_object_handlers;
54
55 #ifdef HAVE_CZMQ_2
56 static zend_class_entry *php_zmq_cert_sc_entry;
57 static zend_class_entry *php_zmq_auth_sc_entry;
58
59 static zend_class_entry *php_zmq_cert_exception_sc_entry;
60 static zend_class_entry *php_zmq_auth_exception_sc_entry;
61
62 static zend_object_handlers zmq_cert_object_handlers;
63 static zend_object_handlers zmq_auth_object_handlers;
64 #endif
65
66
67 #include "zmq_object_access.c"
68
php_zmq_context_exception_sc_entry_get()69 zend_class_entry *php_zmq_context_exception_sc_entry_get ()
70 {
71 return php_zmq_context_exception_sc_entry;
72 }
73
php_zmq_socket_exception_sc_entry_get()74 zend_class_entry *php_zmq_socket_exception_sc_entry_get ()
75 {
76 return php_zmq_socket_exception_sc_entry;
77 }
78
php_zmq_device_exception_sc_entry_get()79 zend_class_entry *php_zmq_device_exception_sc_entry_get ()
80 {
81 return php_zmq_device_exception_sc_entry;
82 }
83
84 static
php_zmq_context_socket_count_get(php_zmq_context * context)85 zend_long php_zmq_context_socket_count_get(php_zmq_context *context)
86 {
87 zend_long value = 0;
88
89 if (context->use_shared_ctx) {
90 value = php_zmq_shared_ctx_socket_count();
91 }
92 else {
93 value = context->socket_count;
94 }
95 return value;
96 }
97
98 static
php_zmq_context_socket_count_incr(php_zmq_context * context)99 void php_zmq_context_socket_count_incr(php_zmq_context *context)
100 {
101 if (context->use_shared_ctx) {
102 php_zmq_shared_ctx_socket_count_incr();
103 }
104 else {
105 context->socket_count++;
106 }
107 }
108
109 static
php_zmq_context_socket_count_decr(php_zmq_context * context)110 void php_zmq_context_socket_count_decr(php_zmq_context *context)
111 {
112 if (context->use_shared_ctx) {
113 php_zmq_shared_ctx_socket_count_decr();
114 }
115 else {
116 context->socket_count--;
117 }
118 }
119
120 /* list entries */
121 static int le_zmq_socket, le_zmq_context;
122
123 /** {{{ static int php_zmq_socket_list_entry(void)
124 */
php_zmq_socket_list_entry(void)125 static int php_zmq_socket_list_entry(void)
126 {
127 return le_zmq_socket;
128 }
129 /* }}} */
130
131 /* {{{ static int php_zmq_context_list_entry(void)
132 */
php_zmq_context_list_entry(void)133 static int php_zmq_context_list_entry(void)
134 {
135 return le_zmq_context;
136 }
137 /* }}} */
138
139 /* {{{ static void php_zmq_context_destroy(php_zmq_context *context)
140 Destroy the context
141 */
php_zmq_context_destroy(php_zmq_context * context)142 static void php_zmq_context_destroy(php_zmq_context *context)
143 {
144 if (context->pid == getpid()) {
145 (void) zmq_term(context->z_ctx);
146 }
147 pefree(context, context->is_persistent);
148 }
149 /* }}} */
150
151 /* {{{ static void php_zmq_socket_destroy(php_zmq_socket *zmq_sock)
152 Destroy the socket (note: does not touch context)
153 */
php_zmq_socket_destroy(php_zmq_socket * zmq_sock)154 static void php_zmq_socket_destroy(php_zmq_socket *zmq_sock)
155 {
156 zend_hash_destroy(&(zmq_sock->connect));
157 zend_hash_destroy(&(zmq_sock->bind));
158
159 /* Decrement socket count */
160 php_zmq_context_socket_count_decr(zmq_sock->ctx);
161
162 if (zmq_sock->pid == getpid ()) {
163 (void) zmq_close(zmq_sock->z_socket);
164 }
165 pefree(zmq_sock, zmq_sock->is_persistent);
166 }
167 /* }}} */
168
169 /* --- START ZMQContext --- */
170
171 /* {{{ static php_zmq_context *php_zmq_context_new(zend_long io_threads, zend_bool is_persistent, zend_bool use_shared_ctx)
172 Create a new zmq context
173 */
174 static
php_zmq_context_new(zend_long io_threads,zend_bool is_persistent,zend_bool use_shared_ctx)175 php_zmq_context *php_zmq_context_new(zend_long io_threads, zend_bool is_persistent, zend_bool use_shared_ctx)
176 {
177 php_zmq_context *context = pecalloc(1, sizeof(php_zmq_context), is_persistent);
178
179 if (use_shared_ctx) {
180 php_zmq_shared_ctx_assign_to(context);
181 }
182 else {
183 context->z_ctx = zmq_init(io_threads);
184 }
185
186 if (!context->z_ctx) {
187 pefree(context, is_persistent);
188 return NULL;
189 }
190
191 context->io_threads = io_threads;
192 context->is_persistent = is_persistent;
193 context->pid = getpid();
194 context->socket_count = 0;
195 context->use_shared_ctx = use_shared_ctx;
196 return context;
197 }
198 /* }}} */
199
200 /* {{{ static php_zmq_context *php_zmq_context_get(zend_long io_threads, zend_bool is_persistent)
201 */
202 static
php_zmq_context_get(zend_long io_threads,zend_bool is_persistent)203 php_zmq_context *php_zmq_context_get(zend_long io_threads, zend_bool is_persistent)
204 {
205 php_zmq_context *context;
206 zend_string *plist_key = NULL;
207
208 if (is_persistent) {
209 zend_resource *le_p = NULL;
210 plist_key = strpprintf(0, "zmq_context=[%ld]", io_threads);
211
212 if ((le_p = zend_hash_find_ptr(&EG(persistent_list), plist_key)) != NULL) {
213 if (le_p->type == php_zmq_context_list_entry()) {
214
215 if (plist_key) {
216 zend_string_release(plist_key);
217 }
218 return (php_zmq_context *) le_p->ptr;
219 }
220 }
221 }
222
223 context = php_zmq_context_new(io_threads, is_persistent, 0);
224
225 if (!context) {
226 if (plist_key) {
227 zend_string_release(plist_key);
228 }
229 return NULL;
230 }
231
232 if (is_persistent) {
233
234 zend_resource le;
235 le.type = php_zmq_context_list_entry();
236 le.ptr = context;
237
238 #if PHP_VERSION_ID < 70300
239 GC_REFCOUNT(&le) = 1;
240 #else
241 GC_SET_REFCOUNT(&le, 1);
242 #endif
243
244 /* plist_key is not a persistent allocated key, thus we use str_update here */
245 if (zend_hash_str_update_mem(&EG(persistent_list), plist_key->val, plist_key->len, &le, sizeof(le)) == NULL) {
246 if (plist_key) {
247 zend_string_release(plist_key);
248 }
249 php_error_docref(NULL, E_ERROR, "Could not register persistent entry for the context");
250 /* not reached */
251 }
252 }
253 if (plist_key) {
254 zend_string_release(plist_key);
255 }
256 return context;
257 }
258 /* }}} */
259
260 /* {{{ proto ZMQ ZMQ::__construct()
261 Private constructor
262 */
PHP_METHOD(zmq,__construct)263 PHP_METHOD(zmq, __construct) {}
264 /* }}} */
265
266 /* {{{ proto integer ZMQ::clock()
267 A monotonic clock
268 */
PHP_METHOD(zmq,clock)269 PHP_METHOD(zmq, clock)
270 {
271 if (zend_parse_parameters_none() == FAILURE) {
272 return;
273 }
274 RETURN_LONG((long) php_zmq_clock (ZMQ_G (clock_ctx)));
275 }
276 /* }}} */
277
278 #ifdef PHP_ZMQ_HAVE_Z85
279
280 /* {{{ proto string ZMQ::z85Encode(string $data)
281
282 */
PHP_METHOD(zmq,z85encode)283 PHP_METHOD(zmq, z85encode)
284 {
285 zend_string *data;
286 char *buffer;
287 size_t buffer_size;
288
289 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &data) == FAILURE) {
290 return;
291 }
292
293 if (!data->len) {
294 RETURN_NULL();
295 }
296
297 buffer_size = 5 * data->len / 4 + 1;
298 buffer = emalloc(buffer_size);
299
300 if (!zmq_z85_encode (buffer, (const uint8_t *) data->val, data->len)) {
301 efree(buffer);
302 RETURN_NULL();
303 }
304
305 RETVAL_STRINGL(buffer, buffer_size - 1);
306 efree(buffer);
307 return;
308 }
309 /* }}} */
310
311 /* {{{ proto string ZMQ::z85Decode(string $z85_encoded_data)
312
313 */
PHP_METHOD(zmq,z85decode)314 PHP_METHOD(zmq, z85decode)
315 {
316 zend_string *data;
317 uint8_t *buffer;
318 size_t buffer_size;
319
320 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &data) == FAILURE) {
321 return;
322 }
323
324 if (!data->len) {
325 RETURN_NULL();
326 }
327
328 buffer_size = 4 * data->len / 5;
329 buffer = emalloc(buffer_size);
330
331 if (!zmq_z85_decode (buffer, data->val)) {
332 efree(buffer);
333 RETURN_NULL();
334 }
335
336 RETVAL_STRINGL((char *) buffer, buffer_size);
337 efree(buffer);
338 return;
339 }
340 /* }}} */
341 #endif
342
343 #ifdef PHP_ZMQ_HAVE_CURVE_KEYPAIR
344
345 #define PHP_ZMQ_KEY_SIZE 41
346
347 /* {{{ proto array ZMQ::curveKeypair()
348
349 */
PHP_METHOD(zmq,curvekeypair)350 PHP_METHOD(zmq, curvekeypair)
351 {
352 char public_key[PHP_ZMQ_KEY_SIZE], secret_key[PHP_ZMQ_KEY_SIZE];
353
354 if (zend_parse_parameters_none() == FAILURE) {
355 return;
356 }
357
358 if (zmq_curve_keypair(public_key, secret_key) == 0) {
359 array_init(return_value);
360
361 add_assoc_stringl(return_value, "public_key", public_key, PHP_ZMQ_KEY_SIZE - 1);
362 add_assoc_stringl(return_value, "secret_key", secret_key, PHP_ZMQ_KEY_SIZE - 1);
363 }
364 }
365 /* }}} */
366
367 #endif
368
369
370 /* {{{ proto ZMQContext ZMQContext::__construct(integer $io_threads[, boolean $is_persistent = true])
371 Build a new ZMQContext object
372 */
PHP_METHOD(zmqcontext,__construct)373 PHP_METHOD(zmqcontext, __construct)
374 {
375 php_zmq_context_object *intern;
376 long io_threads = 1;
377 zend_bool is_persistent = 1;
378
379 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|lb", &io_threads, &is_persistent) == FAILURE) {
380 return;
381 }
382 intern = php_zmq_context_fetch_object(Z_OBJ_P(getThis()));
383 intern->context = php_zmq_context_get(io_threads, is_persistent);
384
385 if (!intern->context) {
386 zend_throw_exception_ex(php_zmq_context_exception_sc_entry, errno, "Error creating context: %s", zmq_strerror(errno));
387 return;
388 }
389 return;
390 }
391 /* }}} */
392
393 /* {{{ proto ZMQContext ZMQContext::acquire()
394 Acquires a handle to the process global context
395 */
PHP_METHOD(zmqcontext,acquire)396 PHP_METHOD(zmqcontext, acquire)
397 {
398 php_zmq_context *context;
399 php_zmq_context_object *intern;
400
401 if (zend_parse_parameters_none() == FAILURE) {
402 return;
403 }
404
405 context = php_zmq_context_new(1, 1, 1);
406
407 // Create a global context
408 object_init_ex(return_value, php_zmq_context_sc_entry);
409 intern = php_zmq_context_fetch_object(Z_OBJ_P(return_value));
410 intern->context = context;
411 return;
412 }
413 /* }}} */
414
415 /* {{{ proto integer ZMQContext::getSocketCount()
416 Number of active sockets in this context
417 */
PHP_METHOD(zmqcontext,getsocketcount)418 PHP_METHOD(zmqcontext, getsocketcount)
419 {
420 php_zmq_context_object *intern;
421
422 if (zend_parse_parameters_none() == FAILURE) {
423 return;
424 }
425 intern = PHP_ZMQ_CONTEXT_OBJECT;
426 RETURN_LONG(php_zmq_context_socket_count_get(intern->context));
427 }
428 /* }}} */
429
430 #ifdef PHP_ZMQ_HAVE_CTX_OPTIONS
431 /* {{{ proto ZMQContext ZMQContext::setOpt(int option, int value)
432 Set a context option
433 */
PHP_METHOD(zmqcontext,setOpt)434 PHP_METHOD(zmqcontext, setOpt)
435 {
436 php_zmq_context_object *intern;
437 zend_long option, value;
438
439 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &option, &value) == FAILURE) {
440 return;
441 }
442 intern = PHP_ZMQ_CONTEXT_OBJECT;
443
444 switch (option) {
445 case ZMQ_MAX_SOCKETS:
446 {
447 if (zmq_ctx_set(intern->context->z_ctx, option, value) != 0) {
448 zend_throw_exception_ex(php_zmq_context_exception_sc_entry_get (), errno, "Failed to set the option ZMQ::CTXOPT_MAX_SOCKETS value: %s", zmq_strerror(errno));
449 return;
450 }
451 }
452 break;
453
454 default:
455 {
456 zend_throw_exception(php_zmq_context_exception_sc_entry_get (), "Unknown option key", PHP_ZMQ_INTERNAL_ERROR);
457 return;
458 }
459 }
460 return;
461 }
462 /* }}} */
463
464 /* {{{ proto ZMQContext ZMQContext::getOpt(int option)
465 Set a context option
466 */
PHP_METHOD(zmqcontext,getOpt)467 PHP_METHOD(zmqcontext, getOpt)
468 {
469 php_zmq_context_object *intern;
470 zend_long option;
471
472 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &option) == FAILURE) {
473 return;
474 }
475 intern = PHP_ZMQ_CONTEXT_OBJECT;
476
477 switch (option) {
478
479 case ZMQ_MAX_SOCKETS:
480 {
481 int value = zmq_ctx_get(intern->context->z_ctx, option);
482 RETURN_LONG(value);
483 }
484 break;
485
486 default:
487 {
488 zend_throw_exception(php_zmq_context_exception_sc_entry_get (), "Unknown option key", PHP_ZMQ_INTERNAL_ERROR);
489 return;
490 }
491 }
492 return;
493 }
494 /* }}} */
495 #endif
496
497
498 /* {{{ static php_zmq_socket *php_zmq_socket_new(php_zmq_context *context, int type, zend_bool is_persistent)
499 Create a new zmq socket
500 */
501 static
php_zmq_socket_new(php_zmq_context * context,int type,zend_bool is_persistent)502 php_zmq_socket *php_zmq_socket_new(php_zmq_context *context, int type, zend_bool is_persistent)
503 {
504 php_zmq_socket *zmq_sock;
505
506 zmq_sock = pecalloc(1, sizeof(php_zmq_socket), is_persistent);
507 zmq_sock->z_socket = zmq_socket(context->z_ctx, type);
508 zmq_sock->pid = getpid();
509 zmq_sock->ctx = context;
510 zmq_sock->socket_type = type;
511
512 if (!zmq_sock->z_socket) {
513 pefree(zmq_sock, is_persistent);
514 return NULL;
515 }
516
517 /* Increment socket count */
518 php_zmq_context_socket_count_incr(context);
519 zmq_sock->is_persistent = is_persistent;
520
521 zend_hash_init(&(zmq_sock->connect), 0, NULL, NULL, is_persistent);
522 zend_hash_init(&(zmq_sock->bind), 0, NULL, NULL, is_persistent);
523 return zmq_sock;
524 }
525 /* }}} */
526
527 static
php_zmq_socket_plist_key(zend_long type,zend_string * persistent_id,zend_bool use_shared_ctx)528 zend_string *php_zmq_socket_plist_key(zend_long type, zend_string *persistent_id, zend_bool use_shared_ctx)
529 {
530 return strpprintf(0, "zmq_socket:[%ld]-[%s]-[%d]", type, persistent_id->val, use_shared_ctx);
531 }
532
533 static
php_zmq_socket_store(php_zmq_socket * zmq_sock_p,zend_long type,zend_string * persistent_id,zend_bool use_shared_ctx)534 void php_zmq_socket_store(php_zmq_socket *zmq_sock_p, zend_long type, zend_string *persistent_id, zend_bool use_shared_ctx)
535 {
536 zend_string *plist_key = NULL;
537
538 zend_resource le;
539 le.type = php_zmq_socket_list_entry();
540 le.ptr = zmq_sock_p;
541
542 #if PHP_VERSION_ID < 70300
543 GC_REFCOUNT(&le) = 1;
544 #else
545 GC_SET_REFCOUNT(&le, 1);
546 #endif
547
548 plist_key = php_zmq_socket_plist_key(type, persistent_id, use_shared_ctx);
549
550 /* plist_key is not a persistent allocated key, thus we use str_update here */
551 if (zend_hash_str_update_mem(&EG(persistent_list), plist_key->val, plist_key->len, &le, sizeof(le)) == NULL) {
552 if (plist_key) {
553 zend_string_release(plist_key);
554 }
555 php_error_docref(NULL, E_ERROR, "Could not register persistent entry for the socket");
556 /* not reached */
557 }
558
559 if (plist_key) {
560 zend_string_release(plist_key);
561 }
562 }
563
564 /* {{{ static php_zmq_socket *php_zmq_socket_get(php_zmq_context *context, zend_long type, zend_string *persistent_id, zend_bool *is_new)
565 Tries to get context from plist and allocates a new context if context does not exist
566 */
php_zmq_socket_get(php_zmq_context * context,zend_long type,zend_string * persistent_id,zend_bool * is_new)567 static php_zmq_socket *php_zmq_socket_get(php_zmq_context *context, zend_long type, zend_string *persistent_id, zend_bool *is_new)
568 {
569 php_zmq_socket *zmq_sock_p;
570 zend_string *plist_key = NULL;
571 zend_bool is_persistent = 0;
572
573 is_persistent = (context->is_persistent && persistent_id && persistent_id->len) ? 1 : 0;
574 *is_new = 0;
575
576 if (is_persistent) {
577 zend_resource *le_p = NULL;
578
579 plist_key = php_zmq_socket_plist_key(type, persistent_id, context->use_shared_ctx);
580
581 if ((le_p = zend_hash_find_ptr(&EG(persistent_list), plist_key)) != NULL) {
582 if (le_p->type == php_zmq_socket_list_entry()) {
583 if (plist_key) {
584 zend_string_release(plist_key);
585 }
586 return (php_zmq_socket *) le_p->ptr;
587 }
588 }
589 }
590 zmq_sock_p = php_zmq_socket_new(context, type, is_persistent);
591
592 if (plist_key) {
593 zend_string_release(plist_key);
594 }
595
596 if (!zmq_sock_p) {
597 return NULL;
598 }
599
600 *is_new = 1;
601 return zmq_sock_p;
602 }
603 /* }}} */
604
605 static
php_zmq_connect_callback(zval * socket,zend_fcall_info * fci,zend_fcall_info_cache * fci_cache,zend_string * persistent_id)606 zend_bool php_zmq_connect_callback(zval *socket, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, zend_string *persistent_id)
607 {
608 zval retval;
609 zval params[2];
610 zend_bool rv = 1;
611
612 /* Call the cb */
613 params[0] = *socket;
614
615 if (persistent_id && persistent_id->len) {
616 ZVAL_STR(¶ms[1], zend_string_copy(persistent_id));
617 } else {
618 ZVAL_NULL(¶ms[1]);
619 }
620
621 fci->params = params;
622 fci->param_count = 2;
623 fci->retval = &retval;
624 fci->no_separation = 1;
625
626 if (zend_call_function(fci, fci_cache) == FAILURE) {
627 if (!EG(exception)) {
628 char *func_name = php_zmq_printable_func(fci, fci_cache);
629 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, 0, "Failed to invoke 'on_new_socket' callback %s()", func_name);
630 efree(func_name);
631 }
632 rv = 0;
633 }
634
635 zval_ptr_dtor(¶ms[1]);
636
637 if (Z_TYPE(retval) != IS_UNDEF) {
638 zval_ptr_dtor(&retval);
639 }
640
641 if (EG(exception)) {
642 rv = 0;
643 }
644 return rv;
645 }
646
647 /* {{{ proto ZMQContext ZMQContext::getSocket(integer $type[, string $persistent_id = null[, callback $on_new_socket = null]])
648 Build a new ZMQContext object
649 */
PHP_METHOD(zmqcontext,getsocket)650 PHP_METHOD(zmqcontext, getsocket)
651 {
652 php_zmq_socket *socket;
653 php_zmq_socket_object *interns;
654 php_zmq_context_object *intern;
655 zend_long type;
656 zend_string *persistent_id = NULL;
657 int rc;
658 zend_bool is_new;
659
660 zend_fcall_info fci;
661 zend_fcall_info_cache fci_cache;
662
663 PHP_ZMQ_ERROR_HANDLING_INIT()
664 PHP_ZMQ_ERROR_HANDLING_THROW()
665
666 fci.size = 0;
667 rc = zend_parse_parameters(ZEND_NUM_ARGS(), "l|S!f!", &type, &persistent_id, &fci, &fci_cache);
668
669 PHP_ZMQ_ERROR_HANDLING_RESTORE()
670
671 if (rc == FAILURE) {
672 return;
673 }
674
675 intern = php_zmq_context_fetch_object(Z_OBJ_P(getThis()));
676 socket = php_zmq_socket_get(intern->context, type, persistent_id, &is_new);
677
678 if (!socket) {
679 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Error creating socket: %s", zmq_strerror(errno));
680 return;
681 }
682
683 object_init_ex(return_value, php_zmq_socket_sc_entry);
684 interns = php_zmq_socket_fetch_object(Z_OBJ_P(return_value));
685 interns->socket = socket;
686
687 /* Need to add refcount if context is not persistent */
688 if (!intern->context->is_persistent) {
689 ZVAL_OBJ(&interns->context_obj, &intern->zo);
690 Z_ADDREF(interns->context_obj);
691 }
692
693 if (is_new) {
694 if (fci.size) {
695 if (!php_zmq_connect_callback(return_value, &fci, &fci_cache, persistent_id)) {
696 php_zmq_socket_destroy(socket);
697 interns->socket = NULL;
698 zval_dtor(return_value);
699 return;
700 }
701 }
702 if (socket->is_persistent) {
703 php_zmq_socket_store(socket, type, persistent_id, intern->context->use_shared_ctx);
704 }
705 }
706 if (socket->is_persistent) {
707 interns->persistent_id = estrdup(persistent_id->val);
708 }
709 return;
710 }
711 /* }}} */
712
713 /* {{{ proto ZMQContext ZMQContext::isPersistent()
714 Whether the context is persistent
715 */
PHP_METHOD(zmqcontext,ispersistent)716 PHP_METHOD(zmqcontext, ispersistent)
717 {
718 php_zmq_context_object *intern;
719
720 if (zend_parse_parameters(ZEND_NUM_ARGS(), "") == FAILURE) {
721 return;
722 }
723
724 intern = PHP_ZMQ_CONTEXT_OBJECT;
725 RETURN_BOOL(intern->context->is_persistent);
726 }
727 /* }}} */
728
729 /* {{{ proto ZMQContext ZMQContext::__clone()
730 Clones the instance of the ZMQContext class
731 */
PHP_METHOD(zmqcontext,__clone)732 PHP_METHOD(zmqcontext, __clone) { }
733 /* }}} */
734
735 /* --- END ZMQContext --- */
736
737 /* --- START ZMQSocket --- */
738
739 /* {{{ proto ZMQSocket ZMQSocket::__construct(ZMQContext $context, integer $type[, string $persistent_id = null[, callback $on_new_socket = null]])
740 Build a new ZMQSocket object
741 */
PHP_METHOD(zmqsocket,__construct)742 PHP_METHOD(zmqsocket, __construct)
743 {
744 php_zmq_socket *socket;
745 php_zmq_socket_object *intern;
746 php_zmq_context_object *internc;
747 zend_long type;
748 zend_string *persistent_id = NULL;
749 int rc;
750 zval *obj;
751 zend_bool is_new;
752
753 zend_fcall_info fci;
754 zend_fcall_info_cache fci_cache;
755
756 PHP_ZMQ_ERROR_HANDLING_INIT()
757 PHP_ZMQ_ERROR_HANDLING_THROW()
758
759 fci.size = 0;
760 rc = zend_parse_parameters(ZEND_NUM_ARGS(), "Ol|S!f!", &obj, php_zmq_context_sc_entry, &type, &persistent_id, &fci, &fci_cache);
761
762 PHP_ZMQ_ERROR_HANDLING_RESTORE()
763
764 if (rc == FAILURE) {
765 return;
766 }
767
768 internc = php_zmq_context_fetch_object(Z_OBJ_P(obj));
769 socket = php_zmq_socket_get(internc->context, type, persistent_id, &is_new);
770
771 if (!socket) {
772 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Error creating socket: %s", zmq_strerror(errno));
773 return;
774 }
775
776 intern = PHP_ZMQ_SOCKET_OBJECT;
777 intern->socket = socket;
778
779 /* Need to add refcount if context is not persistent */
780 if (!internc->context->is_persistent) {
781 ZVAL_OBJ(&intern->context_obj, &internc->zo);
782 Z_ADDREF(intern->context_obj);
783 }
784
785 if (is_new) {
786 if (fci.size) {
787 if (!php_zmq_connect_callback(getThis(), &fci, &fci_cache, persistent_id)) {
788 php_zmq_socket_destroy(socket);
789 intern->socket = NULL;
790 return;
791 }
792 }
793 if (socket->is_persistent) {
794 php_zmq_socket_store(socket, type, persistent_id, internc->context->use_shared_ctx);
795 }
796 }
797 if (socket->is_persistent) {
798 intern->persistent_id = estrdup(persistent_id->val);
799 }
800
801 return;
802 }
803 /* }}} */
804
805 /* {{{ static zend_bool php_zmq_send(php_zmq_socket_object *intern, char *message_param, long flags)
806 */
php_zmq_send(php_zmq_socket_object * intern,zend_string * message_param,long flags)807 static zend_bool php_zmq_send(php_zmq_socket_object *intern, zend_string *message_param, long flags)
808 {
809 int rc, errno_;
810 zmq_msg_t message;
811
812 if (zmq_msg_init_size(&message, message_param->len) != 0) {
813 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Failed to initialize message structure: %s", zmq_strerror(errno));
814 return 0;
815 }
816 memcpy(zmq_msg_data(&message), message_param->val, message_param->len);
817
818 rc = zmq_sendmsg(intern->socket->z_socket, &message, flags);
819 errno_ = errno;
820
821 zmq_msg_close(&message);
822
823 if (rc == -1) {
824 if (errno_ == EAGAIN) {
825 return 0;
826 }
827 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno_, "Failed to send message: %s", zmq_strerror(errno_));
828 return 0;
829 }
830
831 return 1;
832 }
833 /* }}} */
834
php_zmq_sendmsg_impl(INTERNAL_FUNCTION_PARAMETERS)835 static void php_zmq_sendmsg_impl(INTERNAL_FUNCTION_PARAMETERS)
836 {
837 php_zmq_socket_object *intern;
838 zend_string *message_param;
839 long flags = 0;
840 zend_bool ret;
841
842 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &message_param, &flags) == FAILURE) {
843 return;
844 }
845 intern = PHP_ZMQ_SOCKET_OBJECT;
846 ret = php_zmq_send(intern, message_param, flags);
847
848 if (ret) {
849 ZMQ_RETURN_THIS;
850 } else {
851 RETURN_FALSE;
852 }
853 }
854
855 /* {{{ proto ZMQSocket ZMQSocket::send(string $message[, integer $flags = 0])
856 Send a message. Return true if message was sent and false on EAGAIN
857 */
PHP_METHOD(zmqsocket,send)858 PHP_METHOD(zmqsocket, send)
859 {
860 php_zmq_sendmsg_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU);
861 }
862 /* }}} */
863
864
865 static
php_zmq_send_cb(zval * zv,int num_args,va_list args,zend_hash_key * hash_key)866 int php_zmq_send_cb(zval *zv, int num_args, va_list args, zend_hash_key *hash_key)
867 {
868 php_zmq_socket_object *intern;
869 int flags, *rc, *to_send;
870
871 intern = va_arg(args, php_zmq_socket_object *);
872 flags = va_arg(args, int);
873 to_send = va_arg(args, int *);
874 rc = va_arg(args, int *);
875
876 if (--(*to_send)) {
877 flags = flags | ZMQ_SNDMORE;
878 } else {
879 flags = flags & ~ZMQ_SNDMORE;
880 }
881
882 zend_string *str = zval_get_string(zv);
883 *rc = php_zmq_send(intern, str, flags);
884
885 zend_string_release(str);
886
887 if (!*rc) {
888 return ZEND_HASH_APPLY_STOP;
889 }
890 return ZEND_HASH_APPLY_KEEP;
891 }
892
893 /* {{{ proto ZMQSocket ZMQSocket::sendmulti(arrays $messages[, integer $flags = 0])
894 Send a multipart message. Return true if message was sent and false on EAGAIN
895 */
PHP_METHOD(zmqsocket,sendmulti)896 PHP_METHOD(zmqsocket, sendmulti)
897 {
898 zval *messages;
899 php_zmq_socket_object *intern;
900 int to_send, ret = 0;
901 long flags = 0;
902
903 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|l", &messages, &flags) == FAILURE) {
904 return;
905 }
906
907 intern = PHP_ZMQ_SOCKET_OBJECT;
908 to_send = zend_hash_num_elements(Z_ARRVAL_P(messages));
909 zend_hash_apply_with_arguments(Z_ARRVAL_P(messages), (apply_func_args_t) php_zmq_send_cb, 4, intern, flags, &to_send, &ret);
910
911 if (ret) {
912 ZMQ_RETURN_THIS;
913 } else {
914 RETURN_FALSE;
915 }
916 }
917
918 /* {{{ static zend_bool php_zmq_recv(php_zmq_socket_object *intern, long flags, zval *return_value)
919 */
920 static
php_zmq_recv(php_zmq_socket_object * intern,long flags)921 zend_string *php_zmq_recv(php_zmq_socket_object *intern, long flags)
922 {
923 int rc, errno_;
924 zmq_msg_t message;
925 zend_string *str = NULL;
926
927 if (zmq_msg_init(&message) != 0) {
928 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Failed to initialize message structure: %s", zmq_strerror(errno));
929 return NULL;
930 }
931
932 rc = zmq_recvmsg(intern->socket->z_socket, &message, flags);
933 errno_ = errno;
934
935 if (rc == -1) {
936 zmq_msg_close(&message);
937 if (errno == EAGAIN) {
938 return NULL;
939 }
940 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno_, "Failed to receive message: %s", zmq_strerror(errno_));
941 return NULL;
942 }
943
944 str = zend_string_init(zmq_msg_data(&message), zmq_msg_size(&message), 1);
945 zmq_msg_close(&message);
946 return str;
947 }
948 /* }}} */
949
php_zmq_recvmsg_impl(INTERNAL_FUNCTION_PARAMETERS)950 static void php_zmq_recvmsg_impl(INTERNAL_FUNCTION_PARAMETERS)
951 {
952 zend_string *str = NULL;
953 php_zmq_socket_object *intern;
954 long flags = 0;
955
956 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &flags) == FAILURE) {
957 return;
958 }
959
960 intern = PHP_ZMQ_SOCKET_OBJECT;
961 str = php_zmq_recv(intern, flags);
962
963 if (!str) {
964 RETURN_FALSE;
965 }
966 RETURN_STR(str);
967 }
968
969 /* {{{ proto string ZMQ::recv([integer $flags = 0])
970 Receive a message
971 */
PHP_METHOD(zmqsocket,recv)972 PHP_METHOD(zmqsocket, recv)
973 {
974 php_zmq_recvmsg_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU);
975 }
976 /* }}} */
977
978 /* {{{ proto array ZMQ::recvmulti([integer $flags = 0])
979 Receive an array of message parts
980 */
PHP_METHOD(zmqsocket,recvmulti)981 PHP_METHOD(zmqsocket, recvmulti)
982 {
983 php_zmq_socket_object *intern;
984 size_t value_len;
985 long flags = 0;
986 #if ZMQ_VERSION_MAJOR < 3
987 int64_t value;
988 #else
989 int value;
990 #endif
991
992 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &flags) == FAILURE) {
993 return;
994 }
995
996 intern = PHP_ZMQ_SOCKET_OBJECT;
997 array_init(return_value);
998 value_len = sizeof (value);
999
1000 do {
1001 zend_string *part = php_zmq_recv(intern, flags);
1002 if (!part) {
1003 zval_dtor(return_value);
1004 RETURN_FALSE;
1005 }
1006 add_next_index_str(return_value, part);
1007 zmq_getsockopt(intern->socket->z_socket, ZMQ_RCVMORE, &value, &value_len);
1008 } while (value > 0);
1009
1010 return;
1011 }
1012 /* }}} */
1013
1014 #if PHP_ZMQ_HAVE_SOCKET_MONITOR
1015
1016 /* {{{ proto array ZMQ::recvevent([integer $flags = 0])
1017 Receive an event from monitor endpoint
1018 */
PHP_METHOD(zmqsocket,recvevent)1019 PHP_METHOD(zmqsocket, recvevent)
1020 {
1021 php_zmq_socket_object *intern;
1022 zend_long flags = 0;
1023 int value;
1024 uint8_t *data;
1025 uint16_t event;
1026 zend_string *metadata, *address;
1027
1028 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &flags) == FAILURE) {
1029 return;
1030 }
1031
1032 intern = PHP_ZMQ_SOCKET_OBJECT;
1033
1034 metadata = php_zmq_recv(intern, flags);
1035 if (!metadata || metadata->len != sizeof (uint16_t) + sizeof (uint32_t)) {
1036 if (metadata) {
1037 zend_string_release(metadata);
1038 }
1039 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Invalid monitor message received: %s", zmq_strerror(errno));
1040 return;
1041 }
1042 address = php_zmq_recv(intern, flags);
1043 if (!address) {
1044 zend_string_release(metadata);
1045 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Invalid monitor message received: %s", zmq_strerror(errno));
1046 return;
1047 }
1048
1049 data = (uint8_t *) metadata->val;
1050 event = *(uint16_t *) (data);
1051 value = *(uint32_t *) (data + sizeof(uint16_t));
1052
1053 array_init(return_value);
1054
1055 add_assoc_long(return_value, "event", event);
1056 add_assoc_long(return_value, "value", value);
1057 add_assoc_str(return_value, "address", address);
1058
1059 zend_string_release(metadata);
1060 return;
1061 }
1062 /* }}} */
1063
1064 /* {{{ proto ZMQSocket ZMQ::monitor(string $dsn[, integer $events = ZMQ::EVENTS_ALL])
1065 Add a monitor
1066 */
PHP_METHOD(zmqsocket,monitor)1067 PHP_METHOD(zmqsocket, monitor)
1068 {
1069 php_zmq_socket_object *intern;
1070
1071 zend_string *dsn;
1072 zend_long events = ZMQ_EVENT_ALL;
1073
1074 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &dsn, &events) == FAILURE) {
1075 return;
1076 }
1077
1078 intern = PHP_ZMQ_SOCKET_OBJECT;
1079
1080 if (zmq_socket_monitor(intern->socket->z_socket, dsn->val, events) != 0) {
1081 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Failed to add socket monitor: %s", zmq_strerror(errno));
1082 return;
1083 }
1084 ZMQ_RETURN_THIS;
1085 }
1086 /* }}} */
1087
1088 #endif
1089
1090 /** {{{ string ZMQ::getPersistentId()
1091 Returns the persistent id of the object
1092 */
PHP_METHOD(zmqsocket,getpersistentid)1093 PHP_METHOD(zmqsocket, getpersistentid)
1094 {
1095 php_zmq_socket_object *intern;
1096
1097 if (zend_parse_parameters(ZEND_NUM_ARGS(), "") == FAILURE) {
1098 return;
1099 }
1100
1101 intern = PHP_ZMQ_SOCKET_OBJECT;
1102
1103 if (intern->socket->is_persistent && intern->persistent_id) {
1104 RETURN_STRING(intern->persistent_id);
1105 }
1106 RETURN_NULL();
1107 }
1108 /* }}} */
1109
1110 /* {{{ proto ZMQSocket ZMQSocket::bind(string $dsn[, boolean $force = false])
1111 Bind the socket to an endpoint
1112 */
PHP_METHOD(zmqsocket,bind)1113 PHP_METHOD(zmqsocket, bind)
1114 {
1115 php_zmq_socket_object *intern;
1116 zend_string *dsn;
1117 zend_bool force = 0;
1118
1119 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &dsn, &force) == FAILURE) {
1120 return;
1121 }
1122
1123 intern = php_zmq_socket_fetch_object(Z_OBJ_P(getThis()));
1124
1125 /* already connected ? */
1126 if (!force && zend_hash_exists(&(intern->socket->bind), dsn)) {
1127 ZMQ_RETURN_THIS;
1128 }
1129
1130 if (zmq_bind(intern->socket->z_socket, dsn->val) != 0) {
1131 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Failed to bind the ZMQ: %s", zmq_strerror(errno));
1132 return;
1133 }
1134
1135 zend_hash_str_add_empty_element(&(intern->socket->bind), dsn->val, dsn->len);
1136 ZMQ_RETURN_THIS;
1137 }
1138 /* }}} */
1139
1140 /* {{{ proto ZMQSocket ZMQSocket::connect(string $dsn[, boolean $force = false])
1141 Connect the socket to an endpoint
1142 */
PHP_METHOD(zmqsocket,connect)1143 PHP_METHOD(zmqsocket, connect)
1144 {
1145 php_zmq_socket_object *intern;
1146 zend_string *dsn;
1147 zend_bool force = 0;
1148
1149 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &dsn, &force) == FAILURE) {
1150 return;
1151 }
1152
1153 intern = PHP_ZMQ_SOCKET_OBJECT;
1154
1155 /* already connected ? */
1156 if (!force && zend_hash_exists(&(intern->socket->connect), dsn)) {
1157 ZMQ_RETURN_THIS;
1158 }
1159
1160 if (zmq_connect(intern->socket->z_socket, dsn->val) != 0) {
1161 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Failed to connect the ZMQ: %s", zmq_strerror(errno));
1162 return;
1163 }
1164
1165 zend_hash_str_add_empty_element(&(intern->socket->connect), dsn->val, dsn->len);
1166 ZMQ_RETURN_THIS;
1167 }
1168 /* }}} */
1169
1170 #ifdef PHP_ZMQ_HAVE_UNBIND
1171 /* {{{ proto ZMQSocket ZMQSocket::unbind(string $dsn)
1172 Unbind the socket from an endpoint
1173 */
PHP_METHOD(zmqsocket,unbind)1174 PHP_METHOD(zmqsocket, unbind)
1175 {
1176 php_zmq_socket_object *intern;
1177 zend_string *dsn;
1178
1179 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &dsn) == FAILURE) {
1180 return;
1181 }
1182
1183 intern = PHP_ZMQ_SOCKET_OBJECT;
1184
1185 if (zmq_unbind(intern->socket->z_socket, dsn->val) != 0) {
1186 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Failed to unbind the ZMQ socket: %s", zmq_strerror(errno));
1187 return;
1188 }
1189
1190 zend_hash_del(&(intern->socket->bind), dsn);
1191 ZMQ_RETURN_THIS;
1192 }
1193 /* }}} */
1194 #endif
1195
1196 #ifdef PHP_ZMQ_HAVE_DISCONNECT
1197 /* {{{ proto ZMQSocket ZMQSocket::disconnect(string $dsn)
1198 Disconnect the socket from an endpoint
1199 */
PHP_METHOD(zmqsocket,disconnect)1200 PHP_METHOD(zmqsocket, disconnect)
1201 {
1202 php_zmq_socket_object *intern;
1203 zend_string *dsn;
1204
1205 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &dsn) == FAILURE) {
1206 return;
1207 }
1208
1209 intern = PHP_ZMQ_SOCKET_OBJECT;
1210
1211 if (zmq_disconnect(intern->socket->z_socket, dsn->val) != 0) {
1212 zend_throw_exception_ex(php_zmq_socket_exception_sc_entry, errno, "Failed to disconnect the ZMQ socket: %s", zmq_strerror(errno));
1213 return;
1214 }
1215
1216 zend_hash_del(&(intern->socket->connect), dsn);
1217 ZMQ_RETURN_THIS;
1218 }
1219 /* }}} */
1220 #endif
1221
1222
1223 static
php_zmq_get_keys(zval * ppzval,int num_args,va_list args,zend_hash_key * hash_key)1224 int php_zmq_get_keys(zval *ppzval, int num_args, va_list args, zend_hash_key *hash_key)
1225 {
1226 zval *retval = va_arg(args, zval *);
1227 add_next_index_string(retval, hash_key->key->val);
1228 return ZEND_HASH_APPLY_KEEP;
1229 }
1230 /* }}} */
1231
1232 /* {{{ proto array ZMQ::getEndpoints()
1233 Returns endpoints where this socket is connected/bound to. Contains two keys ('bind', 'connect')
1234 */
PHP_METHOD(zmqsocket,getendpoints)1235 PHP_METHOD(zmqsocket, getendpoints)
1236 {
1237 php_zmq_socket_object *intern;
1238 zval connect, bind;
1239
1240 if (zend_parse_parameters(ZEND_NUM_ARGS(), "") == FAILURE) {
1241 return;
1242 }
1243
1244 intern = PHP_ZMQ_SOCKET_OBJECT;
1245 array_init(return_value);
1246
1247 array_init(&connect);
1248 array_init(&bind);
1249
1250 zend_hash_apply_with_arguments(&(intern->socket->connect), (apply_func_args_t) php_zmq_get_keys, 1, &connect);
1251 zend_hash_apply_with_arguments(&(intern->socket->bind), (apply_func_args_t) php_zmq_get_keys, 1, &bind);
1252
1253 add_assoc_zval(return_value, "connect", &connect);
1254 add_assoc_zval(return_value, "bind", &bind);
1255 return;
1256 }
1257 /* }}} */
1258
1259 /* {{{ proto integer ZMQSocket::getSocketType()
1260 Returns the socket type
1261 */
PHP_METHOD(zmqsocket,getsockettype)1262 PHP_METHOD(zmqsocket, getsockettype)
1263 {
1264 int type;
1265 size_t type_siz;
1266 php_zmq_socket_object *intern;
1267
1268 if (zend_parse_parameters(ZEND_NUM_ARGS(), "") == FAILURE) {
1269 return;
1270 }
1271 intern = PHP_ZMQ_SOCKET_OBJECT;
1272 type_siz = sizeof (int);
1273
1274 if (zmq_getsockopt(intern->socket->z_socket, ZMQ_TYPE, &type, &type_siz) != -1) {
1275 RETURN_LONG(type);
1276 }
1277 RETURN_LONG(-1);
1278 }
1279 /* }}} */
1280
1281 /* {{{ proto boolean ZMQSocket::isPersistent()
1282 Whether the socket is persistent
1283 */
PHP_METHOD(zmqsocket,ispersistent)1284 PHP_METHOD(zmqsocket, ispersistent)
1285 {
1286 php_zmq_socket_object *intern;
1287
1288 if (zend_parse_parameters(ZEND_NUM_ARGS(), "") == FAILURE) {
1289 return;
1290 }
1291
1292 intern = PHP_ZMQ_SOCKET_OBJECT;
1293 RETURN_BOOL(intern->socket->is_persistent);
1294 }
1295 /* }}} */
1296
1297 /* {{{ proto ZMQSocket ZMQSocket::__clone()
1298 Clones the instance of the ZMQSocket class
1299 */
PHP_METHOD(zmqsocket,__clone)1300 PHP_METHOD(zmqsocket, __clone) { }
1301 /* }}} */
1302
1303 /* -- END ZMQSocket--- */
1304
1305 /* -- START ZMQPoll --- */
1306
1307 /* {{{ proto integer ZMQPoll::add(ZMQSocket $object, integer $events)
1308 Add a ZMQSocket object into the pollset
1309 */
PHP_METHOD(zmqpoll,add)1310 PHP_METHOD(zmqpoll, add)
1311 {
1312 php_zmq_poll_object *intern;
1313 zval *object;
1314 long events;
1315 int error;
1316 zend_string *key;
1317
1318 if (zend_parse_parameters(ZEND_NUM_ARGS(), "zl", &object, &events) == FAILURE) {
1319 return;
1320 }
1321
1322 intern = PHP_ZMQ_POLL_OBJECT;
1323
1324 switch (Z_TYPE_P(object)) {
1325 case IS_OBJECT:
1326 if (!instanceof_function(Z_OBJCE_P(object), php_zmq_socket_sc_entry)) {
1327 zend_throw_exception(php_zmq_poll_exception_sc_entry, "The first argument must be an instance of ZMQSocket or a resource", PHP_ZMQ_INTERNAL_ERROR);
1328 return;
1329 }
1330 break;
1331
1332 case IS_RESOURCE:
1333 /* noop */
1334 break;
1335
1336 default:
1337 zend_throw_exception(php_zmq_poll_exception_sc_entry, "The first argument must be an instance of ZMQSocket or a resource", PHP_ZMQ_INTERNAL_ERROR);
1338 return;
1339 break;
1340 }
1341
1342 key = php_zmq_pollset_add(intern->set, object, events, &error);
1343
1344 if (!key) {
1345 const char *message = NULL;
1346
1347 switch (error) {
1348 case PHP_ZMQ_POLLSET_ERR_NO_STREAM:
1349 message = "The supplied resource is not a valid stream resource";
1350 break;
1351
1352 case PHP_ZMQ_POLLSET_ERR_CANNOT_CAST:
1353 message = "The supplied resource is not castable";
1354 break;
1355
1356 case PHP_ZMQ_POLLSET_ERR_CAST_FAILED:
1357 message = "Failed to cast the supplied stream resource";
1358 break;
1359
1360 case PHP_ZMQ_POLLSET_ERR_NO_INIT:
1361 message = "The ZMQSocket object has not been initialized properly";
1362 break;
1363
1364 case PHP_ZMQ_POLLSET_ERR_NO_POLL:
1365 message = "The ZMQSocket object has not been initialized with polling";
1366 break;
1367
1368 default:
1369 message = "Unknown error";
1370 break;
1371 }
1372
1373 zend_throw_exception(php_zmq_poll_exception_sc_entry, message, PHP_ZMQ_INTERNAL_ERROR);
1374 return;
1375 }
1376 RETURN_STR(key);
1377 }
1378 /* }}} */
1379
1380 /* {{{ proto boolean ZMQPoll::remove(mixed $item)
1381 Remove item from poll set
1382 */
PHP_METHOD(zmqpoll,remove)1383 PHP_METHOD(zmqpoll, remove)
1384 {
1385 php_zmq_poll_object *intern;
1386 zval *item;
1387
1388 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &item) == FAILURE) {
1389 return;
1390 }
1391
1392 intern = PHP_ZMQ_POLL_OBJECT;
1393
1394 if (php_zmq_pollset_num_items(intern->set) == 0) {
1395 zend_throw_exception(php_zmq_poll_exception_sc_entry, "No sockets assigned to the ZMQPoll", PHP_ZMQ_INTERNAL_ERROR);
1396 return;
1397 }
1398
1399 switch (Z_TYPE_P(item)) {
1400
1401 case IS_OBJECT:
1402 if (!instanceof_function(Z_OBJCE_P(item), php_zmq_socket_sc_entry)) {
1403 zend_throw_exception(php_zmq_poll_exception_sc_entry, "The object must be an instanceof ZMQSocket", PHP_ZMQ_INTERNAL_ERROR);
1404 return;
1405 }
1406 /* break intentionally missing */
1407 case IS_RESOURCE:
1408 RETVAL_BOOL(php_zmq_pollset_delete(intern->set, item));
1409 break;
1410
1411 default: {
1412 zend_string *str = zval_get_string(item);
1413 zend_bool retval;
1414
1415 retval = php_zmq_pollset_delete_by_key(intern->set, str);
1416 zend_string_release(str);
1417
1418 RETVAL_BOOL(retval);
1419 } break;
1420 }
1421
1422 return;
1423 }
1424 /* }}} */
1425
1426 /* {{{ proto integer ZMQPoll::poll(array &$readable, array &$writable[, integer $timeout = -1])
1427 Poll the sockets
1428 */
PHP_METHOD(zmqpoll,poll)1429 PHP_METHOD(zmqpoll, poll)
1430 {
1431 php_zmq_poll_object *intern;
1432 zval *r_array, *w_array;
1433
1434 long timeout = -1;
1435 int rc;
1436
1437 if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!a!|l", &r_array, &w_array, &timeout) == FAILURE) {
1438 return;
1439 }
1440
1441 intern = PHP_ZMQ_POLL_OBJECT;
1442
1443 if (php_zmq_pollset_num_items(intern->set) == 0) {
1444 zend_throw_exception(php_zmq_poll_exception_sc_entry, "No sockets assigned to the ZMQPoll", PHP_ZMQ_INTERNAL_ERROR);
1445 return;
1446 }
1447
1448 rc = php_zmq_pollset_poll(intern->set, timeout * PHP_ZMQ_TIMEOUT, r_array, w_array);
1449
1450 if (rc == -1) {
1451 zend_throw_exception_ex(php_zmq_poll_exception_sc_entry, errno, "Poll failed: %s", zmq_strerror(errno));
1452 return;
1453 }
1454 RETURN_LONG(rc);
1455 }
1456 /* }}} */
1457
1458 /* {{{ proto integer ZMQPoll::count()
1459 Returns the number of items in the set
1460 */
PHP_METHOD(zmqpoll,count)1461 PHP_METHOD(zmqpoll, count)
1462 {
1463 php_zmq_poll_object *intern;
1464
1465 if (zend_parse_parameters(ZEND_NUM_ARGS(), "") == FAILURE) {
1466 return;
1467 }
1468
1469 intern = PHP_ZMQ_POLL_OBJECT;
1470 RETURN_LONG(php_zmq_pollset_num_items(intern->set));
1471 }
1472 /* }}} */
1473
1474 /* {{{ proto ZMQPoll ZMQPoll::clear()
1475 Clear the pollset
1476 */
PHP_METHOD(zmqpoll,clear)1477 PHP_METHOD(zmqpoll, clear)
1478 {
1479 php_zmq_poll_object *intern;
1480
1481 if (zend_parse_parameters(ZEND_NUM_ARGS(), "") == FAILURE) {
1482 return;
1483 }
1484
1485 intern = PHP_ZMQ_POLL_OBJECT;
1486
1487 php_zmq_pollset_clear(intern->set);
1488 ZMQ_RETURN_THIS;
1489 }
1490 /* }}} */
1491
1492 /* {{{ proto array ZMQPoll::items()
1493 Clear the pollset
1494 */
PHP_METHOD(zmqpoll,items)1495 PHP_METHOD(zmqpoll, items)
1496 {
1497 php_zmq_poll_object *intern;
1498
1499 if (zend_parse_parameters_none() == FAILURE) {
1500 return;
1501 }
1502
1503 intern = PHP_ZMQ_POLL_OBJECT;
1504
1505 array_init(return_value);
1506 php_zmq_pollset_items(intern->set, return_value);
1507 }
1508 /* }}} */
1509
1510 /* {{{ proto array ZMQPoll::getLastErrors()
1511 Returns last errors
1512 */
PHP_METHOD(zmqpoll,getlasterrors)1513 PHP_METHOD(zmqpoll, getlasterrors)
1514 {
1515 php_zmq_poll_object *intern;
1516
1517 if (zend_parse_parameters(ZEND_NUM_ARGS(), "") == FAILURE) {
1518 return;
1519 }
1520
1521 intern = PHP_ZMQ_POLL_OBJECT;
1522 RETVAL_ZVAL(php_zmq_pollset_errors(intern->set), 1, 0);
1523 return;
1524 }
1525 /* }}} */
1526
1527 /* {{{ proto ZMQPoll ZMQPoll::__clone()
1528 Clones the instance of the ZMQPoll class
1529 */
PHP_METHOD(zmqpoll,__clone)1530 PHP_METHOD(zmqpoll, __clone) { }
1531 /* }}} */
1532
1533 /* -- END ZMQPoll */
1534
1535 /* {{{ proto void ZMQDevice::__construct(ZMQSocket frontend, ZMQSocket backend)
1536 Construct a device
1537 */
PHP_METHOD(zmqdevice,__construct)1538 PHP_METHOD(zmqdevice, __construct)
1539 {
1540 php_zmq_device_object *intern;
1541 zval *f, *b, *c = NULL;
1542
1543 if (zend_parse_parameters(ZEND_NUM_ARGS(), "OO|O!", &f, php_zmq_socket_sc_entry, &b, php_zmq_socket_sc_entry, &c, php_zmq_socket_sc_entry) == FAILURE) {
1544 return;
1545 }
1546
1547 intern = PHP_ZMQ_DEVICE_OBJECT;
1548
1549 ZVAL_OBJ(&intern->front, Z_OBJ_P(f));
1550 Z_ADDREF(intern->front);
1551
1552 ZVAL_OBJ(&intern->back, Z_OBJ_P(b));
1553 Z_ADDREF(intern->back);
1554
1555 if (c) {
1556 ZVAL_OBJ(&intern->capture, Z_OBJ_P(c));
1557 Z_ADDREF(intern->capture);
1558 } else {
1559 ZVAL_UNDEF(&intern->capture);
1560 }
1561 }
1562 /* }}} */
1563
1564 /* {{{ proto void ZMQDevice::run()
1565 Start a device
1566 */
PHP_METHOD(zmqdevice,run)1567 PHP_METHOD(zmqdevice, run)
1568 {
1569 php_zmq_device_object *intern;
1570 zend_bool rc;
1571
1572 if (zend_parse_parameters_none() == FAILURE) {
1573 return;
1574 }
1575
1576 intern = PHP_ZMQ_DEVICE_OBJECT;
1577 rc = php_zmq_device (intern);
1578
1579 if (!rc && !EG (exception)) {
1580 zend_throw_exception_ex(php_zmq_device_exception_sc_entry, errno, "Failed to start the device: %s", zmq_strerror (errno));
1581 return;
1582 }
1583 return;
1584 }
1585 /* }}} */
1586
1587 static
s_clear_device_callback(php_zmq_device_cb_t * cb)1588 void s_clear_device_callback (php_zmq_device_cb_t *cb)
1589 {
1590 if (cb->initialized) {
1591 zval_ptr_dtor(&cb->fci.function_name);
1592 cb->fci.size = 0;
1593
1594 if (!Z_ISUNDEF(cb->user_data)) {
1595 zval_ptr_dtor(&cb->user_data);
1596 }
1597 memset (cb, 0, sizeof (php_zmq_device_cb_t));
1598 cb->initialized = 0;
1599 }
1600 }
1601
1602 static
s_init_device_callback(php_zmq_device_cb_t * cb,zend_fcall_info * fci,zend_fcall_info_cache * fci_cache,long timeout,zval * user_data)1603 void s_init_device_callback (php_zmq_device_cb_t *cb, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, long timeout, zval *user_data)
1604 {
1605 memcpy (&cb->fci, fci, sizeof (zend_fcall_info));
1606 memcpy (&cb->fci_cache, fci_cache, sizeof (zend_fcall_info_cache));
1607
1608 Z_TRY_ADDREF (fci->function_name);
1609 cb->initialized = 1;
1610 cb->scheduled_at = php_zmq_clock (ZMQ_G (clock_ctx)) + timeout;
1611 cb->timeout = timeout;
1612
1613 if (user_data) {
1614 ZVAL_COPY(&cb->user_data, user_data);
1615 } else {
1616 ZVAL_NULL(&cb->user_data);
1617 }
1618 }
1619
1620 /* {{{ proto void ZMQDevice::setIdleTimeout (int $milliseconds)
1621 Set the idle timeout value
1622 */
PHP_METHOD(zmqdevice,setidletimeout)1623 PHP_METHOD(zmqdevice, setidletimeout)
1624 {
1625 php_zmq_device_object *intern;
1626 long timeout;
1627
1628 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &timeout) == FAILURE) {
1629 return;
1630 }
1631
1632 intern = PHP_ZMQ_DEVICE_OBJECT;
1633 intern->idle_cb.timeout = timeout;
1634 ZMQ_RETURN_THIS;
1635
1636 }
1637 /* }}} */
1638
PHP_METHOD(zmqdevice,getidletimeout)1639 PHP_METHOD(zmqdevice, getidletimeout)
1640 {
1641 php_zmq_device_object *intern;
1642
1643 if (zend_parse_parameters_none() == FAILURE) {
1644 return;
1645 }
1646
1647 intern = PHP_ZMQ_DEVICE_OBJECT;
1648 RETURN_LONG(intern->idle_cb.timeout);
1649 }
1650
1651
PHP_METHOD(zmqdevice,settimertimeout)1652 PHP_METHOD(zmqdevice, settimertimeout)
1653 {
1654 php_zmq_device_object *intern;
1655 long timeout;
1656
1657 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &timeout) == FAILURE) {
1658 return;
1659 }
1660
1661 intern = PHP_ZMQ_DEVICE_OBJECT;
1662 intern->timer_cb.timeout = timeout;
1663 ZMQ_RETURN_THIS;
1664 }
1665
PHP_METHOD(zmqdevice,gettimertimeout)1666 PHP_METHOD(zmqdevice, gettimertimeout)
1667 {
1668 php_zmq_device_object *intern;
1669
1670 if (zend_parse_parameters_none() == FAILURE) {
1671 return;
1672 }
1673
1674 intern = PHP_ZMQ_DEVICE_OBJECT;
1675 RETURN_LONG(intern->timer_cb.timeout);
1676 }
1677
1678 /* {{{ proto void ZMQDevice::setIdleCallback (callable $function, integer timeout [, mixed $userdata])
1679 Set the idle timeout value
1680 */
PHP_METHOD(zmqdevice,setidlecallback)1681 PHP_METHOD(zmqdevice, setidlecallback)
1682 {
1683 php_zmq_device_object *intern;
1684 zval *user_data = NULL;
1685 zend_fcall_info fci;
1686 zend_fcall_info_cache fci_cache;
1687 long timeout = 0;
1688
1689 if (ZEND_NUM_ARGS() == 2) {
1690 php_error_docref(NULL, E_DEPRECATED, "The signature for setIdleCallback has changed, please update your code");
1691 if (zend_parse_parameters(ZEND_NUM_ARGS(), "f|z!", &fci, &fci_cache, &user_data) == FAILURE) {
1692 return;
1693 }
1694 }
1695 else {
1696 if (zend_parse_parameters(ZEND_NUM_ARGS(), "fl|z!", &fci, &fci_cache, &timeout, &user_data) == FAILURE) {
1697 return;
1698 }
1699 }
1700
1701 intern = PHP_ZMQ_DEVICE_OBJECT;
1702
1703 /* Hack for backwards compatible behaviour */
1704 if (!timeout) {
1705 if (intern->idle_cb.timeout) {
1706 timeout = intern->idle_cb.timeout;
1707 }
1708 }
1709
1710 s_clear_device_callback (&intern->idle_cb);
1711
1712 if (fci.size > 0) {
1713 s_init_device_callback (&intern->idle_cb, &fci, &fci_cache, timeout, user_data);
1714 }
1715 ZMQ_RETURN_THIS;
1716
1717 }
1718 /* }}} */
1719
1720 /* {{{ proto void ZMQDevice::setTimerCallback (callable $function, integer timeout [, mixed $userdata])
1721 Set the timer function
1722 */
PHP_METHOD(zmqdevice,settimercallback)1723 PHP_METHOD(zmqdevice, settimercallback)
1724 {
1725 php_zmq_device_object *intern;
1726 zval *user_data = NULL;
1727 zend_fcall_info fci;
1728 zend_fcall_info_cache fci_cache;
1729 long timeout;
1730
1731 if (zend_parse_parameters(ZEND_NUM_ARGS(), "fl|z!", &fci, &fci_cache, &timeout, &user_data) == FAILURE) {
1732 return;
1733 }
1734
1735 intern = PHP_ZMQ_DEVICE_OBJECT;
1736
1737 s_clear_device_callback (&intern->timer_cb);
1738 if (fci.size > 0) {
1739 s_init_device_callback (&intern->timer_cb, &fci, &fci_cache, timeout, user_data);
1740 }
1741 ZMQ_RETURN_THIS;
1742 }
1743 /* }}} */
1744
1745 /* {{{ proto ZMQDevice ZMQDevice::__clone()
1746 Clones the instance of the ZMQDevice class
1747 */
PHP_METHOD(zmqdevice,__clone)1748 PHP_METHOD(zmqdevice, __clone) { }
1749 /* }}} */
1750
1751 /* -- END ZMQPoll */
1752
1753 #ifdef HAVE_CZMQ_2
1754
1755 /* --- START q --- */
1756
1757 static
php_zmq_cert_object_free_storage(zend_object * object)1758 void php_zmq_cert_object_free_storage(zend_object *object)
1759 {
1760 php_zmq_cert_object *intern = php_zmq_cert_fetch_object(object);
1761
1762 if (!intern) {
1763 return;
1764 }
1765
1766 if (intern->zcert) {
1767 zcert_destroy(&intern->zcert);
1768 }
1769 zend_object_std_dtor(&intern->zo);
1770 }
1771
1772 static
php_zmq_cert_new(zend_class_entry * class_type)1773 zend_object *php_zmq_cert_new(zend_class_entry *class_type)
1774 {
1775 php_zmq_cert_object *intern = ecalloc(1, sizeof(php_zmq_cert_object) + zend_object_properties_size(class_type));
1776
1777 /* zcert is initialised in ZMQCert#__construct. */
1778 intern->zcert = NULL;
1779
1780 zend_object_std_init(&intern->zo, class_type);
1781 object_properties_init(&intern->zo, class_type);
1782
1783 intern->zo.handlers = &zmq_cert_object_handlers;
1784 return &intern->zo;
1785 }
1786
PHP_METHOD(zmqcert,__construct)1787 PHP_METHOD(zmqcert, __construct)
1788 {
1789 zend_string *filename = NULL;
1790 zend_error_handling error_handling;
1791 int parse_parameters_result;
1792 php_zmq_cert_object *intern;
1793
1794 zend_replace_error_handling(EH_THROW, php_zmq_cert_exception_sc_entry, &error_handling);
1795 parse_parameters_result = zend_parse_parameters(ZEND_NUM_ARGS(), "|S", &filename);
1796 zend_restore_error_handling(&error_handling);
1797
1798 if (parse_parameters_result != SUCCESS) {
1799 return;
1800 }
1801
1802 intern = PHP_ZMQ_CERT_OBJECT;
1803
1804 if (!filename) {
1805 intern->zcert = zcert_new();
1806
1807 if (!intern->zcert) {
1808 zend_throw_exception_ex(php_zmq_cert_exception_sc_entry, PHP_ZMQ_INTERNAL_ERROR, "Failed to create the underlying zcert object. Is libsodium installed?", filename);
1809 }
1810 return;
1811 }
1812
1813 intern->zcert = zcert_load(filename->val);
1814
1815 if (!intern->zcert) {
1816 zend_throw_exception_ex(php_zmq_cert_exception_sc_entry, PHP_ZMQ_INTERNAL_ERROR, "Failed to load the certificate from %s", filename->val);
1817 }
1818
1819 return;
1820 }
1821
1822 ZEND_BEGIN_ARG_INFO_EX(zmqcert___construct_args, 0, 0, 0)
1823 ZEND_ARG_INFO(0, filename)
1824 ZEND_END_ARG_INFO();
1825
PHP_METHOD(zmqcert,getPublicKey)1826 PHP_METHOD(zmqcert, getPublicKey)
1827 {
1828 php_zmq_cert_object *intern;
1829 byte *public_key;
1830
1831 if (zend_parse_parameters_none() != SUCCESS) {
1832 return;
1833 }
1834
1835 intern = PHP_ZMQ_CERT_OBJECT;
1836 public_key = zcert_public_key(intern->zcert);
1837
1838 if (!public_key) {
1839 RETURN_NULL();
1840 }
1841 RETURN_STRINGL((char *) public_key, 32);
1842 }
1843
1844 ZEND_BEGIN_ARG_INFO_EX(zmqcert_getPublicKey_args, 0, 0, 0)
ZEND_END_ARG_INFO()1845 ZEND_END_ARG_INFO()
1846
1847 PHP_METHOD(zmqcert, getSecretKey)
1848 {
1849 php_zmq_cert_object *intern;
1850 byte *secret_key;
1851
1852 if (zend_parse_parameters_none() != SUCCESS) {
1853 return;
1854 }
1855
1856 intern = PHP_ZMQ_CERT_OBJECT;
1857 secret_key = zcert_secret_key(intern->zcert);
1858
1859 if (!secret_key) {
1860 RETURN_NULL();
1861 }
1862 RETURN_STRINGL((char *) secret_key, 32);
1863 }
1864
1865 ZEND_BEGIN_ARG_INFO_EX(zmqcert_getSecretKey_args, 0, 0, 0)
ZEND_END_ARG_INFO()1866 ZEND_END_ARG_INFO()
1867
1868 PHP_METHOD(zmqcert, getPublicTxt)
1869 {
1870 php_zmq_cert_object *intern;
1871 char *public_txt;
1872
1873 if (zend_parse_parameters_none() != SUCCESS) {
1874 return;
1875 }
1876
1877 intern = PHP_ZMQ_CERT_OBJECT;
1878 public_txt = zcert_public_txt(intern->zcert);
1879
1880 if (!public_txt) {
1881 RETURN_NULL();
1882 }
1883 RETURN_STRING(public_txt);
1884 }
1885
1886 ZEND_BEGIN_ARG_INFO_EX(zmqcert_getPublicTxt_args, 0, 0, 0)
ZEND_END_ARG_INFO()1887 ZEND_END_ARG_INFO()
1888
1889 PHP_METHOD(zmqcert, getSecretTxt)
1890 {
1891 php_zmq_cert_object *intern;
1892 char *secret_txt;
1893
1894 if (zend_parse_parameters_none() != SUCCESS) {
1895 return;
1896 }
1897
1898 intern = PHP_ZMQ_CERT_OBJECT;
1899 secret_txt = zcert_secret_txt(intern->zcert);
1900
1901 if (!secret_txt) {
1902 RETURN_NULL();
1903 }
1904 RETURN_STRING(secret_txt);
1905 }
1906
1907 ZEND_BEGIN_ARG_INFO_EX(zmqcert_getSecretTxt_args, 0, 0, 0)
ZEND_END_ARG_INFO()1908 ZEND_END_ARG_INFO()
1909
1910 PHP_METHOD(zmqcert, setMeta)
1911 {
1912 php_zmq_cert_object *intern;
1913 zend_string *name;
1914 zend_string *format;
1915
1916 if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &name, &format) != SUCCESS) {
1917 return;
1918 }
1919
1920 intern = PHP_ZMQ_CERT_OBJECT;
1921 zcert_set_meta(intern->zcert, name->val, format->val);
1922
1923 return;
1924 }
1925
1926 ZEND_BEGIN_ARG_INFO_EX(zmqcert_setMeta_args, 0, 0, 2)
1927 ZEND_ARG_INFO(0, name)
1928 ZEND_ARG_INFO(0, format)
ZEND_END_ARG_INFO()1929 ZEND_END_ARG_INFO()
1930
1931 PHP_METHOD(zmqcert, getMeta)
1932 {
1933 zend_string *name;
1934 php_zmq_cert_object *intern;
1935 char *result;
1936
1937 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) != SUCCESS) {
1938 return;
1939 }
1940
1941 intern = PHP_ZMQ_CERT_OBJECT;
1942 result = zcert_meta(intern->zcert, name->val);
1943
1944 if (!result) {
1945 RETURN_NULL();
1946 }
1947 RETURN_STRING(result);
1948 }
1949
1950 ZEND_BEGIN_ARG_INFO_EX(zmqcert_getMeta_args, 0, 0, 1)
1951 ZEND_ARG_INFO(0, name)
ZEND_END_ARG_INFO()1952 ZEND_END_ARG_INFO()
1953
1954 PHP_METHOD(zmqcert, getMetaKeys)
1955 {
1956 php_zmq_cert_object *intern;
1957 zlist_t *meta_keys;
1958 char *meta_key;
1959
1960 if (zend_parse_parameters_none() != SUCCESS) {
1961 return;
1962 }
1963
1964 intern = PHP_ZMQ_CERT_OBJECT;
1965
1966 meta_keys = zcert_meta_keys(intern->zcert);
1967 meta_key = (char *) zlist_first(meta_keys);
1968
1969 array_init(return_value);
1970 while (meta_key) {
1971 add_next_index_string(return_value, meta_key);
1972 meta_key = zlist_next(meta_keys);
1973 }
1974
1975 return;
1976 }
1977
1978 ZEND_BEGIN_ARG_INFO_EX(zmqcert_getMetaKeys_args, 0, 0, 0)
ZEND_END_ARG_INFO()1979 ZEND_END_ARG_INFO()
1980
1981 PHP_METHOD(zmqcert, save)
1982 {
1983 php_zmq_cert_object *intern;
1984 zend_string *filename;
1985
1986 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &filename) != SUCCESS) {
1987 return;
1988 }
1989
1990 intern = PHP_ZMQ_CERT_OBJECT;
1991
1992 if (zcert_save(intern->zcert, filename->val) == -1) {
1993 zend_throw_exception_ex(php_zmq_cert_exception_sc_entry, PHP_ZMQ_INTERNAL_ERROR, "Failed to save the certificate to %s", filename->val);
1994 }
1995
1996 return;
1997 }
1998
1999 ZEND_BEGIN_ARG_INFO_EX(zmqcert_save_args, 0, 0, 1)
2000 ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()2001 ZEND_END_ARG_INFO()
2002
2003 PHP_METHOD(zmqcert, savePublic)
2004 {
2005 zend_string *filename;
2006 php_zmq_cert_object *intern;
2007
2008 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &filename) != SUCCESS) {
2009 return;
2010 }
2011
2012 intern = PHP_ZMQ_CERT_OBJECT;
2013
2014 if (zcert_save_public(intern->zcert, filename->val) == -1) {
2015 zend_throw_exception_ex(php_zmq_cert_exception_sc_entry, PHP_ZMQ_INTERNAL_ERROR, "Failed to save the public certificate to %s", filename->val);
2016 }
2017
2018 return;
2019 }
2020
2021 ZEND_BEGIN_ARG_INFO_EX(zmqcert_savePublic_args, 0, 0, 1)
2022 ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()2023 ZEND_END_ARG_INFO()
2024
2025 PHP_METHOD(zmqcert, saveSecret)
2026 {
2027 zend_string *filename;
2028 php_zmq_cert_object *intern;
2029
2030 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &filename) != SUCCESS) {
2031 return;
2032 }
2033
2034 intern = PHP_ZMQ_CERT_OBJECT;
2035
2036 if (zcert_save_secret(intern->zcert, filename->val) == -1) {
2037 zend_throw_exception_ex(php_zmq_cert_exception_sc_entry, PHP_ZMQ_INTERNAL_ERROR, "Failed to save the secret certificate to %s", filename->val);
2038 }
2039
2040 return;
2041 }
2042
2043 ZEND_BEGIN_ARG_INFO_EX(zmqcert_saveSecret_args, 0, 0, 1)
2044 ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()2045 ZEND_END_ARG_INFO()
2046
2047 PHP_METHOD(zmqcert, apply)
2048 {
2049 php_zmq_cert_object *intern;
2050 zval *object;
2051
2052 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &object, php_zmq_socket_sc_entry) != SUCCESS) {
2053 return;
2054 }
2055
2056 intern = PHP_ZMQ_CERT_OBJECT;
2057 zcert_apply(intern->zcert, php_zmq_socket_fetch_object(Z_OBJ_P(object))->socket->z_socket);
2058 }
2059
2060 ZEND_BEGIN_ARG_INFO_EX(zmqcert_apply_args, 0, 0, 1)
2061 ZEND_ARG_OBJ_INFO(0, ZMQSocket, ZMQSocket, 0)
ZEND_END_ARG_INFO()2062 ZEND_END_ARG_INFO()
2063
2064 static
2065 zend_object *php_zmq_cert_clone(zval *object)
2066 {
2067 zend_object *result;
2068 php_zmq_cert_object *intern;
2069 php_zmq_cert_object *that;
2070
2071 intern = php_zmq_cert_fetch_object(Z_OBJ_P(object));
2072 result = php_zmq_cert_new(php_zmq_cert_sc_entry);
2073
2074 that = php_zmq_cert_fetch_object(result);
2075 that->zcert = zcert_dup(intern->zcert);
2076 return result;
2077 }
2078
PHP_METHOD(zmqcert,equals)2079 PHP_METHOD(zmqcert, equals)
2080 {
2081 php_zmq_cert_object *intern;
2082 zval *object;
2083 php_zmq_cert_object *that;
2084
2085 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &object, php_zmq_cert_sc_entry) != SUCCESS) {
2086 return;
2087 }
2088
2089 intern = PHP_ZMQ_CERT_OBJECT;
2090 that = php_zmq_cert_fetch_object(Z_OBJ_P(object));
2091
2092 RETURN_BOOL(zcert_eq(intern->zcert, that->zcert) == 1);
2093 }
2094
2095 ZEND_BEGIN_ARG_INFO_EX(zmqcert_equals_args, 0, 0, 1)
2096 ZEND_ARG_OBJ_INFO(0, ZMQCert, ZMQCert, 0)
2097 ZEND_END_ARG_INFO()
2098
2099 static zend_function_entry php_zmq_cert_class_methods[] = {
2100 PHP_ME(zmqcert, __construct, zmqcert___construct_args, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
2101 PHP_ME(zmqcert, getPublicKey, zmqcert_getPublicKey_args, ZEND_ACC_PUBLIC)
2102 PHP_ME(zmqcert, getSecretKey, zmqcert_getSecretKey_args, ZEND_ACC_PUBLIC)
2103 PHP_ME(zmqcert, getPublicTxt, zmqcert_getPublicTxt_args, ZEND_ACC_PUBLIC)
2104 PHP_ME(zmqcert, getSecretTxt, zmqcert_getSecretTxt_args, ZEND_ACC_PUBLIC)
2105 PHP_ME(zmqcert, setMeta, zmqcert_setMeta_args, ZEND_ACC_PUBLIC)
2106 PHP_ME(zmqcert, getMeta, zmqcert_getMeta_args, ZEND_ACC_PUBLIC)
2107 PHP_ME(zmqcert, getMetaKeys, zmqcert_getMetaKeys_args, ZEND_ACC_PUBLIC)
2108 PHP_ME(zmqcert, save, zmqcert_save_args, ZEND_ACC_PUBLIC)
2109 PHP_ME(zmqcert, savePublic, zmqcert_savePublic_args, ZEND_ACC_PUBLIC)
2110 PHP_ME(zmqcert, saveSecret, zmqcert_saveSecret_args, ZEND_ACC_PUBLIC)
2111 PHP_ME(zmqcert, apply, zmqcert_apply_args, ZEND_ACC_PUBLIC)
2112 /* PHP_ME(zmqcert, __clone, zmqcert___clone_args, ZEND_ACC_PUBLIC) */
2113 PHP_ME(zmqcert, equals, zmqcert_equals_args, ZEND_ACC_PUBLIC)
2114 {NULL, NULL, NULL}
2115 };
2116
2117 /* --- END ZMQCert --- */
2118
2119 /* --- START ZMQAuth --- */
2120
2121 static
php_zmq_auth_object_free_storage(zend_object * object)2122 void php_zmq_auth_object_free_storage(zend_object *object)
2123 {
2124 php_zmq_auth_object *intern = php_zmq_auth_fetch_object(object);
2125
2126 if (!intern) {
2127 return;
2128 }
2129
2130 if (intern->zauth) {
2131 zauth_destroy(&intern->zauth);
2132 }
2133 if (intern->shadow_context) {
2134 zctx_destroy(&intern->shadow_context);
2135 }
2136 zend_object_std_dtor(&intern->zo);
2137 }
2138
2139 static
php_zmq_auth_new(zend_class_entry * class_type)2140 zend_object *php_zmq_auth_new(zend_class_entry *class_type)
2141 {
2142 php_zmq_auth_object *intern = ecalloc(1, sizeof(php_zmq_auth_object) + zend_object_properties_size(class_type));
2143
2144 /* zcert is initialised in ZMQCert#__construct. */
2145 intern->zauth = NULL;
2146
2147 zend_object_std_init(&intern->zo, class_type);
2148 object_properties_init(&intern->zo, class_type);
2149
2150 intern->zo.handlers = &zmq_auth_object_handlers;
2151 return &intern->zo;
2152 }
2153
PHP_METHOD(zmqauth,__construct)2154 PHP_METHOD(zmqauth, __construct)
2155 {
2156 php_zmq_auth_object *intern;
2157 zval *object;
2158 zend_error_handling error_handling;
2159 int parse_parameters_result;
2160 php_zmq_context_object *context_object;
2161
2162 zend_replace_error_handling(EH_THROW, php_zmq_cert_exception_sc_entry, &error_handling);
2163 parse_parameters_result = zend_parse_parameters(ZEND_NUM_ARGS(), "O", &object, php_zmq_context_sc_entry);
2164 zend_restore_error_handling(&error_handling);
2165
2166 if (parse_parameters_result != SUCCESS) {
2167 return;
2168 }
2169
2170 intern = PHP_ZMQ_AUTH_OBJECT;
2171
2172 context_object = php_zmq_context_fetch_object(Z_OBJ_P(object));
2173
2174 // NOTE (phuedx, 2014-05-14): A zauth object needs a context so that it
2175 // can take over authentication for all incoming connections in that
2176 // context. Creating a shadow context from the specified context allows
2177 // us to continue working with CZMQ.
2178 intern->shadow_context = zctx_shadow_zmq_ctx(context_object->context->z_ctx);
2179
2180 if (!intern->shadow_context) {
2181 zend_throw_exception_ex(php_zmq_auth_exception_sc_entry, PHP_ZMQ_INTERNAL_ERROR, "Failed to create the underlying shadow context object.");
2182 return;
2183 }
2184
2185 intern->zauth = zauth_new(intern->shadow_context);
2186
2187 if (!intern->zauth) {
2188 zctx_destroy(&intern->shadow_context);
2189 zend_throw_exception_ex(php_zmq_auth_exception_sc_entry, PHP_ZMQ_INTERNAL_ERROR, "Failed to create the underlying zauth object.");
2190 }
2191 return;
2192 }
2193
2194 ZEND_BEGIN_ARG_INFO_EX(zmqauth___construct_args, 0, 0, 1)
2195 ZEND_ARG_OBJ_INFO(0, ZMQContext, ZMQContext, 0)
2196 ZEND_END_ARG_INFO();
2197
PHP_METHOD(zmqauth,allow)2198 PHP_METHOD(zmqauth, allow)
2199 {
2200 zend_string *address;
2201 php_zmq_auth_object *intern;
2202
2203 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &address) != SUCCESS) {
2204 return;
2205 }
2206
2207 intern = PHP_ZMQ_AUTH_OBJECT;
2208 zauth_allow(intern->zauth, address->val);
2209 RETURN_ZVAL(getThis(), 1, 0);
2210 }
2211
2212 ZEND_BEGIN_ARG_INFO_EX(zmqauth_allow_args, 0, 0, 1)
2213 ZEND_ARG_INFO(0, address)
2214 ZEND_END_ARG_INFO();
2215
PHP_METHOD(zmqauth,deny)2216 PHP_METHOD(zmqauth, deny)
2217 {
2218 zend_string *address;
2219 php_zmq_auth_object *intern;
2220
2221 if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &address) != SUCCESS) {
2222 return;
2223 }
2224
2225 intern = PHP_ZMQ_AUTH_OBJECT;
2226 zauth_deny(intern->zauth, address->val);
2227 RETURN_ZVAL(getThis(), 1, 0);
2228 }
2229
2230 ZEND_BEGIN_ARG_INFO_EX(zmqauth_deny_args, 0, 0, 1)
2231 ZEND_ARG_INFO(0, address)
2232 ZEND_END_ARG_INFO();
2233
PHP_METHOD(zmqauth,configure)2234 PHP_METHOD(zmqauth, configure)
2235 {
2236 php_zmq_auth_object *intern;
2237 zend_long type;
2238 zend_string *domain;
2239 zend_string *filename;
2240
2241 intern = PHP_ZMQ_AUTH_OBJECT
2242
2243 if (zend_parse_parameters(ZEND_NUM_ARGS(), "lSS", &type, &domain, &filename) != SUCCESS) {
2244 return;
2245 }
2246
2247 intern = PHP_ZMQ_AUTH_OBJECT;
2248
2249 switch (type) {
2250 case PHP_ZMQ_AUTH_TYPE_PLAIN:
2251 zauth_configure_plain(intern->zauth, domain->val, filename->val);
2252 break;
2253
2254 case PHP_ZMQ_AUTH_TYPE_CURVE:
2255 zauth_configure_curve(intern->zauth, domain->val, filename->val);
2256 break;
2257
2258 // TODO (phuedx, 2014-05-16): CZMQ now supports GSSAPI (see
2259 // zauth_configure_gssapi).
2260
2261 default:
2262 zend_throw_exception_ex(php_zmq_auth_exception_sc_entry, PHP_ZMQ_INTERNAL_ERROR, "Unknown auth type. Are you using one of the ZMQAuth constants?");
2263 break;
2264 }
2265
2266 RETURN_ZVAL(getThis(), 1, 0);
2267 }
2268
2269 ZEND_BEGIN_ARG_INFO_EX(zmqauth_configure_args, 0, 0, 3)
2270 ZEND_ARG_INFO(0, type)
2271 ZEND_ARG_INFO(0, domain)
2272 ZEND_ARG_INFO(0, filename)
2273 ZEND_END_ARG_INFO();
2274
2275 static zend_function_entry php_zmq_auth_class_methods[] = {
2276 PHP_ME(zmqauth, __construct, zmqauth___construct_args, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
2277 PHP_ME(zmqauth, allow, zmqauth_allow_args, ZEND_ACC_PUBLIC)
2278 PHP_ME(zmqauth, deny, zmqauth_deny_args, ZEND_ACC_PUBLIC)
2279 PHP_ME(zmqauth, configure, zmqauth_configure_args, ZEND_ACC_PUBLIC)
2280 {NULL, NULL, NULL}
2281 };
2282
2283 /* --- END ZMQAuth --- */
2284
2285 #endif // HAVE_CZMQ_2
2286
2287 ZEND_BEGIN_ARG_INFO_EX(zmq_construct_args, 0, 0, 0)
2288 ZEND_END_ARG_INFO()
2289
2290 ZEND_BEGIN_ARG_INFO_EX(zmq_clock_args, 0, 0, 0)
2291 ZEND_END_ARG_INFO()
2292
2293 #ifdef PHP_ZMQ_HAVE_Z85
2294
2295 ZEND_BEGIN_ARG_INFO_EX(zmq_z85encode_args, 0, 0, 1)
2296 ZEND_ARG_INFO(0, data)
2297 ZEND_END_ARG_INFO()
2298
2299 ZEND_BEGIN_ARG_INFO_EX(zmq_z85decode_args, 0, 0, 1)
2300 ZEND_ARG_INFO(0, data)
2301 ZEND_END_ARG_INFO()
2302
2303 #endif
2304
2305 #ifdef PHP_ZMQ_HAVE_CURVE_KEYPAIR
2306 ZEND_BEGIN_ARG_INFO_EX(zmq_curvekeypair_args, 0, 0, 0)
2307 ZEND_END_ARG_INFO()
2308 #endif
2309
2310 static zend_function_entry php_zmq_class_methods[] = {
2311 PHP_ME(zmq, __construct, zmq_construct_args, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
2312 PHP_ME(zmq, clock, zmq_clock_args, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
2313 #ifdef PHP_ZMQ_HAVE_Z85
2314 PHP_ME(zmq, z85encode, zmq_z85encode_args, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
2315 PHP_ME(zmq, z85decode, zmq_z85decode_args, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
2316 #endif
2317 #ifdef PHP_ZMQ_HAVE_CURVE_KEYPAIR
2318 PHP_ME(zmq, curvekeypair, zmq_curvekeypair_args, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
2319 #endif
2320 {NULL, NULL, NULL}
2321 };
2322
2323 ZEND_BEGIN_ARG_INFO_EX(zmq_context_construct_args, 0, 0, 0)
2324 ZEND_ARG_INFO(0, io_threads)
2325 ZEND_ARG_INFO(0, persistent)
2326 ZEND_END_ARG_INFO()
2327
2328 ZEND_BEGIN_ARG_INFO_EX(zmq_context_acquire_args, 0, 0, 0)
2329 ZEND_END_ARG_INFO()
2330
2331 ZEND_BEGIN_ARG_INFO_EX(zmq_context_getsocketcount_args, 0, 0, 0)
2332 ZEND_END_ARG_INFO()
2333
2334 ZEND_BEGIN_ARG_INFO_EX(zmq_context_getsocket_args, 0, 0, 2)
2335 ZEND_ARG_INFO(0, type)
2336 ZEND_ARG_INFO(0, dsn)
2337 ZEND_ARG_INFO(0, on_new_socket)
2338 ZEND_END_ARG_INFO()
2339
2340 ZEND_BEGIN_ARG_INFO_EX(zmq_context_ispersistent_args, 0, 0, 2)
2341 ZEND_END_ARG_INFO()
2342
2343 ZEND_BEGIN_ARG_INFO_EX(zmq_context_clone_args, 0, 0, 0)
2344 ZEND_END_ARG_INFO()
2345
2346 #ifdef PHP_ZMQ_HAVE_CTX_OPTIONS
2347 ZEND_BEGIN_ARG_INFO_EX(zmq_context_setopt_args, 0, 0, 2)
2348 ZEND_ARG_INFO(0, option)
2349 ZEND_ARG_INFO(0, value)
2350 ZEND_END_ARG_INFO()
2351
2352 ZEND_BEGIN_ARG_INFO_EX(zmq_context_getopt_args, 0, 0, 2)
2353 ZEND_ARG_INFO(0, option)
2354 ZEND_END_ARG_INFO()
2355 #endif
2356
2357 static zend_function_entry php_zmq_context_class_methods[] = {
2358 PHP_ME(zmqcontext, __construct, zmq_context_construct_args, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
2359 PHP_ME(zmqcontext, acquire, zmq_context_acquire_args, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
2360 PHP_ME(zmqcontext, getsocketcount, zmq_context_getsocketcount_args,ZEND_ACC_PUBLIC)
2361 PHP_ME(zmqcontext, getsocket, zmq_context_getsocket_args, ZEND_ACC_PUBLIC)
2362 PHP_ME(zmqcontext, ispersistent, zmq_context_ispersistent_args, ZEND_ACC_PUBLIC)
2363 PHP_ME(zmqcontext, __clone, zmq_context_clone_args, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
2364 #ifdef PHP_ZMQ_HAVE_CTX_OPTIONS
2365 PHP_ME(zmqcontext, setOpt, zmq_context_setopt_args, ZEND_ACC_PUBLIC)
2366 PHP_ME(zmqcontext, getOpt, zmq_context_getopt_args, ZEND_ACC_PUBLIC)
2367 #endif
2368 {NULL, NULL, NULL}
2369 };
2370
2371 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_construct_args, 0, 0, 2)
2372 ZEND_ARG_OBJ_INFO(0, ZMQContext, ZMQContext, 0)
2373 ZEND_ARG_INFO(0, type)
2374 ZEND_ARG_INFO(0, persistent_id)
2375 ZEND_ARG_INFO(0, on_new_socket)
2376 ZEND_END_ARG_INFO()
2377
2378 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_bind_args, 0, 0, 1)
2379 ZEND_ARG_INFO(0, dsn)
2380 ZEND_ARG_INFO(0, force)
2381 ZEND_END_ARG_INFO()
2382
2383 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_connect_args, 0, 0, 1)
2384 ZEND_ARG_INFO(0, dsn)
2385 ZEND_ARG_INFO(0, force)
2386 ZEND_END_ARG_INFO()
2387
2388 #ifdef PHP_ZMQ_HAVE_SOCKET_MONITOR
2389 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_monitor_args, 0, 0, 1)
2390 ZEND_ARG_INFO(0, dsn)
2391 ZEND_ARG_INFO(0, events)
2392 ZEND_END_ARG_INFO()
2393
2394 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_recvevent_args, 0, 0, 0)
2395 ZEND_ARG_INFO(0, flags)
2396 ZEND_END_ARG_INFO()
2397 #endif
2398
2399 #ifdef PHP_ZMQ_HAVE_UNBIND
2400 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_unbind_args, 0, 0, 1)
2401 ZEND_ARG_INFO(0, dsn)
2402 ZEND_END_ARG_INFO()
2403 #endif
2404
2405 #ifdef PHP_ZMQ_HAVE_DISCONNECT
2406 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_disconnect_args, 0, 0, 1)
2407 ZEND_ARG_INFO(0, dsn)
2408 ZEND_END_ARG_INFO()
2409 #endif
2410
2411 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_setsockopt_args, 0, 0, 2)
2412 ZEND_ARG_INFO(0, key)
2413 ZEND_ARG_INFO(0, value)
2414 ZEND_END_ARG_INFO()
2415
2416 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_getendpoints_args, 0, 0, 0)
2417 ZEND_END_ARG_INFO()
2418
2419 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_getsockettype_args, 0, 0, 0)
2420 ZEND_END_ARG_INFO()
2421
2422 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_send_args, 0, 0, 1)
2423 ZEND_ARG_INFO(0, message)
2424 ZEND_ARG_INFO(0, mode)
2425 ZEND_END_ARG_INFO()
2426
2427 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_recv_args, 0, 0, 0)
2428 ZEND_ARG_INFO(0, mode)
2429 ZEND_END_ARG_INFO()
2430
2431 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_getpersistentid_args, 0, 0, 0)
2432 ZEND_END_ARG_INFO()
2433
2434 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_getsockopt_args, 0, 0, 1)
2435 ZEND_ARG_INFO(0, key)
2436 ZEND_END_ARG_INFO()
2437
2438 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_ispersistent_args, 0, 0, 0)
2439 ZEND_END_ARG_INFO()
2440
2441 ZEND_BEGIN_ARG_INFO_EX(zmq_socket_clone_args, 0, 0, 0)
2442 ZEND_END_ARG_INFO()
2443
2444 static zend_function_entry php_zmq_socket_class_methods[] = {
2445 PHP_ME(zmqsocket, __construct, zmq_socket_construct_args, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
2446 PHP_ME(zmqsocket, send, zmq_socket_send_args, ZEND_ACC_PUBLIC)
2447 PHP_ME(zmqsocket, recv, zmq_socket_recv_args, ZEND_ACC_PUBLIC)
2448 PHP_ME(zmqsocket, sendmulti, zmq_socket_send_args, ZEND_ACC_PUBLIC)
2449 PHP_ME(zmqsocket, recvmulti, zmq_socket_recv_args, ZEND_ACC_PUBLIC)
2450 PHP_ME(zmqsocket, bind, zmq_socket_bind_args, ZEND_ACC_PUBLIC)
2451 PHP_ME(zmqsocket, connect, zmq_socket_connect_args, ZEND_ACC_PUBLIC)
2452 #ifdef PHP_ZMQ_HAVE_SOCKET_MONITOR
2453 PHP_ME(zmqsocket, monitor, zmq_socket_monitor_args, ZEND_ACC_PUBLIC)
2454 PHP_ME(zmqsocket, recvevent, zmq_socket_recvevent_args, ZEND_ACC_PUBLIC)
2455 #endif
2456 #ifdef PHP_ZMQ_HAVE_UNBIND
2457 PHP_ME(zmqsocket, unbind, zmq_socket_unbind_args, ZEND_ACC_PUBLIC)
2458 #endif
2459 #ifdef PHP_ZMQ_HAVE_DISCONNECT
2460 PHP_ME(zmqsocket, disconnect, zmq_socket_disconnect_args, ZEND_ACC_PUBLIC)
2461 #endif
2462 PHP_ME(zmqsocket, setsockopt, zmq_socket_setsockopt_args, ZEND_ACC_PUBLIC)
2463 PHP_ME(zmqsocket, getendpoints, zmq_socket_getendpoints_args, ZEND_ACC_PUBLIC)
2464 PHP_ME(zmqsocket, getsockettype, zmq_socket_getsockettype_args, ZEND_ACC_PUBLIC)
2465 PHP_ME(zmqsocket, ispersistent, zmq_socket_ispersistent_args, ZEND_ACC_PUBLIC)
2466 PHP_ME(zmqsocket, getpersistentid, zmq_socket_getpersistentid_args, ZEND_ACC_PUBLIC)
2467 PHP_ME(zmqsocket, getsockopt, zmq_socket_getsockopt_args, ZEND_ACC_PUBLIC)
2468 PHP_ME(zmqsocket, __clone, zmq_socket_clone_args, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
2469 PHP_MALIAS(zmqsocket, sendmsg, send, zmq_socket_send_args, ZEND_ACC_PUBLIC)
2470 PHP_MALIAS(zmqsocket, recvmsg, recv, zmq_socket_recv_args, ZEND_ACC_PUBLIC)
2471 {NULL, NULL, NULL}
2472 };
2473
2474 ZEND_BEGIN_ARG_INFO_EX(zmq_poll_add_args, 0, 0, 2)
2475 ZEND_ARG_INFO(0, entry)
2476 ZEND_ARG_INFO(0, type)
2477 ZEND_END_ARG_INFO()
2478
2479 ZEND_BEGIN_ARG_INFO_EX(zmq_poll_poll_args, 0, 0, 2)
2480 ZEND_ARG_INFO(1, readable)
2481 ZEND_ARG_INFO(1, writable)
2482 ZEND_ARG_INFO(0, timeout)
2483 ZEND_END_ARG_INFO()
2484
2485 ZEND_BEGIN_ARG_INFO_EX(zmq_poll_getlasterrors_args, 0, 0, 0)
2486 ZEND_END_ARG_INFO()
2487
2488 ZEND_BEGIN_ARG_INFO_EX(zmq_poll_remove_args, 0, 0, 2)
2489 ZEND_ARG_INFO(0, remove)
2490 ZEND_END_ARG_INFO()
2491
2492 ZEND_BEGIN_ARG_INFO_EX(zmq_poll_count_args, 0, 0, 0)
2493 ZEND_END_ARG_INFO()
2494
2495 ZEND_BEGIN_ARG_INFO_EX(zmq_poll_clear_args, 0, 0, 0)
2496 ZEND_END_ARG_INFO()
2497
2498 ZEND_BEGIN_ARG_INFO_EX(zmq_poll_items_args, 0, 0, 0)
2499 ZEND_END_ARG_INFO()
2500
2501 ZEND_BEGIN_ARG_INFO_EX(zmq_poll_clone_args, 0, 0, 0)
2502 ZEND_END_ARG_INFO()
2503
2504 static zend_function_entry php_zmq_poll_class_methods[] = {
2505 PHP_ME(zmqpoll, add, zmq_poll_add_args, ZEND_ACC_PUBLIC)
2506 PHP_ME(zmqpoll, poll, zmq_poll_poll_args, ZEND_ACC_PUBLIC)
2507 PHP_ME(zmqpoll, getlasterrors, zmq_poll_getlasterrors_args, ZEND_ACC_PUBLIC)
2508 PHP_ME(zmqpoll, remove, zmq_poll_remove_args, ZEND_ACC_PUBLIC)
2509 PHP_ME(zmqpoll, count, zmq_poll_count_args, ZEND_ACC_PUBLIC)
2510 PHP_ME(zmqpoll, clear, zmq_poll_clear_args, ZEND_ACC_PUBLIC)
2511 PHP_ME(zmqpoll, items, zmq_poll_items_args, ZEND_ACC_PUBLIC)
2512 PHP_ME(zmqpoll, __clone, zmq_poll_clone_args, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
2513 {NULL, NULL, NULL}
2514 };
2515
2516 ZEND_BEGIN_ARG_INFO_EX(zmq_device_construct_args, 0, 0, 2)
2517 ZEND_ARG_OBJ_INFO(0, frontend, ZMQSocket, 0)
2518 ZEND_ARG_OBJ_INFO(0, backend, ZMQSocket, 0)
2519 ZEND_ARG_OBJ_INFO(0, capture, ZMQSocket, 0)
2520 ZEND_END_ARG_INFO()
2521
2522 ZEND_BEGIN_ARG_INFO_EX(zmq_device_run_args, 0, 0, 0)
2523 ZEND_END_ARG_INFO()
2524
2525 ZEND_BEGIN_ARG_INFO_EX(zmq_device_setidlecallback_args, 0, 0, 2)
2526 ZEND_ARG_INFO(0, idle_callback)
2527 ZEND_ARG_INFO(0, timeout)
2528 ZEND_ARG_INFO(0, user_data)
2529 ZEND_END_ARG_INFO()
2530
2531 ZEND_BEGIN_ARG_INFO_EX(zmq_device_settimercallback_args, 0, 0, 2)
2532 ZEND_ARG_INFO(0, idle_callback)
2533 ZEND_ARG_INFO(0, timeout)
2534 ZEND_ARG_INFO(0, user_data)
2535 ZEND_END_ARG_INFO()
2536
2537 ZEND_BEGIN_ARG_INFO_EX(zmq_device_setidletimeout_args, 0, 0, 1)
2538 ZEND_ARG_INFO(0, timeout)
2539 ZEND_END_ARG_INFO()
2540
2541 ZEND_BEGIN_ARG_INFO_EX(zmq_device_settimertimeout_args, 0, 0, 1)
2542 ZEND_ARG_INFO(0, timeout)
2543 ZEND_END_ARG_INFO()
2544
2545 ZEND_BEGIN_ARG_INFO_EX(zmq_device_getidletimeout_args, 0, 0, 0)
2546 ZEND_END_ARG_INFO()
2547
2548 ZEND_BEGIN_ARG_INFO_EX(zmq_device_gettimertimeout_args, 0, 0, 0)
2549 ZEND_END_ARG_INFO()
2550
2551 ZEND_BEGIN_ARG_INFO_EX(zmq_device_clone_args, 0, 0, 0)
2552 ZEND_END_ARG_INFO()
2553
2554 static zend_function_entry php_zmq_device_class_methods[] = {
2555 PHP_ME(zmqdevice, __construct, zmq_device_construct_args, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL)
2556 PHP_ME(zmqdevice, run, zmq_device_run_args, ZEND_ACC_PUBLIC)
2557 PHP_ME(zmqdevice, setidlecallback, zmq_device_setidlecallback_args, ZEND_ACC_PUBLIC)
2558 PHP_ME(zmqdevice, setidletimeout, zmq_device_setidletimeout_args, ZEND_ACC_PUBLIC)
2559 PHP_ME(zmqdevice, getidletimeout, zmq_device_getidletimeout_args, ZEND_ACC_PUBLIC)
2560 PHP_ME(zmqdevice, settimercallback, zmq_device_settimercallback_args, ZEND_ACC_PUBLIC)
2561 PHP_ME(zmqdevice, settimertimeout, zmq_device_settimertimeout_args, ZEND_ACC_PUBLIC)
2562 PHP_ME(zmqdevice, gettimertimeout, zmq_device_gettimertimeout_args, ZEND_ACC_PUBLIC)
2563 PHP_ME(zmqdevice, __clone, zmq_device_clone_args, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
2564 {NULL, NULL, NULL}
2565 };
2566
2567
2568 zend_function_entry zmq_functions[] = {
2569 {NULL, NULL, NULL}
2570 };
2571
2572 static
php_zmq_context_object_free_storage(zend_object * object)2573 void php_zmq_context_object_free_storage(zend_object *object)
2574 {
2575 php_zmq_context_object *intern = php_zmq_context_fetch_object(object);
2576
2577 if (!intern) {
2578 return;
2579 }
2580
2581 if (intern->context) {
2582 if (!intern->context->is_persistent) {
2583 php_zmq_context_destroy(intern->context);
2584 }
2585 }
2586 zend_object_std_dtor(&intern->zo);
2587 }
2588
2589 static
php_zmq_socket_object_free_storage(zend_object * object)2590 void php_zmq_socket_object_free_storage(zend_object *object)
2591 {
2592 php_zmq_socket_object *intern = php_zmq_socket_fetch_object(object);
2593
2594 if (!intern) {
2595 return;
2596 }
2597
2598 if (intern->socket) {
2599 if (intern->socket->is_persistent && intern->persistent_id) {
2600 efree(intern->persistent_id);
2601 }
2602 if (!intern->socket->is_persistent) {
2603 php_zmq_socket_destroy(intern->socket);
2604 }
2605 }
2606
2607 if (!Z_ISUNDEF(intern->context_obj)) {
2608 zval_ptr_dtor(&intern->context_obj);
2609 }
2610 zend_object_std_dtor(&intern->zo);
2611 }
2612
2613 static
php_zmq_poll_object_free_storage(zend_object * object)2614 void php_zmq_poll_object_free_storage(zend_object *object)
2615 {
2616 php_zmq_poll_object *intern = php_zmq_poll_fetch_object(object);
2617
2618 if (!intern) {
2619 return;
2620 }
2621 php_zmq_pollset_destroy(&intern->set);
2622 zend_object_std_dtor(&intern->zo);
2623 }
2624
php_zmq_device_object_free_storage(zend_object * object)2625 static void php_zmq_device_object_free_storage(zend_object *object)
2626 {
2627 php_zmq_device_object *intern = php_zmq_device_fetch_object(object);
2628
2629 if (!intern) {
2630 return;
2631 }
2632
2633 s_clear_device_callback (&intern->idle_cb);
2634 s_clear_device_callback (&intern->timer_cb);
2635
2636 if (!Z_ISUNDEF(intern->front)) {
2637 zval_ptr_dtor(&intern->front);
2638 }
2639
2640 if (!Z_ISUNDEF(intern->back)) {
2641 zval_ptr_dtor(&intern->back);
2642 }
2643
2644 if (!Z_ISUNDEF(intern->capture)) {
2645 zval_ptr_dtor(&intern->capture);
2646 }
2647 zend_object_std_dtor(&intern->zo);
2648 }
2649
2650 static
php_zmq_context_object_new_ex(zend_class_entry * class_type,php_zmq_context_object ** ptr)2651 zend_object *php_zmq_context_object_new_ex(zend_class_entry *class_type, php_zmq_context_object **ptr)
2652 {
2653 php_zmq_context_object *intern = ecalloc(1, sizeof(php_zmq_context_object) + zend_object_properties_size(class_type));
2654
2655 /* Context is initialized in the constructor */
2656 intern->context = NULL;
2657
2658 if (ptr) {
2659 *ptr = intern;
2660 }
2661
2662 zend_object_std_init(&intern->zo, class_type);
2663 object_properties_init(&intern->zo, class_type);
2664
2665 intern->zo.handlers = &zmq_context_object_handlers;
2666 return &intern->zo;
2667 }
2668
2669 static
php_zmq_socket_object_new_ex(zend_class_entry * class_type,php_zmq_socket_object ** ptr)2670 zend_object *php_zmq_socket_object_new_ex(zend_class_entry *class_type, php_zmq_socket_object **ptr)
2671 {
2672 php_zmq_socket_object *intern;
2673
2674 /* Allocate memory for it */
2675 intern = ecalloc(1, sizeof(php_zmq_socket_object) + zend_object_properties_size(class_type));
2676
2677 intern->socket = NULL;
2678 intern->persistent_id = NULL;
2679 ZVAL_UNDEF(&intern->context_obj);
2680
2681 if (ptr) {
2682 *ptr = intern;
2683 }
2684
2685 zend_object_std_init(&intern->zo, class_type);
2686 object_properties_init(&intern->zo, class_type);
2687
2688 intern->zo.handlers = &zmq_socket_object_handlers;
2689 return &intern->zo;
2690 }
2691
2692 static
php_zmq_poll_object_new_ex(zend_class_entry * class_type,php_zmq_poll_object ** ptr)2693 zend_object *php_zmq_poll_object_new_ex(zend_class_entry *class_type, php_zmq_poll_object **ptr)
2694 {
2695 php_zmq_poll_object *intern = ecalloc(1, sizeof(php_zmq_poll_object) + zend_object_properties_size(class_type));
2696 intern->set = php_zmq_pollset_init();
2697
2698 if (ptr) {
2699 *ptr = intern;
2700 }
2701
2702 zend_object_std_init(&intern->zo, class_type);
2703 object_properties_init(&intern->zo, class_type);
2704
2705 intern->zo.handlers = &zmq_poll_object_handlers;
2706 return &intern->zo;
2707 }
2708
2709 static
php_zmq_device_object_new_ex(zend_class_entry * class_type,php_zmq_device_object ** ptr)2710 zend_object *php_zmq_device_object_new_ex(zend_class_entry *class_type, php_zmq_device_object **ptr)
2711 {
2712 php_zmq_device_object *intern = ecalloc(1, sizeof(php_zmq_device_object) + zend_object_properties_size(class_type));
2713
2714 memset (&intern->idle_cb, 0, sizeof (php_zmq_device_cb_t));
2715 memset (&intern->timer_cb, 0, sizeof (php_zmq_device_cb_t));
2716
2717 ZVAL_UNDEF(&intern->front);
2718 ZVAL_UNDEF(&intern->back);
2719 ZVAL_UNDEF(&intern->capture);
2720
2721 if (ptr) {
2722 *ptr = intern;
2723 }
2724
2725 zend_object_std_init(&intern->zo, class_type);
2726 object_properties_init(&intern->zo, class_type);
2727
2728 intern->zo.handlers = &zmq_device_object_handlers;
2729 return &intern->zo;
2730 }
2731
2732 static
php_zmq_context_object_new(zend_class_entry * class_type)2733 zend_object *php_zmq_context_object_new(zend_class_entry *class_type)
2734 {
2735 return php_zmq_context_object_new_ex(class_type, NULL);
2736 }
2737
2738 static
php_zmq_socket_object_new(zend_class_entry * class_type)2739 zend_object *php_zmq_socket_object_new(zend_class_entry *class_type)
2740 {
2741 return php_zmq_socket_object_new_ex(class_type, NULL);
2742 }
2743
2744 static
php_zmq_poll_object_new(zend_class_entry * class_type)2745 zend_object *php_zmq_poll_object_new(zend_class_entry *class_type)
2746 {
2747 return php_zmq_poll_object_new_ex(class_type, NULL);
2748 }
2749
2750 static
php_zmq_device_object_new(zend_class_entry * class_type)2751 zend_object *php_zmq_device_object_new(zend_class_entry *class_type)
2752 {
2753 return php_zmq_device_object_new_ex(class_type, NULL);
2754 }
2755
ZEND_RSRC_DTOR_FUNC(php_zmq_context_dtor)2756 ZEND_RSRC_DTOR_FUNC(php_zmq_context_dtor)
2757 {
2758 if (res->ptr) {
2759 php_zmq_context *ctx = (php_zmq_context *)res->ptr;
2760 php_zmq_context_destroy(ctx);
2761 res->ptr = NULL;
2762 }
2763 }
2764
ZEND_RSRC_DTOR_FUNC(php_zmq_socket_dtor)2765 ZEND_RSRC_DTOR_FUNC(php_zmq_socket_dtor)
2766 {
2767 if (res->ptr) {
2768 php_zmq_socket *zms = (php_zmq_socket *)res->ptr;
2769 php_zmq_socket_destroy(zms);
2770 res->ptr = NULL;
2771 }
2772 }
2773
2774 static
php_zmq_init_globals(zend_php_zmq_globals * zmq_globals)2775 void php_zmq_init_globals (zend_php_zmq_globals *zmq_globals)
2776 {
2777 zmq_globals->clock_ctx = NULL;
2778 }
2779
PHP_MINIT_FUNCTION(zmq)2780 PHP_MINIT_FUNCTION(zmq)
2781 {
2782 char *version;
2783 zend_class_entry ce, ce_context, ce_socket, ce_poll, ce_device;
2784 zend_class_entry ce_exception, ce_context_exception, ce_socket_exception, ce_poll_exception, ce_device_exception;
2785
2786 #ifdef HAVE_CZMQ_2
2787 zend_class_entry ce_cert, ce_cert_exception, ce_auth, ce_auth_exception;
2788 #endif
2789
2790 le_zmq_context = zend_register_list_destructors_ex(NULL, php_zmq_context_dtor, "ZMQ persistent context", module_number);
2791 le_zmq_socket = zend_register_list_destructors_ex(NULL, php_zmq_socket_dtor, "ZMQ persistent socket", module_number);
2792
2793 memcpy(&zmq_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2794 memcpy(&zmq_context_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2795 memcpy(&zmq_socket_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2796 memcpy(&zmq_poll_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2797 memcpy(&zmq_device_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2798
2799 #ifdef HAVE_CZMQ_2
2800 memcpy(&zmq_cert_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2801 memcpy(&zmq_auth_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2802 #endif
2803
2804 INIT_CLASS_ENTRY(ce, "ZMQ", php_zmq_class_methods);
2805 ce.create_object = NULL;
2806 zmq_object_handlers.clone_obj = NULL;
2807 php_zmq_sc_entry = zend_register_internal_class(&ce);
2808
2809 INIT_CLASS_ENTRY(ce_context, "ZMQContext", php_zmq_context_class_methods);
2810 ce_context.create_object = php_zmq_context_object_new;
2811
2812 zmq_context_object_handlers.offset = XtOffsetOf(php_zmq_context_object, zo);
2813 zmq_context_object_handlers.clone_obj = NULL;
2814 zmq_context_object_handlers.free_obj = php_zmq_context_object_free_storage;
2815
2816 php_zmq_context_sc_entry = zend_register_internal_class(&ce_context);
2817
2818 INIT_CLASS_ENTRY(ce_socket, "ZMQSocket", php_zmq_socket_class_methods);
2819 ce_socket.create_object = php_zmq_socket_object_new;
2820
2821 zmq_socket_object_handlers.offset = XtOffsetOf(php_zmq_socket_object, zo);
2822 zmq_socket_object_handlers.clone_obj = NULL;
2823 zmq_socket_object_handlers.free_obj = php_zmq_socket_object_free_storage;
2824
2825 php_zmq_socket_sc_entry = zend_register_internal_class(&ce_socket);
2826
2827 INIT_CLASS_ENTRY(ce_poll, "ZMQPoll", php_zmq_poll_class_methods);
2828 ce_poll.create_object = php_zmq_poll_object_new;
2829
2830 zmq_poll_object_handlers.offset = XtOffsetOf(php_zmq_poll_object, zo);
2831 zmq_poll_object_handlers.clone_obj = NULL;
2832 zmq_poll_object_handlers.free_obj = php_zmq_poll_object_free_storage;
2833
2834 php_zmq_poll_sc_entry = zend_register_internal_class(&ce_poll);
2835
2836 INIT_CLASS_ENTRY(ce_device, "ZMQDevice", php_zmq_device_class_methods);
2837 ce_device.create_object = php_zmq_device_object_new;
2838
2839 zmq_device_object_handlers.offset = XtOffsetOf(php_zmq_device_object, zo);
2840 zmq_device_object_handlers.clone_obj = NULL;
2841 zmq_device_object_handlers.free_obj = php_zmq_device_object_free_storage;
2842
2843 php_zmq_device_sc_entry = zend_register_internal_class(&ce_device);
2844
2845 #ifdef HAVE_CZMQ_2
2846 INIT_CLASS_ENTRY(ce_cert, "ZMQCert", php_zmq_cert_class_methods);
2847 ce_cert.create_object = php_zmq_cert_new;
2848
2849 zmq_cert_object_handlers.offset = XtOffsetOf(php_zmq_cert_object, zo);
2850 zmq_cert_object_handlers.clone_obj = php_zmq_cert_clone;
2851 zmq_cert_object_handlers.free_obj = php_zmq_cert_object_free_storage;
2852
2853 php_zmq_cert_sc_entry = zend_register_internal_class(&ce_cert);
2854
2855 INIT_CLASS_ENTRY(ce_auth, "ZMQAuth", php_zmq_auth_class_methods);
2856 ce_auth.create_object = php_zmq_auth_new;
2857
2858 zmq_auth_object_handlers.offset = XtOffsetOf(php_zmq_auth_object, zo);
2859 zmq_auth_object_handlers.clone_obj = NULL;
2860 zmq_auth_object_handlers.free_obj = php_zmq_auth_object_free_storage;
2861
2862 php_zmq_auth_sc_entry = zend_register_internal_class(&ce_auth);
2863 #endif
2864
2865 INIT_CLASS_ENTRY(ce_exception, "ZMQException", NULL);
2866 php_zmq_exception_sc_entry = zend_register_internal_class_ex(&ce_exception, zend_exception_get_default());
2867 php_zmq_exception_sc_entry->ce_flags &= ~ZEND_ACC_FINAL;
2868
2869 INIT_CLASS_ENTRY(ce_context_exception, "ZMQContextException", NULL);
2870 php_zmq_context_exception_sc_entry = zend_register_internal_class_ex(&ce_context_exception, php_zmq_exception_sc_entry);
2871 php_zmq_context_exception_sc_entry->ce_flags |= ZEND_ACC_FINAL;
2872
2873 INIT_CLASS_ENTRY(ce_socket_exception, "ZMQSocketException", NULL);
2874 php_zmq_socket_exception_sc_entry = zend_register_internal_class_ex(&ce_socket_exception, php_zmq_exception_sc_entry);
2875 php_zmq_socket_exception_sc_entry->ce_flags |= ZEND_ACC_FINAL;
2876
2877 INIT_CLASS_ENTRY(ce_poll_exception, "ZMQPollException", NULL);
2878 php_zmq_poll_exception_sc_entry = zend_register_internal_class_ex(&ce_poll_exception, php_zmq_exception_sc_entry);
2879 php_zmq_poll_exception_sc_entry->ce_flags |= ZEND_ACC_FINAL;
2880
2881 INIT_CLASS_ENTRY(ce_device_exception, "ZMQDeviceException", NULL);
2882 php_zmq_device_exception_sc_entry = zend_register_internal_class_ex(&ce_device_exception, php_zmq_exception_sc_entry);
2883 php_zmq_device_exception_sc_entry->ce_flags |= ZEND_ACC_FINAL;
2884
2885 #ifdef HAVE_CZMQ_2
2886 INIT_CLASS_ENTRY(ce_cert_exception, "ZMQCertException", NULL);
2887 php_zmq_cert_exception_sc_entry = zend_register_internal_class_ex(&ce_cert_exception, php_zmq_exception_sc_entry);
2888 php_zmq_cert_exception_sc_entry->ce_flags |= ZEND_ACC_FINAL;
2889
2890 INIT_CLASS_ENTRY(ce_auth_exception, "ZMQAuthException", NULL);
2891 php_zmq_auth_exception_sc_entry = zend_register_internal_class_ex(&ce_auth_exception, php_zmq_exception_sc_entry);
2892 php_zmq_auth_exception_sc_entry->ce_flags |= ZEND_ACC_FINAL;
2893 #endif
2894
2895 ZEND_INIT_MODULE_GLOBALS(php_zmq, php_zmq_init_globals, NULL);
2896
2897 ZMQ_G(clock_ctx) = php_zmq_clock_init ();
2898
2899 if (!ZMQ_G(clock_ctx)) {
2900 php_error_docref(NULL, E_WARNING, "Failed to initialise clock");
2901 return FAILURE;
2902 }
2903
2904 #define PHP_ZMQ_REGISTER_CONST_LONG(const_name, value) \
2905 zend_declare_class_constant_long(php_zmq_sc_entry, const_name, sizeof(const_name)-1, (long)value);
2906 #define PHP_ZMQ_REGISTER_CONST_STRING(const_name, value) \
2907 zend_declare_class_constant_string (php_zmq_sc_entry, const_name, sizeof(const_name)-1, value);
2908 #define PHP_ZMQ_REGISTER_CONST_BOOL(const_name, value) \
2909 zend_declare_class_constant_bool (php_zmq_sc_entry, const_name, sizeof(const_name)-1, value);
2910
2911 /* Socket constants */
2912 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_PAIR", ZMQ_PAIR);
2913 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_PUB", ZMQ_PUB);
2914 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_SUB", ZMQ_SUB);
2915 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_REQ", ZMQ_REQ);
2916 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_REP", ZMQ_REP);
2917 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_XREQ", ZMQ_XREQ);
2918 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_XREP", ZMQ_XREP);
2919 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_PUSH", ZMQ_PUSH);
2920 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_PULL", ZMQ_PULL);
2921 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_DEALER", ZMQ_DEALER);
2922 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_ROUTER", ZMQ_ROUTER);
2923 #ifdef ZMQ_XSUB
2924 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_XSUB", ZMQ_XSUB);
2925 #endif
2926 #ifdef ZMQ_XPUB
2927 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_XPUB", ZMQ_XPUB);
2928 #endif
2929 #ifdef ZMQ_STREAM
2930 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_STREAM", ZMQ_STREAM);
2931 #endif
2932
2933 /* 2.0? */
2934 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_UPSTREAM", ZMQ_PULL);
2935 PHP_ZMQ_REGISTER_CONST_LONG("SOCKET_DOWNSTREAM", ZMQ_PUSH);
2936
2937 #ifdef ZMQ_SNDLABEL
2938 PHP_ZMQ_REGISTER_CONST_LONG("MODE_SNDLABEL", ZMQ_SNDLABEL);
2939 #endif
2940
2941 PHP_ZMQ_REGISTER_CONST_LONG("POLL_IN", ZMQ_POLLIN);
2942 PHP_ZMQ_REGISTER_CONST_LONG("POLL_OUT", ZMQ_POLLOUT);
2943
2944 PHP_ZMQ_REGISTER_CONST_LONG("MODE_SNDMORE", ZMQ_SNDMORE);
2945 PHP_ZMQ_REGISTER_CONST_LONG("MODE_NOBLOCK", ZMQ_DONTWAIT);
2946 PHP_ZMQ_REGISTER_CONST_LONG("MODE_DONTWAIT", ZMQ_DONTWAIT);
2947
2948 PHP_ZMQ_REGISTER_CONST_LONG("ERR_INTERNAL", PHP_ZMQ_INTERNAL_ERROR);
2949 PHP_ZMQ_REGISTER_CONST_LONG("ERR_EAGAIN", EAGAIN);
2950 PHP_ZMQ_REGISTER_CONST_LONG("ERR_ENOTSUP", ENOTSUP);
2951 PHP_ZMQ_REGISTER_CONST_LONG("ERR_EFSM", EFSM);
2952 PHP_ZMQ_REGISTER_CONST_LONG("ERR_ETERM", ETERM);
2953
2954 version = php_zmq_get_libzmq_version();
2955
2956 PHP_ZMQ_REGISTER_CONST_STRING("LIBZMQ_VER", version);
2957 PHP_ZMQ_REGISTER_CONST_STRING("LIBZMQ_VERSION", version);
2958 PHP_ZMQ_REGISTER_CONST_LONG("LIBZMQ_VERSION_ID", php_zmq_get_libzmq_version_id());
2959
2960 PHP_ZMQ_REGISTER_CONST_LONG("LIBZMQ_VERSION_MAJOR", ZMQ_VERSION_MAJOR);
2961 PHP_ZMQ_REGISTER_CONST_LONG("LIBZMQ_VERSION_MINOR", ZMQ_VERSION_MINOR);
2962 PHP_ZMQ_REGISTER_CONST_LONG("LIBZMQ_VERSION_PATCH", ZMQ_VERSION_PATCH);
2963
2964 efree(version);
2965
2966 php_zmq_register_sockopt_constants (php_zmq_sc_entry);
2967
2968 #ifdef ZMQ_MAX_SOCKETS
2969 PHP_ZMQ_REGISTER_CONST_LONG("CTXOPT_MAX_SOCKETS", ZMQ_MAX_SOCKETS);
2970 #endif
2971
2972 #ifdef ZMQ_MAX_SOCKETS_DFLT
2973 PHP_ZMQ_REGISTER_CONST_LONG("CTXOPT_MAX_SOCKETS_DEFAULT", ZMQ_MAX_SOCKETS_DFLT);
2974 #endif
2975
2976 #ifdef HAVE_CZMQ_2
2977 PHP_ZMQ_REGISTER_CONST_STRING("CURVE_ALLOW_ANY", CURVE_ALLOW_ANY);
2978
2979 zend_declare_class_constant_long(php_zmq_auth_sc_entry, "AUTH_TYPE_PLAIN", 15, (long)PHP_ZMQ_AUTH_TYPE_PLAIN);
2980 zend_declare_class_constant_long(php_zmq_auth_sc_entry, "AUTH_TYPE_CURVE", 15, (long)PHP_ZMQ_AUTH_TYPE_CURVE);
2981 #endif
2982
2983 #ifdef PHP_ZMQ_HAVE_SOCKET_MONITOR
2984 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_CONNECTED", ZMQ_EVENT_CONNECTED);
2985 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_CONNECT_DELAYED", ZMQ_EVENT_CONNECT_DELAYED);
2986 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_CONNECT_RETRIED", ZMQ_EVENT_CONNECT_RETRIED);
2987 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_LISTENING", ZMQ_EVENT_LISTENING);
2988 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_BIND_FAILED", ZMQ_EVENT_BIND_FAILED);
2989 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_ACCEPTED", ZMQ_EVENT_ACCEPTED);
2990 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_ACCEPT_FAILED", ZMQ_EVENT_ACCEPT_FAILED);
2991 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_CLOSED", ZMQ_EVENT_CLOSED);
2992 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_CLOSE_FAILED", ZMQ_EVENT_CLOSE_FAILED);
2993 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_DISCONNECTED", ZMQ_EVENT_DISCONNECTED);
2994 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_MONITOR_STOPPED", ZMQ_EVENT_MONITOR_STOPPED);
2995 PHP_ZMQ_REGISTER_CONST_LONG("EVENT_ALL", ZMQ_EVENT_ALL);
2996 #endif
2997
2998 #undef PHP_ZMQ_REGISTER_CONST_LONG
2999 #undef PHP_ZMQ_REGISTER_CONST_STRING
3000
3001 if (!php_zmq_shared_ctx_init()) {
3002 return FAILURE;
3003 }
3004 return SUCCESS;
3005 }
3006
PHP_MSHUTDOWN_FUNCTION(zmq)3007 PHP_MSHUTDOWN_FUNCTION(zmq)
3008 {
3009 php_zmq_shared_ctx_destroy();
3010 php_zmq_clock_destroy (&ZMQ_G (clock_ctx));
3011 return SUCCESS;
3012 }
3013
PHP_MINFO_FUNCTION(zmq)3014 PHP_MINFO_FUNCTION(zmq)
3015 {
3016 char *version = php_zmq_get_libzmq_version();
3017
3018 php_info_print_table_start();
3019
3020 php_info_print_table_header(2, "ZMQ extension", "enabled");
3021 php_info_print_table_row(2, "ZMQ extension version", PHP_ZMQ_VERSION);
3022 php_info_print_table_row(2, "libzmq version", version);
3023
3024 php_info_print_table_end();
3025 DISPLAY_INI_ENTRIES();
3026
3027 efree(version);
3028 }
3029
3030 zend_module_entry zmq_module_entry =
3031 {
3032 STANDARD_MODULE_HEADER,
3033 PHP_ZMQ_EXTNAME,
3034 zmq_functions, /* Functions */
3035 PHP_MINIT(zmq), /* MINIT */
3036 PHP_MSHUTDOWN(zmq), /* MSHUTDOWN */
3037 NULL, /* RINIT */
3038 NULL, /* RSHUTDOWN */
3039 PHP_MINFO(zmq), /* MINFO */
3040 PHP_ZMQ_VERSION, /* version */
3041 STANDARD_MODULE_PROPERTIES
3042 };
3043
3044 #ifdef COMPILE_DL_ZMQ
3045 ZEND_GET_MODULE(zmq)
3046 #endif /* COMPILE_DL_ZMQ */
3047