@@ -610,10 +610,8 @@ private function hasColorSupport($stream): bool
610
610
return false ;
611
611
}
612
612
613
- // Detect msysgit/mingw and assume this is a tty because detection
614
- // does not work correctly, see https://github.com/composer/composer/issues/9690
615
- if (!@stream_isatty ($ stream ) && !\in_array (strtoupper ((string ) getenv ('MSYSTEM ' )), ['MINGW32 ' , 'MINGW64 ' ], true )) {
616
- return true ;
613
+ if (!self ::isTty ()) {
614
+ return false ;
617
615
}
618
616
619
617
if ('\\' === \DIRECTORY_SEPARATOR && @sapi_windows_vt100_support ($ stream )) {
@@ -636,6 +634,36 @@ private function hasColorSupport($stream): bool
636
634
return preg_match ('/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/ ' , $ term );
637
635
}
638
636
637
+ /**
638
+ * Checks if the stream is a TTY, i.e; whether the output stream is connected to a terminal.
639
+ *
640
+ * Reference: Composer\Util\Platform::isTty
641
+ * https://github.com/composer/composer
642
+ */
643
+ private static function isTty (): bool
644
+ {
645
+ // Detect msysgit/mingw and assume this is a tty because detection
646
+ // does not work correctly, see https://github.com/composer/composer/issues/9690
647
+ if (\in_array (strtoupper ((string ) getenv ('MSYSTEM ' )), ['MINGW32 ' , 'MINGW64 ' ], true )) {
648
+ return true ;
649
+ }
650
+
651
+ // Modern cross-platform function, includes the fstat fallback so if it is present we trust it
652
+ if (\function_exists ('stream_isatty ' )) {
653
+ return @stream_isatty (\STDOUT );
654
+ }
655
+
656
+ // Only trusting this if it is positive, otherwise prefer fstat fallback.
657
+ if (\function_exists ('posix_isatty ' ) && @posix_isatty (\STDOUT )) {
658
+ return true ;
659
+ }
660
+
661
+ $ stat = @fstat (\STDOUT );
662
+
663
+ // Check if formatted mode is S_IFCHR
664
+ return $ stat ? 0020000 === ($ stat ['mode ' ] & 0170000 ) : false ;
665
+ }
666
+
639
667
/**
640
668
* Returns true if the Windows terminal supports true color.
641
669
*
0 commit comments