diff options
Diffstat (limited to 'ext/standard/streamsfuncs.c')
| -rw-r--r-- | ext/standard/streamsfuncs.c | 292 |
1 files changed, 219 insertions, 73 deletions
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index ba3387d7ce..34a5d97495 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -30,6 +30,9 @@ #include "streamsfuncs.h" #include "php_network.h" #include "php_string.h" +#if HAVE_UNISTD_H +#include <unistd.h> +#endif #ifndef PHP_WIN32 #define php_select(m, r, w, e, t) select(m, r, w, e, t) @@ -37,6 +40,7 @@ typedef unsigned long long php_timeout_ull; #else #include "win32/select.h" #include "win32/sockets.h" +#include "win32/console.h" typedef unsigned __int64 php_timeout_ull; #endif @@ -55,10 +59,11 @@ PHP_FUNCTION(stream_socket_pair) php_stream *s1, *s2; php_socket_t pair[2]; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "lll", - &domain, &type, &protocol)) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_LONG(domain) + Z_PARAM_LONG(type) + Z_PARAM_LONG(protocol) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); if (0 != socketpair((int)domain, (int)type, (int)protocol, pair)) { char errbuf[256]; @@ -101,9 +106,15 @@ PHP_FUNCTION(stream_socket_client) RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|z/z/dlr", &host, &zerrno, &zerrstr, &timeout, &flags, &zcontext) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(1, 6) + Z_PARAM_STR(host) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL_DEREF(zerrno) + Z_PARAM_ZVAL_DEREF(zerrstr) + Z_PARAM_DOUBLE(timeout) + Z_PARAM_LONG(flags) + Z_PARAM_RESOURCE(zcontext) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); @@ -121,11 +132,11 @@ PHP_FUNCTION(stream_socket_client) tv.tv_usec = conv % 1000000; #endif if (zerrno) { - zval_dtor(zerrno); + zval_ptr_dtor(zerrno); ZVAL_LONG(zerrno, 0); } if (zerrstr) { - zval_dtor(zerrstr); + zval_ptr_dtor(zerrstr); ZVAL_EMPTY_STRING(zerrstr); } @@ -149,11 +160,11 @@ PHP_FUNCTION(stream_socket_client) if (stream == NULL) { if (zerrno) { - zval_dtor(zerrno); + zval_ptr_dtor(zerrno); ZVAL_LONG(zerrno, err); } if (zerrstr && errstr) { - zval_dtor(zerrstr); + zval_ptr_dtor(zerrstr); ZVAL_STR(zerrstr, errstr); } else if (errstr) { zend_string_release(errstr); @@ -185,9 +196,14 @@ PHP_FUNCTION(stream_socket_server) RETVAL_FALSE; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|z/z/lr", &host, &host_len, &zerrno, &zerrstr, &flags, &zcontext) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(1, 5) + Z_PARAM_STRING(host, host_len) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL_DEREF(zerrno) + Z_PARAM_ZVAL_DEREF(zerrstr) + Z_PARAM_LONG(flags) + Z_PARAM_RESOURCE(zcontext) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); @@ -196,11 +212,11 @@ PHP_FUNCTION(stream_socket_server) } if (zerrno) { - zval_dtor(zerrno); + zval_ptr_dtor(zerrno); ZVAL_LONG(zerrno, 0); } if (zerrstr) { - zval_dtor(zerrstr); + zval_ptr_dtor(zerrstr); ZVAL_EMPTY_STRING(zerrstr); } @@ -214,11 +230,11 @@ PHP_FUNCTION(stream_socket_server) if (stream == NULL) { if (zerrno) { - zval_dtor(zerrno); + zval_ptr_dtor(zerrno); ZVAL_LONG(zerrno, err); } if (zerrstr && errstr) { - zval_dtor(zerrstr); + zval_ptr_dtor(zerrstr); ZVAL_STR(zerrstr, errstr); } else if (errstr) { zend_string_release(errstr); @@ -251,7 +267,7 @@ PHP_FUNCTION(stream_socket_accept) Z_PARAM_RESOURCE(zstream) Z_PARAM_OPTIONAL Z_PARAM_DOUBLE(timeout) - Z_PARAM_ZVAL_EX(zpeername, 0, 1) + Z_PARAM_ZVAL_DEREF(zpeername) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); php_stream_from_zval(stream, zstream); @@ -266,7 +282,7 @@ PHP_FUNCTION(stream_socket_accept) tv.tv_usec = conv % 1000000; #endif if (zpeername) { - zval_dtor(zpeername); + zval_ptr_dtor(zpeername); ZVAL_NULL(zpeername); } @@ -335,9 +351,13 @@ PHP_FUNCTION(stream_socket_sendto) php_sockaddr_storage sa; socklen_t sl = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|ls", &zstream, &data, &datalen, &flags, &target_addr, &target_addr_len) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_RESOURCE(zstream) + Z_PARAM_STRING(data, datalen) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + Z_PARAM_STRING(target_addr, target_addr_len) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); php_stream_from_zval(stream, zstream); if (target_addr_len) { @@ -364,14 +384,18 @@ PHP_FUNCTION(stream_socket_recvfrom) zend_long flags = 0; int recvd; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|lz/", &zstream, &to_read, &flags, &zremote) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_RESOURCE(zstream) + Z_PARAM_LONG(to_read) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + Z_PARAM_ZVAL_DEREF(zremote) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); php_stream_from_zval(stream, zstream); if (zremote) { - zval_dtor(zremote); + zval_ptr_dtor(zremote); ZVAL_NULL(zremote); } @@ -410,9 +434,12 @@ PHP_FUNCTION(stream_get_contents) desiredpos = -1L; zend_string *contents; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|ll", &zsrc, &maxlen, &desiredpos) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_RESOURCE(zsrc) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(maxlen) + Z_PARAM_LONG(desiredpos) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); php_stream_from_zval(stream, zsrc); @@ -458,9 +485,13 @@ PHP_FUNCTION(stream_copy_to_stream) size_t len; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|ll", &zsrc, &zdest, &maxlen, &pos) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_RESOURCE(zsrc) + Z_PARAM_RESOURCE(zdest) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(maxlen) + Z_PARAM_LONG(pos) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); php_stream_from_zval(src, zsrc); php_stream_from_zval(dest, zdest); @@ -1061,9 +1092,10 @@ PHP_FUNCTION(stream_context_get_default) zval *params = NULL; php_stream_context *context; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a", ¶ms) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY(params) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); if (FG(default_context) == NULL) { FG(default_context) = php_stream_context_alloc(); @@ -1085,9 +1117,9 @@ PHP_FUNCTION(stream_context_set_default) zval *options = NULL; php_stream_context *context; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &options) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY(options) + ZEND_PARSE_PARAMETERS_END(); if (FG(default_context) == NULL) { FG(default_context) = php_stream_context_alloc(); @@ -1107,9 +1139,11 @@ PHP_FUNCTION(stream_context_create) zval *options = NULL, *params = NULL; php_stream_context *context; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!a!", &options, ¶ms) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(0, 2) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_EX(options, 1, 0) + Z_PARAM_ARRAY_EX(params, 1, 0) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); context = php_stream_context_alloc(); @@ -1137,10 +1171,13 @@ static void apply_filter_to_stream(int append, INTERNAL_FUNCTION_PARAMETERS) php_stream_filter *filter = NULL; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|lz", &zstream, - &filtername, &filternamelen, &read_write, &filterparams) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_RESOURCE(zstream) + Z_PARAM_STRING(filtername, filternamelen) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(read_write) + Z_PARAM_ZVAL(filterparams) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); php_stream_from_zval(stream, zstream); @@ -1225,9 +1262,9 @@ PHP_FUNCTION(stream_filter_remove) zval *zfilter; php_stream_filter *filter; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zfilter) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_RESOURCE(zfilter) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); filter = zend_fetch_resource(Z_RES_P(zfilter), NULL, php_file_le_stream_filter()); if (!filter) { @@ -1261,9 +1298,12 @@ PHP_FUNCTION(stream_get_line) zend_string *buf; php_stream *stream; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|s", &zstream, &max_length, &str, &str_len) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(zstream) + Z_PARAM_LONG(max_length) + Z_PARAM_OPTIONAL + Z_PARAM_STRING(str, str_len) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); if (max_length < 0) { php_error_docref(NULL, E_WARNING, "The maximum allowed length must be greater than or equal to zero"); @@ -1319,9 +1359,12 @@ PHP_FUNCTION(stream_set_timeout) php_stream *stream; int argc = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argc, "rl|l", &socket, &seconds, µseconds) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(socket) + Z_PARAM_LONG(seconds) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(microseconds) + ZEND_PARSE_PARAMETERS_END(); php_stream_from_zval(stream, socket); @@ -1364,9 +1407,10 @@ PHP_FUNCTION(stream_set_write_buffer) size_t buff; php_stream *stream; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &arg1, &arg2) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_RESOURCE(arg1) + Z_PARAM_LONG(arg2) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); php_stream_from_zval(stream, arg1); @@ -1392,9 +1436,10 @@ PHP_FUNCTION(stream_set_chunk_size) zval *zstream; php_stream *stream; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &zstream, &csize) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_RESOURCE(zstream) + Z_PARAM_LONG(csize) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); if (csize <= 0) { php_error_docref(NULL, E_WARNING, "The chunk size must be a positive integer, given " ZEND_LONG_FMT, csize); @@ -1427,9 +1472,10 @@ PHP_FUNCTION(stream_set_read_buffer) size_t buff; php_stream *stream; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &arg1, &arg2) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_RESOURCE(arg1) + Z_PARAM_LONG(arg2) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); php_stream_from_zval(stream, arg1); @@ -1509,9 +1555,9 @@ PHP_FUNCTION(stream_resolve_include_path) size_t filename_len; zend_string *resolved_path; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &filename, &filename_len) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_PATH(filename, filename_len) + ZEND_PARSE_PARAMETERS_END(); resolved_path = zend_resolve_path(filename, (int)filename_len); @@ -1530,9 +1576,9 @@ PHP_FUNCTION(stream_is_local) php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zstream) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(zstream) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); if (Z_TYPE_P(zstream) == IS_RESOURCE) { php_stream_from_zval(stream, zstream); @@ -1561,9 +1607,9 @@ PHP_FUNCTION(stream_supports_lock) php_stream *stream; zval *zsrc; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zsrc) == FAILURE) { - RETURN_FALSE; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_RESOURCE(zsrc) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); php_stream_from_zval(stream, zsrc); @@ -1574,6 +1620,106 @@ PHP_FUNCTION(stream_supports_lock) RETURN_TRUE; } +/* {{{ proto bool stream_isatty(resource stream) +Check if a stream is a TTY. +*/ +PHP_FUNCTION(stream_isatty) +{ + zval *zsrc; + php_stream *stream; + zend_long fileno; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_RESOURCE(zsrc) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + + php_stream_from_zval(stream, zsrc); + + if (php_stream_can_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT) == SUCCESS) { + php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT, (void*)&fileno, 0); + } else if (php_stream_can_cast(stream, PHP_STREAM_AS_FD) == SUCCESS) { + php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fileno, 0); + } else { + RETURN_FALSE; + } + +#ifdef PHP_WIN32 + /* Check if the Windows standard handle is redirected to file */ + RETVAL_BOOL(php_win32_console_fileno_is_console(fileno)); +#elif HAVE_UNISTD_H + /* Check if the file descriptor identifier is a terminal */ + RETVAL_BOOL(isatty(fileno)); +#else + { + zend_stat_t stat = {0}; + RETVAL_BOOL(zend_fstat(fileno, &stat) == 0 && (stat.st_mode & /*S_IFMT*/0170000) == /*S_IFCHR*/0020000); + } +#endif +} + +#ifdef PHP_WIN32 +/* {{{ proto bool sapi_windows_vt100_support(resource stream[, bool enable]) + Get or set VT100 support for the specified stream associated to an + output buffer of a Windows console. +*/ +PHP_FUNCTION(sapi_windows_vt100_support) +{ + zval *zsrc; + php_stream *stream; + zend_bool enable; + zend_long fileno; + + int argc = ZEND_NUM_ARGS(); + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(zsrc) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(enable) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + + php_stream_from_zval(stream, zsrc); + + if (php_stream_can_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT) == SUCCESS) { + php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT, (void*)&fileno, 0); + } + else if (php_stream_can_cast(stream, PHP_STREAM_AS_FD) == SUCCESS) { + php_stream_cast(stream, PHP_STREAM_AS_FD, (void*)&fileno, 0); + } + else { + zend_internal_type_error( + ZEND_ARG_USES_STRICT_TYPES(), + "%s() was not able to analyze the specified stream", + get_active_function_name() + ); + RETURN_FALSE; + } + + /* Check if the file descriptor is a console */ + if (!php_win32_console_fileno_is_console(fileno)) { + RETURN_FALSE; + } + + if (argc == 1) { + /* Check if the Windows standard handle has VT100 control codes enabled */ + if (php_win32_console_fileno_has_vt100(fileno)) { + RETURN_TRUE; + } + else { + RETURN_FALSE; + } + } + else { + /* Enable/disable VT100 control codes support for the specified Windows standard handle */ + if (php_win32_console_fileno_set_vt100(fileno, enable ? TRUE : FALSE)) { + RETURN_TRUE; + } + else { + RETURN_FALSE; + } + } +} +#endif + #ifdef HAVE_SHUTDOWN /* {{{ proto int stream_socket_shutdown(resource stream, int how) causes all or part of a full-duplex connection on the socket associated |
