summaryrefslogtreecommitdiff
path: root/ext/standard/streamsfuncs.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/streamsfuncs.c')
-rw-r--r--ext/standard/streamsfuncs.c292
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", &params) == 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, &params) == 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, &microseconds) == 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