fopen, fwrite, fclose のエラー処理

好き嫌いの問題っていうよりは信頼性の問題で open, write, close のほうが普通?って思ったりするけれど、それはおいといて。
以下のソースコードは、引数に与えられたパスに1バイト分"a"を書き出して終了するプログラム。

#include <stdio.h>
#include <errno.h>

int main(int argc, char *argv[])
{
        FILE *fp;
        char s[1] = {"a"};
        size_t fwb;
        int ret;

        if ((fp = fopen(argv[1], "a+")) == NULL ) {
                printf("Failed to open: %s\n", strerror(errno));
                exit(1);
        }

        fwb = fwrite(s, sizeof(char), 1, fp);
        if (fwb < 1) {
                printf("Failed to write: %s\n", strerror(errno));
                exit(2);
        }

        if (EOF == (ret=fclose(fp))) {
                printf("Failed to close: %s\n", strerror(errno));
                exit(3);
        };

        printf ("OK.\n");
        return 0;

}

ここで問題です。
あと1バイトも書けません!という時には、どこでエラーになるでしょう?

  • 1: ファイルを開くとき
  • 2: ファイルに書き込むとき
  • 3: ファイルを閉じるとき

開発屋ならぜひ間違えないでほしい正解は…
3です。
fwrite()の返値は、書き込んだ数なんだけど、これはOSの書き込みキャッシュに書いた数なんです。だから、ファイルシステムがいっぱいいっぱいでも、書き込みキャッシュにはかけちゃいます。
fclose()をすると、fflush()が内部で呼ばれてOSの書き込みキャッシュがフラッシュされるので、そこではじめて " No space left on device " となるのです。

なんでこんなエントリ書いてるかって、アホの開発屋がopenじゃなくてfopenで書くし、fcloseのチェックしないもんだからえらい目にあってるんです。怒るぞこコノヤロー!!!!(怒ってるけどな!!)