Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ed64d73

Browse files
[Filesystem] remove dirs atomically if possible
1 parent 5dbc7db commit ed64d73

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ public function remove($files)
167167
} elseif (!\is_array($files)) {
168168
$files = [$files];
169169
}
170+
171+
self::doRemove($files, false);
172+
}
173+
174+
private static function doRemove(array $files, bool $isRecursive): void
175+
{
170176
$files = array_reverse($files);
171177
foreach ($files as $file) {
172178
if (is_link($file)) {
@@ -175,9 +181,26 @@ public function remove($files)
175181
throw new IOException(sprintf('Failed to remove symlink "%s": ', $file).self::$lastError);
176182
}
177183
} elseif (is_dir($file)) {
178-
$this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS));
184+
if (!$isRecursive) {
185+
$file = realpath($file);
186+
$tmpName = \dirname($file).'/.'.strrev(strtr(base64_encode(random_bytes(2)), '/=', '-.'));
187+
188+
if (file_exists($tmpName)) {
189+
try {
190+
self::doRemove([$tmpName], true);
191+
} catch (IOException $e) {
192+
}
193+
}
194+
195+
if (!file_exists($tmpName) && self::box('rename', $file, $tmpName)) {
196+
$file = $tmpName;
197+
}
198+
}
199+
200+
$files = new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS);
201+
self::doRemove(iterator_to_array($files, true), true);
179202

180-
if (!self::box('rmdir', $file) && file_exists($file)) {
203+
if (!self::box('rmdir', $file) && file_exists($file) && ($isRecursive || $file !== $tmpName)) {
181204
throw new IOException(sprintf('Failed to remove directory "%s": ', $file).self::$lastError);
182205
}
183206
} elseif (!self::box('unlink', $file) && (false !== strpos(self::$lastError, 'Permission denied') || file_exists($file))) {

src/Symfony/Component/HttpKernel/Tests/KernelTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1717
use Symfony\Component\DependencyInjection\ContainerBuilder;
1818
use Symfony\Component\DependencyInjection\ContainerInterface;
19+
use Symfony\Component\Filesystem\Exception\IOException;
1920
use Symfony\Component\Filesystem\Filesystem;
2021
use Symfony\Component\HttpFoundation\Request;
2122
use Symfony\Component\HttpFoundation\Response;
@@ -35,8 +36,10 @@ class KernelTest extends TestCase
3536
{
3637
protected function tearDown(): void
3738
{
38-
$fs = new Filesystem();
39-
$fs->remove(__DIR__.'/Fixtures/var');
39+
try {
40+
(new Filesystem())->remove(__DIR__.'/Fixtures/var');
41+
} catch (IOException $e) {
42+
}
4043
}
4144

4245
public function testConstructor()

0 commit comments

Comments
 (0)