mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fix GH-8952: std streams can not be deliberately closed (#8953)
This commit is contained in:
parent
5e0b2e537d
commit
2dbde18b29
4 changed files with 148 additions and 8 deletions
|
@ -538,14 +538,6 @@ static void cli_register_file_handles(bool no_close) /* {{{ */
|
|||
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
|
||||
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
|
||||
|
||||
/* Release stream resources, but don't free the underlying handles. Othewrise,
|
||||
* extensions which write to stderr or company during mshutdown/gshutdown
|
||||
* won't have the expected functionality.
|
||||
*/
|
||||
if (s_in) s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE;
|
||||
if (s_out) s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
|
||||
if (s_err) s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
|
||||
|
||||
if (s_in==NULL || s_out==NULL || s_err==NULL) {
|
||||
if (s_in) php_stream_close(s_in);
|
||||
if (s_out) php_stream_close(s_out);
|
||||
|
@ -553,6 +545,12 @@ static void cli_register_file_handles(bool no_close) /* {{{ */
|
|||
return;
|
||||
}
|
||||
|
||||
if (no_close) {
|
||||
s_in->flags |= PHP_STREAM_FLAG_NO_CLOSE;
|
||||
s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
|
||||
s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
|
||||
}
|
||||
|
||||
s_in_process = s_in;
|
||||
|
||||
php_stream_to_zval(s_in, &ic.value);
|
||||
|
|
38
sapi/cli/tests/gh8827-001.phpt
Normal file
38
sapi/cli/tests/gh8827-001.phpt
Normal file
|
@ -0,0 +1,38 @@
|
|||
--TEST--
|
||||
std handles can be deliberately closed 001
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (php_sapi_name() != "cli") {
|
||||
die("skip CLI only");
|
||||
}
|
||||
if (PHP_OS_FAMILY == 'Windows') {
|
||||
die("skip not for Windows");
|
||||
}
|
||||
if (PHP_DEBUG) {
|
||||
die("skip std streams are not closeable in debug builds");
|
||||
}
|
||||
if (getenv('SKIP_REPEAT')) {
|
||||
die("skip cannot be repeated");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
print "STDIN:\n";
|
||||
fclose(STDIN);
|
||||
var_dump(@fopen('php://stdin', 'r'));
|
||||
|
||||
print "STDERR:\n";
|
||||
fclose(STDERR);
|
||||
var_dump(@fopen('php://stderr', 'a'));
|
||||
|
||||
print "STDOUT:\n";
|
||||
fclose(STDOUT);
|
||||
// not printed if stdout is closed
|
||||
var_dump(@fopen('php://stdout', 'a'));
|
||||
?>
|
||||
--EXPECT--
|
||||
STDIN:
|
||||
bool(false)
|
||||
STDERR:
|
||||
bool(false)
|
||||
STDOUT:
|
47
sapi/cli/tests/gh8827-002.phpt
Normal file
47
sapi/cli/tests/gh8827-002.phpt
Normal file
|
@ -0,0 +1,47 @@
|
|||
--TEST--
|
||||
std handles can be deliberately closed 002
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (php_sapi_name() != "cli") {
|
||||
die("skip CLI only");
|
||||
}
|
||||
if (PHP_OS_FAMILY == 'Windows') {
|
||||
die("skip not for Windows");
|
||||
}
|
||||
if (PHP_DEBUG) {
|
||||
die("skip std streams are not closeable in debug builds");
|
||||
}
|
||||
if (getenv('SKIP_REPEAT')) {
|
||||
die("skip cannot be repeated");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$stdin = fopen('php://stdin', 'r');
|
||||
$stdout = fopen('php://stdout', 'r');
|
||||
$stderr = fopen('php://stderr', 'r');
|
||||
|
||||
ob_start(function ($buffer) use ($stdout) {
|
||||
fwrite($stdout, $buffer);
|
||||
}, 1);
|
||||
|
||||
print "STDIN:\n";
|
||||
fclose(STDIN);
|
||||
var_dump(@fopen('php://stdin', 'r'));
|
||||
|
||||
print "STDERR:\n";
|
||||
fclose(STDERR);
|
||||
var_dump(@fopen('php://stderr', 'a'));
|
||||
|
||||
print "STDOUT:\n";
|
||||
fclose(STDOUT);
|
||||
var_dump(@fopen('php://stdout', 'a'));
|
||||
?>
|
||||
--EXPECT--
|
||||
STDIN:
|
||||
bool(false)
|
||||
STDERR:
|
||||
bool(false)
|
||||
STDOUT:
|
||||
bool(false)
|
57
sapi/cli/tests/gh8827-003.phpt
Normal file
57
sapi/cli/tests/gh8827-003.phpt
Normal file
|
@ -0,0 +1,57 @@
|
|||
--TEST--
|
||||
std handles can be deliberately closed 003
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (php_sapi_name() != "cli") {
|
||||
die("skip CLI only");
|
||||
}
|
||||
if (PHP_OS_FAMILY == 'Windows') {
|
||||
die("skip not for Windows");
|
||||
}
|
||||
if (PHP_DEBUG) {
|
||||
die("skip std streams are not closeable in debug builds");
|
||||
}
|
||||
if (getenv('SKIP_REPEAT')) {
|
||||
die("skip cannot be repeated");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$stdoutStream = fopen('php://stdout', 'r');
|
||||
|
||||
$stdoutFile = tempnam(sys_get_temp_dir(), 'gh8827');
|
||||
$stderrFile = tempnam(sys_get_temp_dir(), 'gh8827');
|
||||
register_shutdown_function(function () use ($stdoutFile, $stderrFile) {
|
||||
unlink($stdoutFile);
|
||||
unlink($stderrFile);
|
||||
});
|
||||
|
||||
fclose(STDOUT);
|
||||
fclose(STDERR);
|
||||
|
||||
$stdoutFileStream = fopen($stdoutFile, 'a');
|
||||
$stderrFileStream = fopen($stderrFile, 'a');
|
||||
|
||||
print "Goes to stdoutFile\n";
|
||||
file_put_contents('php://fd/1', "Also goes to stdoutFile\n");
|
||||
|
||||
file_put_contents('php://fd/2', "Goes to stderrFile\n");
|
||||
|
||||
ob_start(function ($buffer) use ($stdoutStream) {
|
||||
fwrite($stdoutStream, $buffer);
|
||||
}, 1);
|
||||
|
||||
print "stdoutFile:\n";
|
||||
readfile($stdoutFile);
|
||||
|
||||
print "stderrFile:\n";
|
||||
readfile($stderrFile);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
stdoutFile:
|
||||
Goes to stdoutFile
|
||||
Also goes to stdoutFile
|
||||
stderrFile:
|
||||
Goes to stderrFile
|
Loading…
Add table
Add a link
Reference in a new issue