bug #15058 [Console] Fix STDERR output text on IBM iSeries OS400 (johnkary)

This PR was squashed before being merged into the 2.3 branch (closes #15058).

Discussion
----------

[Console] Fix STDERR output text on IBM iSeries OS400

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | None
| License       | MIT
| Doc PR        | None

Prior to this PR a Symfony Console command would output error text as random symbols when executed via the IBM console program QSH. Affected error text output such as when a required InputArgument is missing, or when explicitly using `$output->getErrorOutput()->writeln('Some error text here')`.

![Example error output](http://i.imgur.com/PQplK1p.png)

This PR fixes error text so it properly prints to IBM console programs such as QSH and QP2SHELL.

I previously fixed STDOUT for PHP running on IBM iSeries OS400 (Zend Server) using the same approach. Since that PR was merged ConsoleOutput class began using its own output for STDERR which exhibits the same issue STDOUT did.

The following commits and previous Symfony PRs have our relevant discussion about ASCII vs EBCDIC character encoding to fix this issue:

* [Original IBM STDOUT reported in #1434](https://github.com/symfony/symfony/issues/1434)
* [My PR #4152 that fixes #1434](https://github.com/symfony/symfony/pull/4152)

Thanks!
🚀

Commits
-------

23c42ca [Console] Fix STDERR output text on IBM iSeries OS400
This commit is contained in:
Fabien Potencier 2015-06-23 19:48:55 +02:00
commit 18716153ee
1 changed files with 29 additions and 10 deletions

View File

@ -30,6 +30,9 @@ use Symfony\Component\Console\Formatter\OutputFormatterInterface;
*/
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
{
/**
* @var StreamOutput
*/
private $stderr;
/**
@ -43,14 +46,12 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
*/
public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
{
$outputStream = 'php://stdout';
if (!$this->hasStdoutSupport()) {
$outputStream = 'php://output';
}
$outputStream = $this->hasStdoutSupport() ? 'php://stdout' : 'php://output';
$errorStream = $this->hasStderrSupport() ? 'php://stderr' : 'php://output';
parent::__construct(fopen($outputStream, 'w'), $verbosity, $decorated, $formatter);
$this->stderr = new StreamOutput(fopen('php://stderr', 'w'), $verbosity, $decorated, $this->getFormatter());
$this->stderr = new StreamOutput(fopen($errorStream, 'w'), $verbosity, $decorated, $this->getFormatter());
}
/**
@ -100,14 +101,32 @@ class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
* Returns true if current environment supports writing console output to
* STDOUT.
*
* IBM iSeries (OS400) exhibits character-encoding issues when writing to
* STDOUT and doesn't properly convert ASCII to EBCDIC, resulting in garbage
* output.
*
* @return bool
*/
protected function hasStdoutSupport()
{
return ('OS400' != php_uname('s'));
return false === $this->isRunningOS400();
}
/**
* Returns true if current environment supports writing console output to
* STDERR.
*
* @return bool
*/
protected function hasStderrSupport()
{
return false === $this->isRunningOS400();
}
/**
* Checks if current executing environment is IBM iSeries (OS400), which
* doesn't properly convert character-encodings between ASCII to EBCDIC.
*
* @return bool
*/
private function isRunningOS400()
{
return 'OS400' === php_uname('s');
}
}