Skip to content

Commit ae7ae40

Browse files
committed
436: rm the existing extension before cp the new one
It seems that directly copying the new .so over the old one is slightly different to rm the old .so then copying the new one. This fixes a segfault that was observed when an existing ext was already in the ext directory. This didn't manifest before, because `make install` (the approach used by compiling from source) uses basically: $extSrcPath/build/shtool --debug install -c {$extSrcPath}modules/* $dest This is a shell script, and ultimately it boils down to: - cp (or mv) the .so to a temp file in the dest path - rm the dest file - mv the temp file to the dest file It was observed that this approach did not cause the segfault, but previous to this commit, PIE was only doing: - cp the .so to the dest file It seems there is some much lower-level differences in how these operations affect the running processes, so this commit changes PIE to `rm` the target file if it already exists first, which seems to solve the issue.
1 parent 531433d commit ae7ae40

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

src/Installing/UnixInstall.php

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
use RuntimeException;
1515
use Webmozart\Assert\Assert;
1616

17-
use function array_unshift;
17+
use function array_map;
18+
use function array_merge;
1819
use function file_exists;
1920
use function implode;
2021
use function is_writable;
@@ -45,18 +46,29 @@ public function __invoke(
4546
$sharedObjectName,
4647
);
4748

49+
$installCommands = [];
4850
switch (DownloadUrlMethod::fromDownloadedPackage($downloadedPackage)) {
4951
case DownloadUrlMethod::PrePackagedBinary:
5052
Assert::notNull($builtBinaryFile);
51-
$installCommand = [
53+
54+
if (file_exists($expectedSharedObjectLocation)) {
55+
$installCommands[] = [
56+
'rm',
57+
'-v',
58+
$expectedSharedObjectLocation,
59+
];
60+
}
61+
62+
$installCommands[] = [
5263
'cp',
64+
'-v',
5365
$builtBinaryFile->filePath,
5466
$targetExtensionPath,
5567
];
5668
break;
5769

5870
default:
59-
$installCommand = ['make', 'install'];
71+
$installCommands[] = ['make', 'install'];
6072
}
6173

6274
// If the target directory isn't writable, or a .so file already exists and isn't writable, try to use sudo
@@ -71,18 +83,20 @@ public function __invoke(
7183
'<comment>Cannot write to %s, so using sudo to elevate privileges.</comment>',
7284
$targetExtensionPath,
7385
));
74-
array_unshift($installCommand, Sudo::find());
86+
$installCommands = array_map(static fn (array $command) => array_merge(['sudo'], $command), $installCommands);
7587
}
7688

77-
$io->write(sprintf('<info>Install command is: %s</info>', implode(' ', $installCommand)), verbosity: IOInterface::VERY_VERBOSE);
89+
$io->write(sprintf('<info>Install commands are: %s</info>', implode(', ', array_map(static fn (array $command) => implode(' ', $command), $installCommands))), verbosity: IOInterface::VERY_VERBOSE);
7890

79-
$makeInstallOutput = Process::run(
80-
$installCommand,
81-
$downloadedPackage->extractedSourcePath,
82-
self::MAKE_INSTALL_TIMEOUT_SECS,
83-
);
91+
foreach ($installCommands as $installCommand) {
92+
$makeInstallOutput = Process::run(
93+
$installCommand,
94+
$downloadedPackage->extractedSourcePath,
95+
self::MAKE_INSTALL_TIMEOUT_SECS,
96+
);
8497

85-
$io->write($makeInstallOutput, verbosity: IOInterface::VERY_VERBOSE);
98+
$io->write($makeInstallOutput, verbosity: IOInterface::VERY_VERBOSE);
99+
}
86100

87101
if (! file_exists($expectedSharedObjectLocation)) {
88102
throw new RuntimeException('Install failed, ' . $expectedSharedObjectLocation . ' was not installed.');

0 commit comments

Comments
 (0)