Permalink
Browse files

Remove reliance on proc_open in Filesystem#rename()

  • Loading branch information...
1 parent d26932c commit cd7db1861d8ef59c7a7f76d4e53252a60c46860f @beberlei beberlei committed Nov 19, 2012
Showing with 35 additions and 5 deletions.
  1. +35 −5 src/Composer/Util/Filesystem.php
@@ -86,14 +86,10 @@ public function removeDirectory($directory)
*/
public function removeDirectoryPhp($directory)
{
- $it = new RecursiveDirectoryIterator($directory);
+ $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($ri as $file) {
- if ($file->getFilename() == "." || $file->getFilename() == "..") {
- continue;
- }
-
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
@@ -120,13 +116,47 @@ public function ensureDirectoryExists($directory)
}
}
+ /**
+ * Copy then delete is a non-atomic version of {@link rename}.
+ *
+ * Some systems can't rename and also dont have proc_open,
+ * which requires this solution.
+ *
+ * @param string $source
+ * @param string $target
+ */
+ public function copyThenRemove($source, $target)
+ {
+ $it = new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS);
+ $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST);
+
+ if ( !file_exists($target)) {
+ mkdir($target, 0777, true);
+ }
+
+ foreach ($ri as $file) {
+ $targetPath = $target . DIRECTORY_SEPARATOR . $ri->getSubPathName();
+ if ($file->isDir()) {
+ mkdir($targetPath);
+ } else {
+ copy($file->getPathname(), $targetPath);
+ }
+ }
+
+ $this->removeDirectoryPhp($source);
+ }
+
public function rename($source, $target)
{
if (true === @rename($source, $target)) {
return;
}
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
+ if (!function_exists('proc_open')) {
+ return $this->copyThenRemove($source, $target);
+ }
+
// Try to copy & delete - this is a workaround for random "Access denied" errors.
$command = sprintf('xcopy %s %s /E /I /Q', escapeshellarg($source), escapeshellarg($target));
if (0 === $this->processExecutor->execute($command)) {

0 comments on commit cd7db18

Please sign in to comment.