mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-04-30 15:52:17 +09:00
Use atomic rename to safely overwrite frequently accessed files
This commit is contained in:
parent
1c55d8b411
commit
30106b7fc4
1 changed files with 52 additions and 1 deletions
|
|
@ -7,6 +7,11 @@ namespace Rhymix\Framework;
|
|||
*/
|
||||
class Storage
|
||||
{
|
||||
/**
|
||||
* Use atomic rename to overwrite files.
|
||||
*/
|
||||
public static $safe_overwrite = true;
|
||||
|
||||
/**
|
||||
* Check if a path really exists.
|
||||
*
|
||||
|
|
@ -217,12 +222,18 @@ class Storage
|
|||
if (!self::exists($destination_dir))
|
||||
{
|
||||
$mkdir_success = self::createDirectory($destination_dir);
|
||||
if (!$mkdir_success)
|
||||
if (!$mkdir_success && !self::exists($destination_dir))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$safe_overwrite && strncasecmp($mode, 'a', 1))
|
||||
{
|
||||
$original_filename = $filename;
|
||||
$filename = $filename . '.tmp.' . microtime(true);
|
||||
}
|
||||
|
||||
if ($fp = fopen($filename, $mode))
|
||||
{
|
||||
flock($fp, \LOCK_EX);
|
||||
|
|
@ -243,6 +254,23 @@ class Storage
|
|||
return false;
|
||||
}
|
||||
|
||||
if (self::$safe_overwrite && strncasecmp($mode, 'a', 1))
|
||||
{
|
||||
$rename_success = @rename($filename, $original_filename);
|
||||
if (!$rename_success)
|
||||
{
|
||||
@unlink($original_filename);
|
||||
$rename_success = @rename($filename, $original_filename);
|
||||
if (!$rename_success)
|
||||
{
|
||||
@unlink($filename);
|
||||
throw new Exception('foo');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$filename = $original_filename;
|
||||
}
|
||||
|
||||
@chmod($filename, ($perms === null ? (0666 & ~umask()) : $perms));
|
||||
if (function_exists('opcache_invalidate') && substr($filename, -4) === '.php')
|
||||
{
|
||||
|
|
@ -301,12 +329,35 @@ class Storage
|
|||
$destination = $destination . '/' . basename($source);
|
||||
}
|
||||
|
||||
if (self::$safe_overwrite)
|
||||
{
|
||||
$original_destination = $destination;
|
||||
$destination = $destination . '.tmp.' . microtime(true);
|
||||
}
|
||||
|
||||
$copy_success = @copy($source, $destination);
|
||||
if (!$copy_success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (self::$safe_overwrite)
|
||||
{
|
||||
$rename_success = @rename($destination, $original_destination);
|
||||
if (!$rename_success)
|
||||
{
|
||||
@unlink($original_destination);
|
||||
$rename_success = @rename($destination, $original_destination);
|
||||
if (!$rename_success)
|
||||
{
|
||||
@unlink($destination);
|
||||
throw new Exception('foo');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$destination = $original_destination;
|
||||
}
|
||||
|
||||
if ($destination_perms === null)
|
||||
{
|
||||
if (is_uploaded_file($source))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue