wez Fri Sep 27 19:42:38 2002 EDT Modified files: /php4/ext/standard basic_functions.c file.c file.h Log: Implement stream_select() which works just like socket_select, but only on streams. @ - Added stream_select() which works like socket_select but only works on @ streams returned by fopen(), fsockopen() and pfsockopen(). (Wez)
Index: php4/ext/standard/basic_functions.c diff -u php4/ext/standard/basic_functions.c:1.513 php4/ext/standard/basic_functions.c:1.514 --- php4/ext/standard/basic_functions.c:1.513 Thu Sep 26 06:14:40 2002 +++ php4/ext/standard/basic_functions.c Fri Sep 27 19:42:38 2002 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.513 2002/09/26 10:14:40 wez Exp $ */ +/* $Id: basic_functions.c,v 1.514 2002/09/27 23:42:38 wez Exp $ */ #include "php.h" #include "php_streams.h" @@ -99,6 +99,9 @@ static unsigned char second_args_force_ref[] = { 2, BYREF_NONE, BYREF_FORCE }; static unsigned char third_and_fourth_args_force_ref[] = { 4, BYREF_NONE, BYREF_NONE, BYREF_FORCE, BYREF_FORCE }; static unsigned char third_and_rest_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE_REST }; +static unsigned char first_through_third_args_force_ref[] = +{3, BYREF_FORCE, BYREF_FORCE, BYREF_FORCE}; + typedef struct _php_shutdown_function_entry { zval **arguments; @@ -617,6 +620,7 @@ PHP_STATIC_FE("tmpfile", php_if_tmpfile, NULL) PHP_FE(file, NULL) PHP_FE(file_get_contents, NULL) + PHP_FE(stream_select, +first_through_third_args_force_ref) PHP_FE(stream_context_create, NULL) PHP_FE(stream_context_set_params, NULL) PHP_FE(stream_context_set_option, NULL) @@ -628,11 +632,9 @@ PHP_FE(get_meta_tags, NULL) PHP_FE(set_file_buffer, NULL) - /* set_socket_blocking() is deprecated, - use socket_set_blocking() instead - */ PHP_FE(set_socket_blocking, NULL) - PHP_FE(socket_set_blocking, NULL) + PHP_FE(stream_set_blocking, + NULL) + PHP_FALIAS(socket_set_blocking, stream_set_blocking, + NULL) PHP_FE(file_get_meta_data, NULL) PHP_FE(file_register_wrapper, NULL) Index: php4/ext/standard/file.c diff -u php4/ext/standard/file.c:1.263 php4/ext/standard/file.c:1.264 --- php4/ext/standard/file.c:1.263 Thu Sep 26 08:12:26 2002 +++ php4/ext/standard/file.c Fri Sep 27 19:42:38 2002 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.c,v 1.263 2002/09/26 12:12:26 wez Exp $ */ +/* $Id: file.c,v 1.264 2002/09/27 23:42:38 wez Exp $ */ /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */ @@ -639,6 +639,130 @@ } /* }}} */ +static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, int *max_fd +TSRMLS_DC) +{ + zval **elem; + php_stream *stream; + int this_fd; + + if (Z_TYPE_P(stream_array) != IS_ARRAY) + return 0; + + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); + zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) +== SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { + + php_stream_from_zval_no_verify(stream, elem); + if (stream == NULL) + continue; + + /* get the fd */ + if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, +(void*)&this_fd, 1)) { + FD_SET(this_fd, fds); + if (this_fd > *max_fd) { + *max_fd = this_fd; + } + } + } + + return 1; + +} + +static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) +{ + zval **elem, **dest_elem; + php_stream *stream; + HashTable *new_hash; + int this_fd; + + if (Z_TYPE_P(stream_array) != IS_ARRAY) + return 0; + + ALLOC_HASHTABLE(new_hash); + zend_hash_init(new_hash, 0, NULL, ZVAL_PTR_DTOR, 0); + + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); + zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) +== SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { + + php_stream_from_zval_no_verify(stream, elem); + if (stream == NULL) + continue; + + /* get the fd */ + if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, +(void*)&this_fd, 1)) { + if (FD_ISSET(this_fd, fds)) { + zend_hash_next_index_insert(new_hash, (void *)elem, +sizeof(zval *), (void **)&dest_elem); + if (dest_elem) + zval_add_ref(dest_elem); + } + } + } + + /* destroy old array and add new one */ + zend_hash_destroy(Z_ARRVAL_P(stream_array)); + efree(Z_ARRVAL_P(stream_array)); + + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(stream_array) = new_hash; + + return 1; + +} + + +/* {{{ proto int stream_select(array &read_streams, array &write_streams, array +&except_streams, int tv_sec[, int tv_usec]) + Runs the select() system call on the sets of streams with a timeout specified by +tv_sec and tv_usec */ +PHP_FUNCTION(stream_select) +{ + zval *r_array, *w_array, *e_array, *sec; + struct timeval tv; + struct timeval *tv_p = NULL; + fd_set rfds, wfds, efds; + int max_fd = 0; + int retval, sets = 0, usec = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!a!z!|l", &r_array, +&w_array, &e_array, &sec, &usec) == FAILURE) + return; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + + if (r_array != NULL) sets += stream_array_to_fd_set(r_array, &rfds, &max_fd +TSRMLS_CC); + if (w_array != NULL) sets += stream_array_to_fd_set(w_array, &wfds, &max_fd +TSRMLS_CC); + if (e_array != NULL) sets += stream_array_to_fd_set(e_array, &efds, &max_fd +TSRMLS_CC); + + if (!sets) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stream arrays were +passed"); + RETURN_FALSE; + } + + /* If seconds is not set to null, build the timeval, else we wait indefinitely +*/ + if (sec != NULL) { + convert_to_long_ex(&sec); + tv.tv_sec = Z_LVAL_P(sec); + tv.tv_usec = usec; + tv_p = &tv; + } + + retval = select(max_fd+1, &rfds, &wfds, &efds, tv_p); + + if (retval == -1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to select [%d]: +%s", + errno, strerror(errno)); + RETURN_FALSE; + } + + if (r_array != NULL) stream_array_from_fd_set(r_array, &rfds TSRMLS_CC); + if (w_array != NULL) stream_array_from_fd_set(w_array, &wfds TSRMLS_CC); + if (e_array != NULL) stream_array_from_fd_set(e_array, &efds TSRMLS_CC); + + RETURN_LONG(retval); +} + + /* {{{ stream_context related functions */ static void user_space_stream_notifier(php_stream_context *context, int notifycode, int severity, char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr TSRMLS_DC) @@ -846,6 +970,7 @@ } /* }}} */ +/* {{{ streams filter functions */ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) { zval *zstream; @@ -888,6 +1013,7 @@ apply_filter_to_stream(1, INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ +/* }}} */ /* {{{ proto resource fopen(string filename, string mode [, bool use_include_path [, resource context]]) Open a file or a URL and return a file pointer */ @@ -1045,9 +1171,9 @@ } /* }}} */ -/* {{{ proto bool socket_set_blocking(resource socket, int mode) +/* {{{ proto bool stream_set_blocking(resource socket, int mode) Set blocking/non-blocking mode on a socket or stream */ -PHP_FUNCTION(socket_set_blocking) +PHP_FUNCTION(stream_set_blocking) { zval **arg1, **arg2; int block; @@ -1073,8 +1199,8 @@ Set blocking/non-blocking mode on a socket */ PHP_FUNCTION(set_socket_blocking) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "This function is deprecated, use socket_set_blocking() instead"); - PHP_FN(socket_set_blocking)(INTERNAL_FUNCTION_PARAM_PASSTHRU); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "This function is deprecated, use +stream_set_blocking() instead"); + PHP_FN(stream_set_blocking)(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ Index: php4/ext/standard/file.h diff -u php4/ext/standard/file.h:1.68 php4/ext/standard/file.h:1.69 --- php4/ext/standard/file.h:1.68 Thu Sep 26 08:12:27 2002 +++ php4/ext/standard/file.h Fri Sep 27 19:42:38 2002 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.h,v 1.68 2002/09/26 12:12:27 wez Exp $ */ +/* $Id: file.h,v 1.69 2002/09/27 23:42:38 wez Exp $ */ /* Synced with php 3.0 revision 1.30 1999-06-16 [ssb] */ @@ -55,7 +55,8 @@ PHP_FUNCTION(file); PHP_FUNCTION(file_get_contents); PHP_FUNCTION(set_socket_blocking); /* deprecated */ -PHP_FUNCTION(socket_set_blocking); +PHP_FUNCTION(stream_set_blocking); +PHP_FUNCTION(stream_select); PHP_FUNCTION(socket_set_timeout); PHP_FUNCTION(set_file_buffer); PHP_FUNCTION(get_meta_tags);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php