summaryrefslogtreecommitdiff
path: root/ext/standard/streamsfuncs.c
diff options
context:
space:
mode:
authorMichele Locati <michele@locati.it>2016-08-29 11:57:53 +0200
committerAnatol Belski <ab@php.net>2016-10-28 19:23:00 +0200
commit33301d5bae4964f74fd1fc8c4fc485abfde0378e (patch)
treef077a695e30b939114cf3bc541e71a2973045dda /ext/standard/streamsfuncs.c
parent946eb9b452302a258c90752a9a4c81d1824c1a3a (diff)
downloadphp-git-33301d5bae4964f74fd1fc8c4fc485abfde0378e.tar.gz
Add VT100 support for Windows
Fix function names prefix Use Unicode version of GetFinalPathNameByHandle Use EG(windows_version_info) instead of RtlGetVersion Use the specified handle_id instead of STD_OUTPUT_HANDLE Switch from stream name to stream resource Allow running tests capturing only stdout and/or stderr Add tests for stream_vt100_support function Export Win32 console functions Fix x64 build Use zend_long instead of long long, use GetConsole instead of GetFinalPathNameByHandleW to check if a handle is a valid console stream Always use zend_long on any platform Use _get_osfhandle to determine the standard handle Accept stream names Raise warnings in case of invalid stream parameter Return true if disabling VT100 support on a not-console/redirected stream or on old Windows versions Remove php_win32_console_os_supports_vt100 Differentiate stdin vs stdout/stderr Simplify setting flag Allow avoid piping STDIN Let stream_vt100_support accept only resources Fix run-tests Revert console flags in case of failure Simplify logic of stream_vt100_support when setting the flag Return true if succeeded, false otherwise Drop support for STDIN More comprehensive tests for stream_vt100_support Remove old tests Fix name of included file and use absolute paths Enable ENABLE_VIRTUAL_TERMINAL_PROCESSING on Windows by default Remove tests for stream_vt100_support Split stream_vt100_support into stream_isatty+sapi_windows_vt100_support Add tests for stream_isatty Add tests for sapi_windows_vt100_support Return null from stream_isatty is neither Windows nor Posix Fallback to S_ISCHR if neither Windows nor Posix Avoid defining argc since it's only used once Better comment about php_win32_console_fileno_is_console Use events instead of cNumberOfEvents Do not restore previous console mode We need to restore previous console mode on failing SetConsole calls only for STDIN Don't configure STDOUT/STDERR on Windows with PHP_CLI_WIN32_NO_CONSOLE
Diffstat (limited to 'ext/standard/streamsfuncs.c')
-rw-r--r--ext/standard/streamsfuncs.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c
index 01a49e5679..5979c8cccb 100644
--- a/ext/standard/streamsfuncs.c
+++ b/ext/standard/streamsfuncs.c
@@ -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
@@ -1569,6 +1570,119 @@ PHP_FUNCTION(stream_supports_lock)
RETURN_TRUE;
}
+/* {{{ proto proto stream_isatty(resource stream)
+Check if a stream is a TTY.
+*/
+PHP_FUNCTION(stream_isatty)
+{
+ zval *zsrc;
+ php_stream *stream;
+ zend_long fileno;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zsrc) == FAILURE) {
+ 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 */
+ if (php_win32_console_fileno_is_console(fileno)) {
+ 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
+ zend_stat_t stat;
+ if (zend_fstat(fileno, &stat) == 0) {
+ if ((stat.st_mode & /*S_IFMT*/0170000) == /*S_IFCHR*/0020000) {
+ RETURN_TRUE;
+ }
+ }
+ RETURN_NULL();
+#endif
+}
+
+#ifdef PHP_WIN32
+/* {{{ proto proto 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();
+
+ if (zend_parse_parameters(argc, "r|b", &zsrc, &enable) == FAILURE) {
+ 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