-
Couldn't load subscription status.
- Fork 8k
Implement stream_vt100_support user function #2103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
a0e0d8d
18c5c42
be50062
e11f3d2
6953d2f
bd93781
35bf19a
d9b1c99
2f05643
694e207
4f4ffd0
3fcdc64
99bd01e
7b155f4
08e75a2
c10467e
dd85825
a6e88f6
1643715
f86567e
658ff84
d9e0531
157f8e8
76411a4
4d956f2
7d348a0
4588b50
bf60a78
5d2ecf9
7581767
d15063c
65ad779
67e1eb7
f9ff470
6df8c3c
1081aa8
e4aaa27
2d062f3
d70a7f2
c2988ea
d1772e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,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 | ||
|
|
||
|
|
@@ -1635,6 +1636,127 @@ PHP_FUNCTION(stream_supports_lock) | |
| RETURN_TRUE; | ||
| } | ||
|
|
||
| /* {{{ proto proto stream_vt100_support(resource stream[, bool enable]) | ||
| Get or set VT100 support for the specified stream. | ||
| */ | ||
| PHP_FUNCTION(stream_vt100_support) | ||
| { | ||
| zval *z_stream; | ||
| php_stream *stream; | ||
| int fileno; | ||
| zend_bool enable; | ||
| #ifdef PHP_WIN32 | ||
| DWORD handle_id; | ||
| #endif | ||
| int argc = ZEND_NUM_ARGS(); | ||
|
|
||
| if (zend_parse_parameters(argc, "z|b", &z_stream, &enable) == FAILURE) { | ||
| return; | ||
| } | ||
| stream = NULL; | ||
| switch (Z_TYPE_P(z_stream)) { | ||
| case IS_RESOURCE: | ||
| php_stream_from_zval_no_verify(stream, z_stream); | ||
| break; | ||
| } | ||
| if (stream == NULL) { | ||
| RETURN_FALSE; | ||
| } | ||
| 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); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The void* cast will cause the stack corruption on 64-bit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Fixed in 694e207 |
||
| } 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; | ||
| } | ||
| switch (fileno) { | ||
| case STDOUT_FILENO: | ||
| #ifdef PHP_WIN32 | ||
| handle_id = STD_OUTPUT_HANDLE; | ||
| #endif | ||
| break; | ||
| case STDERR_FILENO: | ||
| #ifdef PHP_WIN32 | ||
| handle_id = STD_ERROR_HANDLE; | ||
| #endif | ||
| break; | ||
| default: | ||
| RETURN_FALSE; | ||
| } | ||
|
|
||
|
|
||
| if (argc == 1) { | ||
| /* Check if the specified stream supports VT100 control codes */ | ||
| #ifdef PHP_WIN32 | ||
| /* Check if the current Windows version supports VT100 control codes */ | ||
| if (!php_win32_console_os_supports_vt100()) { | ||
| RETURN_FALSE; | ||
| } | ||
| /* Check if the Windows standard handle is redirected to file */ | ||
| if (php_win32_console_handle_is_redirected(handle_id)) { | ||
| RETURN_FALSE; | ||
| } | ||
| /* Check if the Windows standard handle has VT100 control codes enabled */ | ||
| if (php_win32_console_handle_has_vt100(handle_id)) { | ||
| RETURN_TRUE; | ||
| } | ||
| else { | ||
| RETURN_FALSE; | ||
| } | ||
| #elif HAVE_POSIX | ||
| /* Check if the file descriptor identifier is a terminal */ | ||
| if (isatty(fileno)) { | ||
| RETURN_TRUE; | ||
| } | ||
| else { | ||
| RETURN_FALSE; | ||
| } | ||
| #else | ||
| RETURN_FALSE; | ||
| #endif | ||
| } | ||
| else { | ||
| /* Enable/disable VT100 control codes support for the specified stream */ | ||
| #ifdef PHP_WIN32 | ||
| /* Check if the current Windows version supports VT100 control codes */ | ||
| if (!php_win32_console_os_supports_vt100()) { | ||
| RETURN_FALSE; | ||
| } | ||
| /* Check if the Windows standard handle is redirected to file */ | ||
| if (php_win32_console_handle_is_redirected(handle_id)) { | ||
| RETURN_FALSE; | ||
| } | ||
| /* Enable/disable VT100 control codes support for the specified Windows standard handle */ | ||
| if (php_win32_console_handle_set_vt100(handle_id, enable ? TRUE : FALSE)) { | ||
| RETURN_TRUE; | ||
| } | ||
| else { | ||
| RETURN_FALSE; | ||
| } | ||
| #elif HAVE_POSIX | ||
| /* Check if the file descriptor identifier is a terminal */ | ||
| if (isatty(fileno)) { | ||
| if (enable) { | ||
| RETURN_TRUE; | ||
| } | ||
| else { | ||
| RETURN_FALSE; | ||
| } | ||
| } | ||
| else { | ||
| if (enable) { | ||
| RETURN_FALSE; | ||
| } | ||
| else { | ||
| 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 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1062,7 +1062,7 @@ function error_report($testname, $logname, $tested) | |
| } | ||
| } | ||
|
|
||
| function system_with_timeout($commandline, $env = null, $stdin = null) | ||
| function system_with_timeout($commandline, $env = null, $stdin = null, $captureStdOut = true, $captureStdErr = true) | ||
|
||
| { | ||
| global $leak_check, $cwd; | ||
|
|
||
|
|
@@ -1073,11 +1073,16 @@ function system_with_timeout($commandline, $env = null, $stdin = null) | |
| $bin_env[$key] = $value; | ||
| } | ||
|
|
||
| $proc = proc_open($commandline, array( | ||
| $descriptorspec = array( | ||
| 0 => array('pipe', 'r'), | ||
| 1 => array('pipe', 'w'), | ||
| 2 => array('pipe', 'w') | ||
| ), $pipes, $cwd, $bin_env, array('suppress_errors' => true, 'binary_pipes' => true)); | ||
| ); | ||
| if ($captureStdOut) { | ||
| $descriptorspec[1] = array('pipe', 'w'); | ||
| } | ||
| if ($captureStdErr) { | ||
| $descriptorspec[2] = array('pipe', 'w'); | ||
| } | ||
| $proc = proc_open($commandline, $descriptorspec, $pipes, $cwd, $bin_env, array('suppress_errors' => true, 'binary_pipes' => true)); | ||
|
|
||
| if (!$proc) { | ||
| return false; | ||
|
|
@@ -1107,7 +1112,13 @@ function system_with_timeout($commandline, $env = null, $stdin = null) | |
| proc_terminate($proc, 9); | ||
| return $data; | ||
| } else if ($n > 0) { | ||
| $line = fread($pipes[1], 8192); | ||
| if ($captureStdOut) { | ||
| $line = fread($pipes[1], 8192); | ||
| } elseif ($captureStdErr) { | ||
| $line = fread($pipes[2], 8192); | ||
| } else { | ||
| $line = ''; | ||
| } | ||
| if (strlen($line) == 0) { | ||
| /* EOF */ | ||
| break; | ||
|
|
@@ -1338,6 +1349,19 @@ function run_test($php, $file, $env) | |
| return 'BORKED'; | ||
| } | ||
|
|
||
| if (isset($section_text['CAPTURE_STDIO'])) { | ||
| $captureStdOut = stripos($section_text['CAPTURE_STDIO'], 'STDOUT') !== false; | ||
| $captureStdErr = stripos($section_text['CAPTURE_STDIO'], 'STDERR') !== false; | ||
| } else { | ||
| $captureStdOut = true; | ||
| $captureStdErr = true; | ||
| } | ||
| if ($captureStdOut && $captureStdErr) { | ||
| $cmdRedirect = ' 2>&1'; | ||
| } else { | ||
| $cmdRedirect = ''; | ||
| } | ||
|
|
||
| $tested = trim($section_text['TEST']); | ||
|
|
||
| /* For GET/POST/PUT tests, check if cgi sapi is available and if it is, use it. */ | ||
|
|
@@ -1750,7 +1774,7 @@ function run_test($php, $file, $env) | |
| } | ||
|
|
||
| save_text($tmp_post, $request); | ||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; | ||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\""; | ||
|
|
||
| } elseif (array_key_exists('PUT', $section_text) && !empty($section_text['PUT'])) { | ||
|
|
||
|
|
@@ -1784,7 +1808,7 @@ function run_test($php, $file, $env) | |
| } | ||
|
|
||
| save_text($tmp_post, $request); | ||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; | ||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\""; | ||
|
|
||
| } else if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { | ||
|
|
||
|
|
@@ -1801,7 +1825,7 @@ function run_test($php, $file, $env) | |
| $env['CONTENT_LENGTH'] = $content_length; | ||
| } | ||
|
|
||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; | ||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\""; | ||
|
|
||
| } else if (array_key_exists('GZIP_POST', $section_text) && !empty($section_text['GZIP_POST'])) { | ||
|
|
||
|
|
@@ -1816,7 +1840,7 @@ function run_test($php, $file, $env) | |
| $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; | ||
| $env['CONTENT_LENGTH'] = $content_length; | ||
|
|
||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; | ||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\""; | ||
|
|
||
| } else if (array_key_exists('DEFLATE_POST', $section_text) && !empty($section_text['DEFLATE_POST'])) { | ||
| $post = trim($section_text['DEFLATE_POST']); | ||
|
|
@@ -1829,15 +1853,15 @@ function run_test($php, $file, $env) | |
| $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; | ||
| $env['CONTENT_LENGTH'] = $content_length; | ||
|
|
||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; | ||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\"$cmdRedirect < \"$tmp_post\""; | ||
|
|
||
| } else { | ||
|
|
||
| $env['REQUEST_METHOD'] = 'GET'; | ||
| $env['CONTENT_TYPE'] = ''; | ||
| $env['CONTENT_LENGTH'] = ''; | ||
|
|
||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\" $args 2>&1"; | ||
| $cmd = "$php $pass_options $ini_settings -f \"$test_file\" $args$cmdRedirect"; | ||
| } | ||
|
|
||
| if ($leak_check) { | ||
|
|
@@ -1873,7 +1897,7 @@ function run_test($php, $file, $env) | |
|
|
||
| junit_start_timer($shortname); | ||
|
|
||
| $out = system_with_timeout($cmd, $env, isset($section_text['STDIN']) ? $section_text['STDIN'] : null); | ||
| $out = system_with_timeout($cmd, $env, isset($section_text['STDIN']) ? $section_text['STDIN'] : null, $captureStdOut, $captureStdErr); | ||
|
|
||
| junit_finish_timer($shortname); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| --TEST-- | ||
| Test stream_vt100_support on POSIX with redirected STDERR | ||
| --SKIPIF-- | ||
| <?php | ||
| if (!function_exists('posix_isatty')) { | ||
| echo "skip Only for POSIX systems"; | ||
| } | ||
| ?> | ||
| --CAPTURE_STDIO-- | ||
| STDERR | ||
| --FILE-- | ||
| <?php | ||
| ob_start(); | ||
| var_dump(stream_vt100_support(STDOUT)); | ||
| var_dump(stream_vt100_support(STDERR)); | ||
| $content = ob_get_clean(); | ||
| fwrite(STDERR, $content); | ||
| ?> | ||
| --EXPECT-- | ||
| bool(true) | ||
| bool(false) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| --TEST-- | ||
| Test stream_vt100_support on POSIX with redirected STDOUT | ||
| --SKIPIF-- | ||
| <?php | ||
| if (!function_exists('posix_isatty')) { | ||
| echo "skip Only for POSIX systems"; | ||
| } | ||
| ?> | ||
| --CAPTURE_STDIO-- | ||
| STDOUT | ||
| --FILE-- | ||
| <?php | ||
| var_dump(stream_vt100_support(STDOUT)); | ||
| var_dump(stream_vt100_support(STDERR)); | ||
| ?> | ||
| --EXPECT-- | ||
| bool(false) | ||
| bool(true) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| --TEST-- | ||
| Test stream_vt100_support on newer Windows versions with redirected STDIO/STDERR | ||
| --SKIPIF-- | ||
| <?php | ||
| if (stripos(PHP_OS, 'WIN') !== 0) { | ||
| echo "skip Only for Windows systems"; | ||
| } elseif (version_compare( | ||
| PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD, | ||
| '10.0.10586' | ||
| ) < 0) { | ||
| echo "skip Only for Windows systems >= 10.0.10586"; | ||
| } | ||
| ?> | ||
| --CAPTURE_STDIO-- | ||
| STDOUT, STDERR | ||
| --FILE-- | ||
| <?php | ||
| var_dump(stream_vt100_support(STDOUT, true)); | ||
| var_dump(stream_vt100_support(STDERR, true)); | ||
| stream_vt100_support(STDOUT, false); | ||
| stream_vt100_support(STDERR, false); | ||
| ?> | ||
| --EXPECT-- | ||
| bool(false) | ||
| bool(false) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| --TEST-- | ||
| Test stream_vt100_support for STDERR on newer Windows versions | ||
| --SKIPIF-- | ||
| <?php | ||
| if (stripos(PHP_OS, 'WIN') !== 0) { | ||
| echo "skip Only for Windows systems"; | ||
| } elseif (version_compare( | ||
| PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD, | ||
| '10.0.10586' | ||
| ) < 0) { | ||
| echo "skip Only for Windows systems >= 10.0.10586"; | ||
| } | ||
| ?> | ||
| --CAPTURE_STDIO-- | ||
| STDOUT | ||
| --FILE-- | ||
| <?php | ||
| var_dump(stream_vt100_support(STDERR, true)); | ||
| var_dump(stream_vt100_support(STDERR)); | ||
| var_dump(stream_vt100_support(STDERR, false)); | ||
| var_dump(stream_vt100_support(STDERR)); | ||
| ?> | ||
| --EXPECT-- | ||
| bool(true) | ||
| bool(true) | ||
| bool(true) | ||
| bool(false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You only use this in the call to
zend_parse_parametersnowThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 1081aa8