影響範囲を調べきれていませんが、get_source等でflock処理がされていません。flockでLOCK_EXを行なってもflockを使っていない処理のファイルアクセスはブロックできないので、file_write側だけでロックしても十分な効果は得られません。
function fopen_w_lock($filename, $mode, $use_include_path = FALSE) { $mode = str_replace('b', '', $mode); $fp = @fopen($filename, 'a+b', $use_include_path); if($fp !== FALSE){ switch($mode){ case 'r': flock($fp, LOCK_SH); rewind($fp); break; case 'r+': flock($fp, LOCK_EX); rewind($fp); break; case 'w': case 'w+': flock($fp, LOCK_EX); ftruncate($fp, 0); break; case 'a': case 'a+': flock($fp, LOCK_EX); fseek($fp, SEEK_END); } } return $fp; } function fclose_w_lock(&$fp) { fflush($fp); flock($fp, LOCK_UN); fclose($fp); } function file_w_lock($filename, $use_include_path = FALSE) { $fp = &fopen_w_lock($filename, 'r', $use_include_path); if($fp === FALSE) return FALSE; $ary = file($filename, $use_include_path); fclose_w_lock($fp); return $ary; }
--- backup.php Sat Apr 30 14:21:00 2005 +++ backup.lock.php Sun Aug 21 18:56:52 2005 @@ -65,12 +65,32 @@ $body = PKWK_SPLITTER . ' ' . get_filetime($page) . "\n" . join('', $body); $body = preg_replace("/\n*$/", "\n", $body); - $fp = _backup_fopen($page, 'wb') - or die_message('cannot write file ' . htmlspecialchars($realfilename) . - '<br />maybe permission is not writable or filename is too long'); - _backup_fputs($fp, $strout); - _backup_fputs($fp, $body); - _backup_fclose($fp); + $filename = _backup_get_filename($page); + do{ + if(($lock = @fopen($filename, 'r')) !== FALSE){ + flock($lock, LOCK_EX); + clearstatcache(); + if(_backup_get_filetime($page) != $lastmod) + break; + }else{ + $lock = @fopen($filename, 'a+') + or die_message('cannot write file ' . htmlspecialchars($filename) . + '<br />maybe permission is not writable or filename is too long'); + flock($lock, LOCK_EX); + // $strout = ''; // 処理中に管理者がファイルを消したとしたら? + clearstatcache(); + if(filesize($filename) != 0) + break; + } + $fp = _backup_fopen($page, 'wb') + or die_message('cannot write file ' . htmlspecialchars($filename) . + '<br />maybe permission is not writable or filename is too long'); + _backup_fputs($fp, $strout); + _backup_fputs($fp, $body); + _backup_fclose($fp); + }while(FALSE); + flock($lock, LOCK_UN); + fclose($lock); } } @@ -230,9 +250,15 @@ */ function _backup_file($page) { - return _backup_file_exists($page) ? - gzfile(_backup_get_filename($page)) : - array(); + $filename = _backup_get_filename($page); + $data = array(); + if(($fp = @fopen($filename, 'r')) !== FALSE){ + flock($fp, LOCK_SH); + $data = gzfile($filename); + flock($fp, LOCK_UN); + fclose($fp); + } + return $data !== FALSE ? $data : array(); } } ///////////////////////////////////////////////// @@ -296,9 +322,15 @@ */ function _backup_file($page) { - return _backup_file_exists($page) ? - file(_backup_get_filename($page)) : - array(); + $filename = _backup_get_filename($page); + $data = array(); + if(($fp = @fopen($filename, 'r')) !== FALSE){ + flock($fp, LOCK_SH); + $data = file($filename); + flock($fp, LOCK_UN); + fclose($fp); + } + return $data !== FALSE ? $data : array(); } } ?>