Skip to content

Commit d4fd4a8

Browse files
committed
Merge branch '5.4' into 6.4
* 5.4: 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 Review portuguese translations [Validator] Fix fields without constraints in `Collection` deal with fields for which no constraints have been configured
2 parents 31642b0 + 7e2c857 commit d4fd4a8

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

Process.php

+14
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class Process implements \IteratorAggregate
8080
private WindowsPipes|UnixPipes $processPipes;
8181

8282
private ?int $latestSignal = null;
83+
private ?int $cachedExitCode = null;
8384

8485
private static ?bool $sigchild = null;
8586

@@ -1291,6 +1292,19 @@ protected function updateStatus(bool $blocking)
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

+54
Original file line numberDiff line numberDiff line change
@@ -1553,6 +1553,60 @@ public function testEnvCaseInsensitiveOnWindows()
15531553
}
15541554
}
15551555

1556+
public function testMultipleCallsToProcGetStatus()
1557+
{
1558+
$process = $this->getProcess('echo foo');
1559+
$process->start(static function () use ($process) {
1560+
return $process->isRunning();
1561+
});
1562+
while ($process->isRunning()) {
1563+
usleep(1000);
1564+
}
1565+
$this->assertSame(0, $process->getExitCode());
1566+
}
1567+
1568+
public function testFailingProcessWithMultipleCallsToProcGetStatus()
1569+
{
1570+
$process = $this->getProcess('exit 123');
1571+
$process->start(static function () use ($process) {
1572+
return $process->isRunning();
1573+
});
1574+
while ($process->isRunning()) {
1575+
usleep(1000);
1576+
}
1577+
$this->assertSame(123, $process->getExitCode());
1578+
}
1579+
1580+
/**
1581+
* @group slow
1582+
*/
1583+
public function testLongRunningProcessWithMultipleCallsToProcGetStatus()
1584+
{
1585+
$process = $this->getProcess('php -r "sleep(1); echo \'done\';"');
1586+
$process->start(static function () use ($process) {
1587+
return $process->isRunning();
1588+
});
1589+
while ($process->isRunning()) {
1590+
usleep(1000);
1591+
}
1592+
$this->assertSame(0, $process->getExitCode());
1593+
}
1594+
1595+
/**
1596+
* @group slow
1597+
*/
1598+
public function testLongRunningProcessWithMultipleCallsToProcGetStatusError()
1599+
{
1600+
$process = $this->getProcess('php -r "sleep(1); echo \'failure\'; exit(123);"');
1601+
$process->start(static function () use ($process) {
1602+
return $process->isRunning();
1603+
});
1604+
while ($process->isRunning()) {
1605+
usleep(1000);
1606+
}
1607+
$this->assertSame(123, $process->getExitCode());
1608+
}
1609+
15561610
/**
15571611
* @group transient-on-windows
15581612
*/

0 commit comments

Comments
 (0)