diff --git a/NEWS b/NEWS index 922ffd36..9fa5c744 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,4 @@ + - use tmp file for file writes, avoid file lock race (Monte) - handle embedded "$smarty.config.foo.tpl" correctly (Monte) - add $smarty.config.varname variable for accessing config vars (Paul Lockaby, Monte) diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index dc15943b..59cc24b6 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -2041,22 +2041,25 @@ class Smarty */ function _write_file($filename, $contents, $create_dirs = false) { - if ($create_dirs) - $this->_create_dir_structure(dirname($filename)); + $_dirname = dirname($filename); + + if ($create_dirs) { + $this->_create_dir_structure($_dirname); + } - if (!($fd = @fopen($filename, 'w'))) { - $this->trigger_error("problem writing '$filename.'"); + // write to tmp file, then rename it to avoid + // file locking race condition + $_tmp_file = $_dirname . '/' . uniqid(''); + + if (!($fd = @fopen($_tmp_file, 'w'))) { + $this->trigger_error("problem writing temporary file '$_tmp_file'"); return false; } - // flock doesn't seem to work on several windows platforms (98, NT4, NT5, ?), - // so we'll not use it at all in windows. - - if ( strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' || (flock($fd, LOCK_EX)) ) { - fwrite( $fd, $contents ); - fclose($fd); - chmod($filename, $this->_file_perms); - } + fwrite($fd, $contents); + fclose($fd); + rename($_tmp_file, $filename); + chmod($filename, $this->_file_perms); return true; }