diff options
Diffstat (limited to 'ext/standard/streamsfuncs.c')
-rw-r--r-- | ext/standard/streamsfuncs.c | 175 |
1 files changed, 98 insertions, 77 deletions
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index a0300606f..6285a337f 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streamsfuncs.c 293995 2010-01-25 15:57:24Z johannes $ */ +/* $Id: streamsfuncs.c 297895 2010-04-12 13:10:05Z pajoye $ */ #include "php.h" #include "php_globals.h" @@ -70,7 +70,7 @@ PHP_FUNCTION(stream_socket_pair) s1 = php_stream_sock_open_from_socket(pair[0], 0); s2 = php_stream_sock_open_from_socket(pair[1], 0); - /* set the __exposed flag. + /* set the __exposed flag. * php_stream_to_zval() does, add_next_index_resource() does not */ php_stream_auto_cleanup(s1); php_stream_auto_cleanup(s2); @@ -99,11 +99,11 @@ PHP_FUNCTION(stream_socket_client) php_stream_context *context = NULL; RETVAL_FALSE; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zzdlr", &host, &host_len, &zerrno, &zerrstr, &timeout, &flags, &zcontext) == FAILURE) { RETURN_FALSE; } - + context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); if (context) { @@ -113,7 +113,7 @@ PHP_FUNCTION(stream_socket_client) if (flags & PHP_STREAM_CLIENT_PERSISTENT) { spprintf(&hashkey, 0, "stream_socket_client__%s", host); } - + /* prepare the timeout value for use */ conv = (php_timeout_ull) (timeout * 1000000.0); tv.tv_sec = conv / 1000000; @@ -132,12 +132,12 @@ PHP_FUNCTION(stream_socket_client) STREAM_XPORT_CLIENT | (flags & PHP_STREAM_CLIENT_CONNECT ? STREAM_XPORT_CONNECT : 0) | (flags & PHP_STREAM_CLIENT_ASYNC_CONNECT ? STREAM_XPORT_CONNECT_ASYNC : 0), hashkey, &tv, context, &errstr, &err); - + if (stream == NULL) { /* host might contain binary characters */ char *quoted_host = php_addslashes(host, host_len, NULL, 0 TSRMLS_CC); - + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s (%s)", quoted_host, errstr == NULL ? "Unknown error" : errstr); efree(quoted_host); } @@ -145,7 +145,7 @@ PHP_FUNCTION(stream_socket_client) if (hashkey) { efree(hashkey); } - + if (stream == NULL) { if (zerrno) { zval_dtor(zerrno); @@ -160,13 +160,13 @@ PHP_FUNCTION(stream_socket_client) } RETURN_FALSE; } - + if (errstr) { efree(errstr); } - + php_stream_to_zval(stream, return_value); - + } /* }}} */ @@ -184,13 +184,13 @@ PHP_FUNCTION(stream_socket_server) php_stream_context *context = NULL; RETVAL_FALSE; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|zzlr", &host, &host_len, &zerrno, &zerrstr, &flags, &zcontext) == FAILURE) { RETURN_FALSE; } - + context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); - + if (context) { zend_list_addref(context->rsrc_id); } @@ -207,11 +207,11 @@ PHP_FUNCTION(stream_socket_server) stream = php_stream_xport_create(host, host_len, ENFORCE_SAFE_MODE | REPORT_ERRORS, STREAM_XPORT_SERVER | flags, NULL, NULL, context, &errstr, &err); - + if (stream == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s (%s)", host, errstr == NULL ? "Unknown error" : errstr); } - + if (stream == NULL) { if (zerrno) { zval_dtor(zerrno); @@ -226,11 +226,11 @@ PHP_FUNCTION(stream_socket_server) } RETURN_FALSE; } - + if (errstr) { efree(errstr); } - + php_stream_to_zval(stream, return_value); } /* }}} */ @@ -249,13 +249,13 @@ PHP_FUNCTION(stream_socket_accept) zval *zstream; char *errstr = NULL; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|dz", &zstream, &timeout, &zpeername) == FAILURE) { RETURN_FALSE; } - + php_stream_from_zval(stream, &zstream); - + /* prepare the timeout value for use */ conv = (php_timeout_ull) (timeout * 1000000.0); tv.tv_sec = conv / 1000000; @@ -272,7 +272,7 @@ PHP_FUNCTION(stream_socket_accept) NULL, NULL, &tv, &errstr TSRMLS_CC) && clistream) { - + if (peername) { ZVAL_STRINGL(zpeername, peername, peername_len, 0); } @@ -297,11 +297,11 @@ PHP_FUNCTION(stream_socket_get_name) zend_bool want_peer; char *name = NULL; int name_len; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb", &zstream, &want_peer) == FAILURE) { RETURN_FALSE; } - + php_stream_from_zval(stream, &zstream); if (0 != php_stream_xport_get_name(stream, want_peer, @@ -327,7 +327,7 @@ PHP_FUNCTION(stream_socket_sendto) int datalen, target_addr_len = 0; php_sockaddr_storage sa; socklen_t sl = 0; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|ls", &zstream, &data, &datalen, &flags, &target_addr, &target_addr_len) == FAILURE) { RETURN_FALSE; } @@ -357,11 +357,11 @@ PHP_FUNCTION(stream_socket_recvfrom) char *read_buf; long flags = 0; int recvd; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|lz", &zstream, &to_read, &flags, &zremote) == FAILURE) { RETURN_FALSE; } - + php_stream_from_zval(stream, &zstream); if (zremote) { @@ -373,9 +373,9 @@ PHP_FUNCTION(stream_socket_recvfrom) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0"); RETURN_FALSE; } - + read_buf = safe_emalloc(1, to_read, 1); - + recvd = php_stream_xport_recvfrom(stream, read_buf, to_read, flags, NULL, NULL, zremote ? &remote_addr : NULL, zremote ? &remote_addr_len : NULL @@ -423,7 +423,7 @@ PHP_FUNCTION(stream_get_contents) } len = php_stream_copy_to_mem(stream, &contents, maxlen, 0); - + if (contents) { if (len && PG(magic_quotes_runtime)) { contents = php_addslashes(contents, len, &newlen, 1 TSRMLS_CC); /* 1 = free source string */ @@ -481,7 +481,7 @@ PHP_FUNCTION(stream_get_meta_data) php_stream_from_zval(stream, &arg1); array_init(return_value); - + if (stream->wrapperdata) { MAKE_STD_ZVAL(newval); MAKE_COPY_ZVAL(&stream->wrapperdata, newval); @@ -494,14 +494,14 @@ PHP_FUNCTION(stream_get_meta_data) add_assoc_string(return_value, "stream_type", (char *)stream->ops->label, 1); add_assoc_string(return_value, "mode", stream->mode, 1); - + #if 0 /* TODO: needs updating for new filter API */ if (stream->filterhead) { php_stream_filter *filter; - + MAKE_STD_ZVAL(newval); array_init(newval); - + for (filter = stream->filterhead; filter != NULL; filter = filter->next) { add_next_index_string(newval, (char *)filter->fops->label, 1); } @@ -509,7 +509,7 @@ PHP_FUNCTION(stream_get_meta_data) add_assoc_zval(return_value, "filters", newval); } #endif - + add_assoc_long(return_value, "unread_bytes", stream->writepos - stream->readpos); add_assoc_bool(return_value, "seekable", (stream->ops->seek) && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0); @@ -610,7 +610,7 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t * is not displayed. * */ if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && this_fd >= 0) { - + PHP_SAFE_FD_SET(this_fd, fds); if (this_fd > *max_fd) { @@ -635,7 +635,7 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) } ALLOC_HASHTABLE(new_hash); zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(stream_array)), 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))) { @@ -644,7 +644,7 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) if (stream == NULL) { continue; } - /* get the fd + /* get the fd * NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag * when casting. It is only used here so that the buffered data warning * is not displayed. @@ -667,7 +667,7 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) zend_hash_internal_pointer_reset(new_hash); Z_ARRVAL_P(stream_array) = new_hash; - + return ret; } @@ -683,7 +683,7 @@ static int stream_array_emulate_read_fd_set(zval *stream_array TSRMLS_DC) } ALLOC_HASHTABLE(new_hash); zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(stream_array)), 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))) { @@ -719,7 +719,7 @@ static int stream_array_emulate_read_fd_set(zval *stream_array TSRMLS_DC) zend_hash_destroy(new_hash); FREE_HASHTABLE(new_hash); } - + return ret; } /* }}} */ @@ -750,7 +750,7 @@ PHP_FUNCTION(stream_select) max_set_count = set_count; sets += set_count; } - + if (w_array != NULL) { set_count = stream_array_to_fd_set(w_array, &wfds, &max_fd TSRMLS_CC); if (set_count > max_set_count) @@ -787,7 +787,7 @@ PHP_FUNCTION(stream_select) /* Solaris + BSD do not like microsecond values which are >= 1 sec */ if (usec > 999999) { tv.tv_sec = Z_LVAL_PP(sec) + (usec / 1000000); - tv.tv_usec = usec % 1000000; + tv.tv_usec = usec % 1000000; } else { tv.tv_sec = Z_LVAL_PP(sec); tv.tv_usec = usec; @@ -812,7 +812,7 @@ PHP_FUNCTION(stream_select) RETURN_LONG(retval); } } - + retval = php_select(max_fd+1, &rfds, &wfds, &efds, tv_p); if (retval == -1) { @@ -839,14 +839,14 @@ static void user_space_stream_notifier(php_stream_context *context, int notifyco zval *ps[6]; zval **ptps[6]; int i; - + for (i = 0; i < 6; i++) { INIT_ZVAL(zvs[i]); ps[i] = &zvs[i]; ptps[i] = &ps[i]; MAKE_STD_ZVAL(ps[i]); } - + ZVAL_LONG(ps[0], notifycode); ZVAL_LONG(ps[1], severity); if (xmsg) { @@ -885,7 +885,7 @@ static int parse_context_options(php_stream_context *context, zval *options TSRM int wkey_len, okey_len; int ret = SUCCESS; ulong num_key; - + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(options), &pos); while (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_P(options), (void**)&wval, &pos)) { if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_P(options), &wkey, &wkey_len, &num_key, 0, &pos) @@ -915,7 +915,7 @@ static int parse_context_params(php_stream_context *context, zval *params TSRMLS zval **tmp; if (SUCCESS == zend_hash_find(Z_ARRVAL_P(params), "notification", sizeof("notification"), (void**)&tmp)) { - + if (context->notifier) { php_stream_notification_free(context->notifier); context->notifier = NULL; @@ -934,7 +934,7 @@ static int parse_context_params(php_stream_context *context, zval *params TSRMLS php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid stream/context parameter"); } } - + return ret; } @@ -1082,7 +1082,7 @@ PHP_FUNCTION(stream_context_get_default) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", ¶ms) == FAILURE) { RETURN_FALSE; } - + if (FG(default_context) == NULL) { FG(default_context) = php_stream_context_alloc(); } @@ -1091,7 +1091,7 @@ PHP_FUNCTION(stream_context_get_default) if (params) { parse_context_options(context, params TSRMLS_CC); } - + php_stream_context_to_zval(context, return_value); } /* }}} */ @@ -1128,9 +1128,9 @@ PHP_FUNCTION(stream_context_create) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!a!", &options, ¶ms) == FAILURE) { RETURN_FALSE; } - + context = php_stream_context_alloc(); - + if (options) { parse_context_options(context, options TSRMLS_CC); } @@ -1138,7 +1138,7 @@ PHP_FUNCTION(stream_context_create) if (params) { parse_context_params(context, params TSRMLS_CC); } - + RETURN_RESOURCE(context->rsrc_id); } /* }}} */ @@ -1166,7 +1166,7 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) /* Chain not specified. * Examine stream->mode to determine which filters are needed * There's no harm in attaching a filter to an unused chain, - * but why waste the memory and clock cycles? + * but why waste the memory and clock cycles? */ if (strchr(stream->mode, 'r') || strchr(stream->mode, '+')) { read_write |= PHP_STREAM_FILTER_READ; @@ -1182,7 +1182,7 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) RETURN_FALSE; } - if (append) { + if (append) { ret = php_stream_filter_append_ex(&stream->readfilters, filter TSRMLS_CC); } else { ret = php_stream_filter_prepend_ex(&stream->readfilters, filter TSRMLS_CC); @@ -1199,7 +1199,7 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) RETURN_FALSE; } - if (append) { + if (append) { ret = php_stream_filter_append_ex(&stream->writefilters, filter TSRMLS_CC); } else { ret = php_stream_filter_prepend_ex(&stream->writefilters, filter TSRMLS_CC); @@ -1277,7 +1277,7 @@ PHP_FUNCTION(stream_get_line) char *buf; size_t buf_size; php_stream *stream; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|s", &zstream, &max_length, &str, &str_len) == FAILURE) { RETURN_FALSE; } @@ -1372,18 +1372,10 @@ PHP_FUNCTION(stream_set_write_buffer) size_t buff; php_stream *stream; - switch (ZEND_NUM_ARGS()) { - case 2: - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &arg2) == FAILURE) { - RETURN_FALSE; - } - break; - default: - WRONG_PARAM_COUNT; - /* NOTREACHED */ - break; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &arg2) == FAILURE) { + RETURN_FALSE; } - + php_stream_from_zval(stream, &arg1); buff = arg2; @@ -1399,6 +1391,35 @@ PHP_FUNCTION(stream_set_write_buffer) } /* }}} */ +/* {{{ proto int stream_set_read_buffer(resource fp, int buffer) + Set file read buffer */ +PHP_FUNCTION(stream_set_read_buffer) +{ + zval *arg1; + int ret; + long arg2; + size_t buff; + php_stream *stream; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &arg2) == FAILURE) { + RETURN_FALSE; + } + + php_stream_from_zval(stream, &arg1); + + buff = arg2; + + /* if buff is 0 then set to non-buffered */ + if (buff == 0) { + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_READ_BUFFER, PHP_STREAM_BUFFER_NONE, NULL); + } else { + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_READ_BUFFER, PHP_STREAM_BUFFER_FULL, &buff); + } + + RETURN_LONG(ret == 0 ? 0 : EOF); +} +/* }}} */ + /* {{{ proto int stream_socket_enable_crypto(resource stream, bool enable [, int cryptokind [, resource sessionstream]]) Enable or disable a specific kind of crypto on the stream */ PHP_FUNCTION(stream_socket_enable_crypto) @@ -1408,18 +1429,18 @@ PHP_FUNCTION(stream_socket_enable_crypto) php_stream *stream, *sessstream = NULL; zend_bool enable; int ret; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb|lr", &zstream, &enable, &cryptokind, &zsessstream) == FAILURE) { RETURN_FALSE; } - + php_stream_from_zval(stream, &zstream); if (ZEND_NUM_ARGS() >= 3) { if (zsessstream) { php_stream_from_zval(sessstream, &zsessstream); } - + if (php_stream_xport_crypto_setup(stream, cryptokind, sessstream TSRMLS_CC) < 0) { RETURN_FALSE; } @@ -1435,7 +1456,7 @@ PHP_FUNCTION(stream_socket_enable_crypto) case 0: RETURN_LONG(0); - + default: RETURN_TRUE; } @@ -1446,7 +1467,7 @@ PHP_FUNCTION(stream_socket_enable_crypto) Determine what file will be opened by calls to fopen() with a relative path */ PHP_FUNCTION(stream_resolve_include_path) { - char *filename, *resolved_path; + char *filename, *resolved_path; int filename_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { @@ -1482,7 +1503,7 @@ PHP_FUNCTION(stream_is_local) wrapper = stream->wrapper; } else { convert_to_string_ex(zstream); - + wrapper = php_stream_locate_url_wrapper(Z_STRVAL_PP(zstream), NULL, 0 TSRMLS_CC); } @@ -1526,11 +1547,11 @@ PHP_FUNCTION(stream_socket_shutdown) long how; zval *zstream; php_stream *stream; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zstream, &how) == FAILURE) { RETURN_FALSE; } - + if (how != STREAM_SHUT_RD && how != STREAM_SHUT_WR && how != STREAM_SHUT_RDWR) { |