Skip to content

Commit 1c0721a

Browse files
committed
Merge branch '7.0' into 7.1
* 7.0: [VarExporter] Uniform unitialized property error message under ghost and non-ghost objects [AssetMapper] Ignore comment lines in JavaScriptImportPathCompiler Update configuration path in help message [Validator] Review Albanian translation [Process] Fix Inconsistent Exit Status in proc_get_status for PHP Versions Below 8.3 [Validator] Update Czech (cz) translation Sync translations [Mailer][Postmark][Webhook] Make allowed IPs configurable Review portuguese translations [Validator] Fix fields without constraints in `Collection` deal with fields for which no constraints have been configured [DomCrawler] [Form] Fix the exclusion of <template>
2 parents bf2a95a + 8d6be7c commit 1c0721a

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

Process.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class Process implements \IteratorAggregate
8181
private WindowsPipes|UnixPipes $processPipes;
8282

8383
private ?int $latestSignal = null;
84+
private ?int $cachedExitCode = null;
8485

8586
private static ?bool $sigchild = null;
8687

@@ -1291,6 +1292,19 @@ protected function updateStatus(bool $blocking): void
12911292
$this->processInformation = proc_get_status($this->process);
12921293
$running = $this->processInformation['running'];
12931294

1295+
// In PHP < 8.3, "proc_get_status" only returns the correct exit status on the first call.
1296+
// Subsequent calls return -1 as the process is discarded. This workaround caches the first
1297+
// retrieved exit status for consistent results in later calls, mimicking PHP 8.3 behavior.
1298+
if (\PHP_VERSION_ID < 80300) {
1299+
if (!isset($this->cachedExitCode) && !$running && -1 !== $this->processInformation['exitcode']) {
1300+
$this->cachedExitCode = $this->processInformation['exitcode'];
1301+
}
1302+
1303+
if (isset($this->cachedExitCode) && !$running && -1 === $this->processInformation['exitcode']) {
1304+
$this->processInformation['exitcode'] = $this->cachedExitCode;
1305+
}
1306+
}
1307+
12941308
$this->readPipes($running && $blocking, '\\' !== \DIRECTORY_SEPARATOR || !$running);
12951309

12961310
if ($this->fallbackStatus && $this->isSigchildEnabled()) {

Tests/ProcessTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,60 @@ public function testEnvCaseInsensitiveOnWindows()
15961596
}
15971597
}
15981598

1599+
public function testMultipleCallsToProcGetStatus()
1600+
{
1601+
$process = $this->getProcess('echo foo');
1602+
$process->start(static function () use ($process) {
1603+
return $process->isRunning();
1604+
});
1605+
while ($process->isRunning()) {
1606+
usleep(1000);
1607+
}
1608+
$this->assertSame(0, $process->getExitCode());
1609+
}
1610+
1611+
public function testFailingProcessWithMultipleCallsToProcGetStatus()
1612+
{
1613+
$process = $this->getProcess('exit 123');
1614+
$process->start(static function () use ($process) {
1615+
return $process->isRunning();
1616+
});
1617+
while ($process->isRunning()) {
1618+
usleep(1000);
1619+
}
1620+
$this->assertSame(123, $process->getExitCode());
1621+
}
1622+
1623+
/**
1624+
* @group slow
1625+
*/
1626+
public function testLongRunningProcessWithMultipleCallsToProcGetStatus()
1627+
{
1628+
$process = $this->getProcess('php -r "sleep(1); echo \'done\';"');
1629+
$process->start(static function () use ($process) {
1630+
return $process->isRunning();
1631+
});
1632+
while ($process->isRunning()) {
1633+
usleep(1000);
1634+
}
1635+
$this->assertSame(0, $process->getExitCode());
1636+
}
1637+
1638+
/**
1639+
* @group slow
1640+
*/
1641+
public function testLongRunningProcessWithMultipleCallsToProcGetStatusError()
1642+
{
1643+
$process = $this->getProcess('php -r "sleep(1); echo \'failure\'; exit(123);"');
1644+
$process->start(static function () use ($process) {
1645+
return $process->isRunning();
1646+
});
1647+
while ($process->isRunning()) {
1648+
usleep(1000);
1649+
}
1650+
$this->assertSame(123, $process->getExitCode());
1651+
}
1652+
15991653
/**
16001654
* @group transient-on-windows
16011655
*/

0 commit comments

Comments
 (0)