fopenでファイルにログ等を書き込んでいますが、

fopenで開く予定のファイルを、ログの確認等で
Apacheではなく管理者ユーザー等が先に開いていた場合、
Win環境では、permission denyでWarningエラーになりますが
Linux環境では、viでもlessでも問題なくApacheが
書き込んで行きます。
この違いはviやlessが読みとり専用で開いていたりするからでしょうか。
また、Win環境で当該permission denyを防ぐ方法として
どのような方法が一般的でしょうか。
個人的には、fopen失敗したら、開く予定のファイル名に連番をふって
そこに書き込むなどを考えていますが。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2014/08/07 14:36:59
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.1

回答回数4972ベストアンサー獲得回数2154

ポイント100pt

だいたいのことは、Wikipedia の以下のページで解説されています。
 →「ファイルロック - Wikipedia


Windows での fopen は WIN32API の CreateFile のラッパーです。
CreateFile API は、その第三引数で共有モードが決まります。
 → CreateFile 関数

Microsoft の fopen のソースを見たことはありませんが、第三引数の dwShareMode は、ゼロが設定されているでしょう。
つまり、排他がかかる。


unix 系の fopen は、open システムコールのラッパーです。
open には、ファイルのロックの機能がありません。
明示的に fctrl なんかでロックをかけないと、ファイルは共有される。

POSIX だと、ファイルの共有モードを指定してファイルを開くのは、sopen 。
デフォルトが「ファイルは、共有される」なので、sopen を使うケースは、ファイル共有に制限をかけたい場合。



個別のコマンドに着目すると、その実装によるので、また事情がちょっと違います。

vi もしくは、そのクローンの場合。
初期の vi は違ったと思いますが、vim に代表される vi のクローンだと、編集ファイルを直接いじるのではなく、ワークファイルを作って、それに編集内容や履歴を保持します。
編集対象には、明示的にロックをかけていませんから、他のプロセスも書き込めます。
でも、vi を触っていると、その他のプロセスからの変更内容が分からない(対象のファイルを、逐一見ているわけでは無いから)。
明示的に、:e! としないと、その時点でのファイルの内容は、編集画面に反映されません。


less の場合。
読み取り専用で開いているとは思いますが、それはファイルの排他を意識してのことでは無くて、ファイルに書き込む機能が無いから、という理由にすぎません。
less が早いのは、一度に対象のファイルをすべて読み込むわけでは無いから。
大きなファイルを開いた直後に、別のプロセスが、ファイルの末尾に追加書込みをした場合、less で、G でファイルの末尾を表示すると、その追加書込みを参照できます。

G は、実ファイルの読み直しもやっています。
ファイルの末尾を表示している状態で、別のプロセスが、ファイルの末尾に追加書込みをする。
less で、G とすると、追加書込みされた内容が表示されます。

それは、そういうふうに実装されているから。


また、Win環境で当該permission denyを防ぐ方法として
どのような方法が一般的でしょうか。

Windows のアプリは、ほぼ全てと言って良いくらい、排他をかけてファイルをオープンします。
なので、一般的なのは、なるべく早くファイルをつかんで、つかみっぱなしにしておく(つまり、fclose しない)ことです。

自分が最初にファイルをつかむことが期待できない場合には、質問の文面にも書かれている通り、別ファイルに書き出すしかないでしょうね。

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません