昨年から PHP7で動作するよう rNote を修正して使用していたが、PHPマニュアルサイトの flock() の説明によると、 PHP 5.3.2 以降は、 flock($fp, LOCK_EX); などでロックしたファイルは、 fclose($fp); の直前で明示的に flock($fp, LOCK_UN); を呼んでアンロックしてやらないといけないことに気づいたので grep で検索してみたら、結構あちこちでアンロックを明示的に呼んでいなかった。
そこで、 flock($fp, LOCK_UN); を明示的に呼びだすように修正した。(修正しなくても特に問題なく動作していたが、 PHP の仕様上正しくロックしなくなっていたはず。)
特に気を付けたいのが rnote.php で下のように定義されている _fopen_wb() 。
function _fopen_wb($fname){
$fp = @fopen($fname, "wb");
if(! $fp) error("$fname : File write error");
set_file_buffer($fp, 0);
flock($fp, LOCK_EX);
rewind($fp);
return $fp;
}
この関数の中では $fp = fopen() が呼ばれ、開かれたファイルをロックしているのだが、アンロックしないまま fclose($fp); も呼ばず、そのまま $fp を返り値として返しているので、_fopen_wb() を呼び出した側で、受け取った $fp を使用した後に fclose($fp) する直前で明示的に flock($fp, LOCK_UN); を呼ばなければいけない。コードとしてはかなり見通しが悪くなり汚いコードになるが仕方がないのでそのように修正した。
この記事のリンク元