From ceecb502f8c8be4d10f4afe96dc24debe221b907 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 30 Nov 2014 11:30:45 +0100 Subject: [PATCH] [Filesystem] fix lock file permissions --- .../Component/Filesystem/LockHandler.php | 22 +++++++++++++------ .../Filesystem/Tests/LockHandlerTest.php | 2 +- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Filesystem/LockHandler.php b/src/Symfony/Component/Filesystem/LockHandler.php index a1716db4d03a..59d35ec92883 100644 --- a/src/Symfony/Component/Filesystem/LockHandler.php +++ b/src/Symfony/Component/Filesystem/LockHandler.php @@ -49,9 +49,7 @@ public function __construct($name, $lockPath = null) throw new IOException(sprintf('The directory "%s" is not writable.', $lockPath), 0, null, $lockPath); } - $name = sprintf('%s-%s', preg_replace('/[^a-z0-9\._-]+/i', '-', $name), hash('sha256', $name)); - - $this->file = sprintf('%s/%s', $lockPath, $name); + $this->file = sprintf('%s/sf.%s.%s.lock', $lockPath, preg_replace('/[^a-z0-9\._-]+/i', '-', $name), hash('sha256', $name)); } /** @@ -67,14 +65,24 @@ public function lock($blocking = false) return true; } - // Set an error handler to not trigger the registered error handler if - // the file can not be opened. + // Silence both userland and native PHP error handlers + $errorLevel = error_reporting(0); set_error_handler('var_dump', 0); - $this->handle = @fopen($this->file, 'c'); + + if (!$this->handle = fopen($this->file, 'r')) { + if ($this->handle = fopen($this->file, 'x')) { + chmod($this->file, 0444); + } elseif (!$this->handle = fopen($this->file, 'r')) { + usleep(100); // Give some time for chmod() to complete + $this->handle = fopen($this->file, 'r'); + } + } restore_error_handler(); + error_reporting($errorLevel); if (!$this->handle) { - throw new IOException(sprintf('Unable to fopen "%s".', $this->file), 0, null, $this->file); + $error = error_get_last(); + throw new IOException($error['message'], 0, null, $this->file); } // On Windows, even if PHP doc says the contrary, LOCK_NB works, see diff --git a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php index e4f30a16a978..c2058ffc588b 100644 --- a/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php +++ b/src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php @@ -28,7 +28,7 @@ public function testConstructSanitizeName() { $lock = new LockHandler(''); - $file = sprintf('%s/-php-echo-hello-word--4b3d9d0d27ddef3a78a64685dda3a963e478659a9e5240feaf7b4173a8f28d5f', sys_get_temp_dir()); + $file = sprintf('%s/sf.-php-echo-hello-word-.4b3d9d0d27ddef3a78a64685dda3a963e478659a9e5240feaf7b4173a8f28d5f.lock', sys_get_temp_dir()); // ensure the file does not exist before the lock @unlink($file);