grep

http://d.hatena.ne.jp/sshi/20061129/p1

"a"だけを2048行並べた4096バイトのファイルfooにgrep a foo >> fooを実行すると処理は無事に止まって、fooは二倍のサイズ(4096行8192バイト)になる。じゃ1バイトだけ増やそう、と思って最終行だけ"aa"にした2048行4097バイトのfooに同じことをすると、、
$ wc foo
2048 2048 4097 foo
$ grep a foo >> foo
$ wc foo
6144  6144 12291 foo
処理は止まるが何故かサイズが三倍に…。なんで三倍?

元ネタよりもid:sshiの結果が気になったので少し調べて以下の仮説を立てみた。

  1. ファイルを全て(4097バイト)読み込む。
  2. grep結果を出力していって最後の行を出力したところでwriteバッファが4096バイトになりフラッシュされファイルにも書き込まれる。writeバッファには"\n"だけ残る。
  3. 最後の行まで出力したので再度ファイルを読むと上で書いた4096バイトが読み込める。読み込んだ最後の行は"aa"。
  4. grep結果を出力していく(writeバッファにたまっていく)が最後の行は改行でもEOFでもないため、もう一度ファイルを読み込む。
  5. 何も読めないのでEOFになる。
  6. 最後の行"aa[EOF]"のgrep結果"aa\n"が書き込まれて終了。

ソース追ったりして確かめる気力はないなぁ…orz