プログラムがファイルをmvしてもmvしたファイルを掴み続ける話

#動機
昨日mvしたらそのファイルが管理から外れて、
それで前のファイル名のファイルにたいして出力されるかなって思ってたらそんなことなかったので検証メモ。

#検証
まずは検証するためのサンプルコード。
今回はC言語で

````C
    #include <stdio.h>

    int main(){
        FILE *fp;
        char *fname = "test.txt";

        fp = fopen( fname, "w" );
        if( fp == NULL ){
            printf( "Open Error", fname );
            return -1;
        }

        fputc('a', fp );


        fputc('b', fp );
        fputc('\0', fp );

        fclose( fp );

        return 0;
    }
````

これを以下のCMakeLists.txtを用いてCMakeでコンパイル、
gdbで途中で実行を止めてmvするということを試す。

````CMake
    cmake_minimum_required (VERSION 2.8)

    project(mv_test)

    set(CMAKE_BUILD_TYPE Debug)

    add_executable(a.out main.c)
    set(CMAKE_C_FLAGS "-std=c99")
````

できたプログラムをgdbでとりあえずfputcのとこで止める。
    
    (gdb) b 13
    Breakpoint 1 at 0x4008b9: file /home/ikaro/Test/main.c, line 13.
    (gdb) run
    Starting program: /home/ikaro/Test/build/a.out 
   
    Breakpoint 1, main () at /home/ikaro/Test/main.c:13
    13          fputc('a', fp );
    
ここでlsofで掴んでいるファイルとiNodeを確認してみる。
一番右が実行されているプログラム、一番左が掴んでいるファイル、
左から二番目がinodeだ。
今回のtext.txtのiNodeは925494となっている。


    $ lsof|grep a.out
    a.out     30785         ikaro  cwd       DIR              253,2      4096     925461 /home/ikaro/Test/build
    a.out     30785         ikaro  rtd       DIR              253,1      4096          2 /
    a.out     30785         ikaro  txt       REG              253,2     10938     925460 /home/ikaro/Test/build/a.out
    a.out     30785         ikaro  mem       REG              253,1    157200    1056509 /usr/lib64/ld-2.18.so
    a.out     30785         ikaro  mem       REG              253,1   2100672    1056512 /usr/lib64/libc-2.18.so
    a.out     30785         ikaro    0u      CHR              136,3       0t0          6 /dev/pts/3
    a.out     30785         ikaro    1u      CHR              136,3       0t0          6 /dev/pts/3
    a.out     30785         ikaro    2u      CHR              136,3       0t0          6 /dev/pts/3
    a.out     30785         ikaro    3w      REG              253,2         0     925494 /home/ikaro/Test/build/test.txt

次にmvしてtest.txt.2というファイル名にリネームしてみよう。

    $ mv test.txt{,.2}

ここでもう一度掴んでいるファイルを確認してみると

    $ lsof|grep a.out
    a.out     30785         ikaro  cwd       DIR              253,2      4096     925461 /home/ikaro/Test/build
    a.out     30785         ikaro  rtd       DIR              253,1      4096          2 /
    a.out     30785         ikaro  txt       REG              253,2     10938     925460 /home/ikaro/Test/build/a.out
    a.out     30785         ikaro  mem       REG              253,1    157200    1056509 /usr/lib64/ld-2.18.so
    a.out     30785         ikaro  mem       REG              253,1   2100672    1056512 /usr/lib64/libc-2.18.so
    a.out     30785         ikaro    0u      CHR              136,3       0t0          6 /dev/pts/3
    a.out     30785         ikaro    1u      CHR              136,3       0t0          6 /dev/pts/3
    a.out     30785         ikaro    2u      CHR              136,3       0t0          6 /dev/pts/3
    a.out     30785         ikaro    3w      REG              253,2         0     925494 /home/ikaro/Test/build/test.txt.2

とつかんでいるファイルのiNodeはかわらないもののファイル名は確かに変化している。
あとはdgbでcontinueして一気におわりまですすませてtext.txt.2を見てみるとたしかにabという内容が書き込まれていて、
text.txtというファイルも生成されていないことがわかる。
ということでfopenしたファイルはアイノードで掴み続けるということでした。

そのうちファイルシステムとかファイルを開く部分の実装とかよんで追記するかも?