Skip to content

Commit c2d0fd6

Browse files
[Filesystem] Fix usages of error_get_last()
1 parent 4026b9e commit c2d0fd6

File tree

1 file changed

+42
-22
lines changed

1 file changed

+42
-22
lines changed

Filesystem.php

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
*/
2222
class Filesystem
2323
{
24+
private static $lastError;
25+
2426
/**
2527
* Copies a file.
2628
*
@@ -95,12 +97,11 @@ public function mkdir($dirs, $mode = 0777)
9597
continue;
9698
}
9799

98-
if (true !== @mkdir($dir, $mode, true)) {
99-
$error = error_get_last();
100+
if (!self::box('mkdir', $dir, $mode, true)) {
100101
if (!is_dir($dir)) {
101102
// The directory was not created by a concurrent process. Let's throw an exception with a developer friendly error message if we have one
102-
if ($error) {
103-
throw new IOException(sprintf('Failed to create "%s": %s.', $dir, $error['message']), 0, null, $dir);
103+
if (self::$lastError) {
104+
throw new IOException(sprintf('Failed to create "%s": %s.', $dir, self::$lastError), 0, null, $dir);
104105
}
105106
throw new IOException(sprintf('Failed to create "%s"', $dir), 0, null, $dir);
106107
}
@@ -169,20 +170,17 @@ public function remove($files)
169170
foreach ($files as $file) {
170171
if (is_link($file)) {
171172
// See https://bugs.php.net/52176
172-
if (!@(unlink($file) || '\\' !== DIRECTORY_SEPARATOR || rmdir($file)) && file_exists($file)) {
173-
$error = error_get_last();
174-
throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, $error['message']));
173+
if (!(self::box('unlink', $file) || '\\' !== DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) {
174+
throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, self::$lastError));
175175
}
176176
} elseif (is_dir($file)) {
177177
$this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS));
178178

179-
if (!@rmdir($file) && file_exists($file)) {
180-
$error = error_get_last();
181-
throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, $error['message']));
179+
if (!self::box('rmdir', $file) && file_exists($file)) {
180+
throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, self::$lastError));
182181
}
183-
} elseif (!@unlink($file) && file_exists($file)) {
184-
$error = error_get_last();
185-
throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, $error['message']));
182+
} elseif (!self::box('unlink', $file) && file_exists($file)) {
183+
throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, self::$lastError));
186184
}
187185
}
188186
}
@@ -336,19 +334,16 @@ public function symlink($originDir, $targetDir, $copyOnWindows = false)
336334

337335
$this->mkdir(dirname($targetDir));
338336

339-
$ok = false;
340337
if (is_link($targetDir)) {
341-
if (readlink($targetDir) != $originDir) {
342-
$this->remove($targetDir);
343-
} else {
344-
$ok = true;
338+
if (readlink($targetDir) === $originDir) {
339+
return;
345340
}
341+
$this->remove($targetDir);
346342
}
347343

348-
if (!$ok && true !== @symlink($originDir, $targetDir)) {
349-
$report = error_get_last();
350-
if (is_array($report)) {
351-
if ('\\' === DIRECTORY_SEPARATOR && false !== strpos($report['message'], 'error code(1314)')) {
344+
if (!self::box('symlink', $originDir, $targetDir)) {
345+
if (null !== self::$lastError) {
346+
if ('\\' === DIRECTORY_SEPARATOR && false !== strpos(self::$lastError, 'error code(1314)')) {
352347
throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', 0, null, $targetDir);
353348
}
354349
}
@@ -580,4 +575,29 @@ private function toIterator($files)
580575

581576
return $files;
582577
}
578+
579+
private static function box($func)
580+
{
581+
self::$lastError = null;
582+
\set_error_handler(__CLASS__.'::handleError');
583+
try {
584+
$result = \call_user_func_array($func, \array_slice(\func_get_args(), 1));
585+
\restore_error_handler();
586+
587+
return $result;
588+
} catch (\Throwable $e) {
589+
} catch (\Exception $e) {
590+
}
591+
\restore_error_handler();
592+
593+
throw $e;
594+
}
595+
596+
/**
597+
* @internal
598+
*/
599+
public static function handleError($type, $msg)
600+
{
601+
self::$lastError = $msg;
602+
}
583603
}

0 commit comments

Comments
 (0)