@@ -94,8 +94,6 @@ php_sockets_globals sockets_globals;
94
94
95
95
static int le_iov ;
96
96
#define le_iov_name "Socket I/O vector"
97
- static int le_destroy ;
98
- #define le_destroy_name "Socket file descriptor set"
99
97
static int le_socket ;
100
98
#define le_socket_name "Socket"
101
99
@@ -111,12 +109,6 @@ static unsigned char third_through_seventh_args_force_ref[] =
111
109
/* {{{ sockets_functions[]
112
110
*/
113
111
function_entry sockets_functions [] = {
114
- PHP_FE (socket_fd_alloc , NULL )
115
- PHP_FE (socket_fd_free , NULL )
116
- PHP_FE (socket_fd_set , NULL )
117
- PHP_FE (socket_fd_isset , NULL )
118
- PHP_FE (socket_fd_clear , NULL )
119
- PHP_FE (socket_fd_zero , NULL )
120
112
PHP_FE (socket_iovec_alloc , NULL )
121
113
PHP_FE (socket_iovec_free , NULL )
122
114
PHP_FE (socket_iovec_set , NULL )
@@ -177,13 +169,6 @@ ZEND_GET_MODULE(sockets)
177
169
/* inet_ntop should be used instead of inet_ntoa */
178
170
int inet_ntoa_lock = 0 ;
179
171
180
- static void destroy_fd_sets (zend_rsrc_list_entry * rsrc TSRMLS_DC )
181
- {
182
- php_fd_set * php_fd = (php_fd_set * )rsrc -> ptr ;
183
-
184
- efree (php_fd );
185
- }
186
-
187
172
static void destroy_iovec (zend_rsrc_list_entry * rsrc TSRMLS_DC )
188
173
{
189
174
unsigned int i ;
@@ -393,7 +378,6 @@ PHP_MINIT_FUNCTION(sockets)
393
378
struct protoent * pe ;
394
379
395
380
le_socket = zend_register_list_destructors_ex (destroy_socket , NULL , le_socket_name , module_number );
396
- le_destroy = zend_register_list_destructors_ex (destroy_fd_sets , NULL , le_destroy_name , module_number );
397
381
le_iov = zend_register_list_destructors_ex (destroy_iovec , NULL , le_iov_name , module_number );
398
382
399
383
REGISTER_LONG_CONSTANT ("AF_UNIX" , AF_UNIX , CONST_CS | CONST_PERSISTENT );
@@ -448,193 +432,96 @@ PHP_MINFO_FUNCTION(sockets)
448
432
}
449
433
/* }}} */
450
434
451
- /* {{{ proto resource socket_fd_alloc(void)
452
- Allocates a new file descriptor set */
453
- PHP_FUNCTION (socket_fd_alloc )
454
- {
455
- php_fd_set * php_fd = (php_fd_set * )emalloc (sizeof (php_fd_set ));
456
-
457
- FD_ZERO (& (php_fd -> set ));
458
-
459
- php_fd -> max_fd = 0 ;
460
-
461
- ZEND_REGISTER_RESOURCE (return_value , php_fd , le_destroy );
462
- }
463
- /* }}} */
464
-
465
- /* {{{ proto bool socket_fd_free(resource set)
466
- Deallocates a file descriptor set */
467
- PHP_FUNCTION (socket_fd_free )
468
- {
469
- zval * arg1 ;
470
- php_fd_set * php_fd ;
471
-
472
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "r" , & arg1 ) == FAILURE )
473
- return ;
474
-
475
- ZEND_FETCH_RESOURCE (php_fd , php_fd_set * , & arg1 , -1 , le_destroy_name , le_destroy );
476
-
477
- zend_list_delete (Z_RESVAL_P (arg1 ));
478
- RETURN_TRUE ;
479
- }
480
- /* }}} */
481
-
482
- /* {{{ proto bool socket_fd_set(resource set, mixed socket)
483
- Adds (a) file descriptor(s) to a set */
484
- PHP_FUNCTION (socket_fd_set )
485
- {
486
- zval * arg1 , * arg2 , * * tmp ;
487
- php_fd_set * php_fd ;
435
+ int php_sock_array_to_fd_set (zval * sock_array , fd_set * fds , int * max_fd TSRMLS_DC ) {
436
+ zval * * element ;
488
437
php_socket * php_sock ;
489
- SOCKET max_fd = 0 ;
490
-
491
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "rz" , & arg1 , & arg2 ) == FAILURE )
492
- return ;
493
-
494
- ZEND_FETCH_RESOURCE (php_fd , php_fd_set * , & arg1 , -1 , le_destroy_name , le_destroy );
438
+
439
+ if (Z_TYPE_P (sock_array ) != IS_ARRAY ) return 0 ;
440
+
441
+ for (zend_hash_internal_pointer_reset (Z_ARRVAL_P (sock_array ));
442
+ zend_hash_get_current_data (Z_ARRVAL_P (sock_array ), (void * * ) & element ) == SUCCESS ;
443
+ zend_hash_move_forward (Z_ARRVAL_P (sock_array ))) {
444
+
445
+ php_sock = (php_socket * ) zend_fetch_resource (element TSRMLS_CC , -1 , le_socket_name , NULL , 1 , le_socket );
446
+ if (!php_sock ) continue ; /* If element is not a resource, skip it */
495
447
496
- if (Z_TYPE_P (arg2 ) == IS_ARRAY ) {
497
- zend_hash_internal_pointer_reset (Z_ARRVAL_P (arg2 ));
498
- while (zend_hash_get_current_data (Z_ARRVAL_P (arg2 ), (void * * )& tmp ) == SUCCESS ) {
499
- ZEND_FETCH_RESOURCE (php_sock , php_socket * , tmp , -1 , le_socket_name , le_socket );
500
- FD_SET (php_sock -> bsd_socket , & (php_fd -> set ));
501
- max_fd = (php_sock -> bsd_socket > max_fd ) ? php_sock -> bsd_socket : max_fd ;
502
- zend_hash_move_forward (Z_ARRVAL_P (arg2 ));
503
- }
504
- } else if (Z_TYPE_P (arg2 ) == IS_RESOURCE ) {
505
- ZEND_FETCH_RESOURCE (php_sock , php_socket * , & arg2 , -1 , le_socket_name , le_socket );
506
- FD_SET (php_sock -> bsd_socket , & (php_fd -> set ));
507
- max_fd = php_sock -> bsd_socket ;
508
- } else {
509
- php_error (E_ERROR , "%s() expecting argument 2 of type resource or array of resources" , get_active_function_name (TSRMLS_C ));
510
- RETURN_FALSE ;
448
+ FD_SET (php_sock -> bsd_socket , fds );
449
+ if (php_sock -> bsd_socket > * max_fd ) * max_fd = php_sock -> bsd_socket ;
511
450
}
512
-
513
- php_fd -> max_fd = max_fd ;
514
- RETURN_TRUE ;
451
+
452
+ return 1 ;
515
453
}
516
- /* }}} */
517
454
518
- /* {{{ proto bool socket_fd_clear(resource set, mixed socket)
519
- Clears (a) file descriptor(s) from a set */
520
- PHP_FUNCTION (socket_fd_clear )
521
- {
522
- zval * arg1 , * arg2 , * * tmp ;
523
- php_fd_set * php_fd ;
455
+ int php_sock_array_from_fd_set (zval * sock_array , fd_set * fds TSRMLS_DC ) {
456
+ zval * * element ;
457
+ zval * * dest_element ;
524
458
php_socket * php_sock ;
525
-
526
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "rz" , & arg1 , & arg2 ) == FAILURE )
527
- return ;
528
-
529
- ZEND_FETCH_RESOURCE (php_fd , php_fd_set * , & arg1 , -1 , le_destroy_name , le_destroy );
530
-
531
- if (Z_TYPE_P (arg2 ) == IS_ARRAY ) {
532
- zend_hash_internal_pointer_reset (Z_ARRVAL_P (arg2 ));
533
- while (zend_hash_get_current_data (Z_ARRVAL_P (arg2 ), (void * * )& tmp ) == SUCCESS ) {
534
- ZEND_FETCH_RESOURCE (php_sock , php_socket * , tmp , -1 , le_socket_name , le_socket );
535
- FD_CLR (php_sock -> bsd_socket , & (php_fd -> set ));
536
- zend_hash_move_forward (Z_ARRVAL_P (arg2 ));
459
+ HashTable * new_hash ;
460
+ if (Z_TYPE_P (sock_array ) != IS_ARRAY ) return 0 ;
461
+
462
+ ALLOC_HASHTABLE (new_hash );
463
+ zend_hash_init (new_hash , 0 , NULL , ZVAL_PTR_DTOR , 0 );
464
+ for (zend_hash_internal_pointer_reset (Z_ARRVAL_P (sock_array ));
465
+ zend_hash_get_current_data (Z_ARRVAL_P (sock_array ), (void * * ) & element ) == SUCCESS ;
466
+ zend_hash_move_forward (Z_ARRVAL_P (sock_array ))) {
467
+
468
+ php_sock = (php_socket * ) zend_fetch_resource (element TSRMLS_CC , -1 , le_socket_name , NULL , 1 , le_socket );
469
+ if (!php_sock ) continue ; /* If element is not a resource, skip it */
470
+
471
+ if (FD_ISSET (php_sock -> bsd_socket , fds )) {
472
+ /* Add fd to new array */
473
+ zend_hash_next_index_insert (new_hash , (void * )element , sizeof (zval * ), (void * * )& dest_element );
474
+ if (dest_element ) zval_add_ref (dest_element );
537
475
}
538
- } else if (Z_TYPE_P (arg2 ) == IS_RESOURCE ) {
539
- ZEND_FETCH_RESOURCE (php_sock , php_socket * , & arg2 , -1 , le_socket_name , le_socket );
540
- FD_CLR (php_sock -> bsd_socket , & (php_fd -> set ));
541
- } else {
542
- php_error (E_ERROR , "%s() expecting argument 2 of type resource or array of resources" , get_active_function_name (TSRMLS_C ));
543
- RETURN_FALSE ;
544
476
}
545
-
546
- php_fd -> max_fd = 0 ;
547
- RETURN_TRUE ;
548
- }
549
- /* }}} */
550
-
551
- /* {{{ proto bool socket_fd_isset(resource set, resource socket)
552
- Checks to see if a file descriptor is set within the file descrirptor set */
553
- PHP_FUNCTION (socket_fd_isset )
554
- {
555
- zval * arg1 , * arg2 ;
556
- php_fd_set * php_fd ;
557
- php_socket * php_sock ;
558
-
559
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "rr" , & arg1 , & arg2 ) == FAILURE )
560
- return ;
561
-
562
- ZEND_FETCH_RESOURCE (php_fd , php_fd_set * , & arg1 , -1 , le_destroy_name , le_destroy );
563
- ZEND_FETCH_RESOURCE (php_sock , php_socket * , & arg2 , -1 , le_socket_name , le_socket );
564
-
565
- if (FD_ISSET (php_sock -> bsd_socket , & (php_fd -> set ))) {
566
- RETURN_TRUE ;
567
- }
568
-
569
- RETURN_FALSE ;
570
- }
571
- /* }}} */
572
-
573
- /* {{{ proto bool socket_fd_zero(resource set)
574
- Clears a file descriptor set */
575
- PHP_FUNCTION (socket_fd_zero )
576
- {
577
- zval * arg1 ;
578
- php_fd_set * php_fd ;
579
-
580
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "r" , & arg1 ) == FAILURE )
581
- return ;
582
-
583
- ZEND_FETCH_RESOURCE (php_fd , php_fd_set * , & arg1 , -1 , le_destroy_name , le_destroy );
584
-
585
- FD_ZERO (& (php_fd -> set ));
586
477
587
- php_fd -> max_fd = 0 ;
588
-
589
- RETURN_TRUE ;
478
+ /* Destroy old array, add new one */
479
+ zend_hash_destroy (Z_ARRVAL_P (sock_array ));
480
+
481
+ zend_hash_internal_pointer_reset (new_hash );
482
+ Z_ARRVAL_P (sock_array ) = new_hash ;
483
+
484
+ return 1 ;
590
485
}
591
- /* }}} */
592
-
593
- /* {{{ proto int socket_select(resource read_fd, resource write_fd, resource except_fd , int tv_sec[, int tv_usec])
486
+
487
+
488
+ /* {{{ proto int socket_select(array &read_fds, array &write_fds, &array except_fds , int tv_sec[, int tv_usec])
594
489
Runs the select() system call on the sets mentioned with a timeout specified by tv_sec and tv_usec */
595
490
PHP_FUNCTION (socket_select )
596
491
{
597
- zval * arg1 , * arg2 , * arg3 , * arg4 ;
492
+ zval * r_array , * w_array , * e_array ;
598
493
struct timeval tv ;
599
- php_fd_set * rfds = NULL , * wfds = NULL , * xfds = NULL ;
494
+ fd_set rfds , wfds , efds ;
600
495
SOCKET max_fd = 0 ;
601
- int sets = 0 , usec = 0 ;
496
+ int retval , sets = 0 , usec = 0 , sec = 0 ;
602
497
603
- if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "r!r!r!z |l" , & arg1 , & arg2 , & arg3 , & arg4 , & usec ) == FAILURE )
498
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "a!a!a!l |l" , & r_array , & w_array , & e_array , & sec , & usec ) == FAILURE )
604
499
return ;
605
500
606
- if (arg1 != NULL ) {
607
- ZEND_FETCH_RESOURCE (rfds , php_fd_set * , & arg1 , -1 , le_destroy_name , le_destroy );
608
- max_fd = rfds -> max_fd ;
609
- sets ++ ;
610
- }
611
-
612
- if (arg2 != NULL ) {
613
- ZEND_FETCH_RESOURCE (wfds , php_fd_set * , & arg2 , -1 , le_destroy_name , le_destroy );
614
- max_fd = (max_fd > wfds -> max_fd ) ? max_fd : wfds -> max_fd ;
615
- sets ++ ;
616
- }
617
-
618
- if (arg3 != NULL ) {
619
- ZEND_FETCH_RESOURCE (xfds , php_fd_set * , & arg3 , -1 , le_destroy_name , le_destroy );
620
- max_fd = (max_fd > xfds -> max_fd ) ? max_fd : xfds -> max_fd ;
621
- sets ++ ;
622
- }
623
-
501
+ FD_ZERO (& rfds );
502
+ FD_ZERO (& wfds );
503
+ FD_ZERO (& efds );
504
+
505
+ if (r_array != NULL ) sets += php_sock_array_to_fd_set (r_array , & rfds , & max_fd TSRMLS_CC );
506
+ if (w_array != NULL ) sets += php_sock_array_to_fd_set (w_array , & wfds , & max_fd TSRMLS_CC );
507
+ if (e_array != NULL ) sets += php_sock_array_to_fd_set (e_array , & efds , & max_fd TSRMLS_CC );
508
+
624
509
if (!sets ) {
625
- php_error (E_ERROR , "%s() expecting at least one %s " , get_active_function_name (TSRMLS_C ), le_destroy_name );
510
+ php_error (E_WARNING , "%s() no resource arrays were passed to select " , get_active_function_name (TSRMLS_C ));
626
511
RETURN_FALSE ;
627
512
}
628
513
629
- if (Z_TYPE_P (arg4 ) != IS_NULL ) {
630
- tv .tv_sec = Z_LVAL_P (arg4 );
631
- tv .tv_usec = usec ;
632
- }
514
+ tv .tv_sec = sec ;
515
+ tv .tv_usec = usec ;
516
+
517
+ retval = select (max_fd + 1 , & rfds , & wfds , & efds , & tv );
518
+
519
+ if (r_array != NULL ) php_sock_array_from_fd_set (r_array , & rfds TSRMLS_CC );
520
+ if (w_array != NULL ) php_sock_array_from_fd_set (w_array , & wfds TSRMLS_CC );
521
+ if (e_array != NULL ) php_sock_array_from_fd_set (e_array , & efds TSRMLS_CC );
522
+
523
+ RETURN_LONG (retval );
633
524
634
- RETURN_LONG (select (max_fd + 1 , rfds ? & (rfds -> set ) : NULL ,
635
- wfds ? & (wfds -> set ) : NULL ,
636
- xfds ? & (xfds -> set ) : NULL ,
637
- (Z_TYPE_P (arg4 ) != IS_NULL ) ? & tv : NULL ));
638
525
}
639
526
/* }}} */
640
527
0 commit comments