カレントディレクトリを消す実験でシェルから実行するとシェルが何をしているかわからないのでopenしているかもしれない。なのでテストプログラムを組んで実験してみた。
koie@guriandgura% df .
Filesystem 1024-blocks Used Avail Capacity Mounted on
/dev/ad4s2a 507630 352518 114502 75% /
koie@guriandgura% uname -sr
FreeBSD 9.0-CURRENT
koie@guriandgura% cat -n foo.c
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <dirent.h>
4 #include <sys/stat.h>
5
6 static void
7 ls_file(const char* path)
8 {
9 struct stat st;
10 lstat(path, &st);
11 printf("%-10s ino=%ld nlink=%ld\n", path, st.st_ino, st.st_nlink);
12 }
13
14 static void
15 ls_dir(const char* path)
16 {
17 DIR* dp = opendir(path);
18 if (dp == NULL) {
19 perror("opendir");
20 return;
21 }
22 printf("ls %s {\n", path);
23 struct dirent *dep;
24 while ((dep = readdir(dp)) != NULL) {
25 char fn[100];
26 snprintf(fn, sizeof fn, "%s/%s", path, dep->d_name);
27 ls_file(fn);
28 }
29 closedir(dp);
30 printf("}\n");
31 }
32
33 int
34 main()
35 {
36 int rc;
37 if (mkdir("d", 0777) < 0) {
38 perror("mkdir");
39 return 1;
40 }
41 if (chdir("d") < 0) {
42 perror("chdir");
43 return 1;
44 }
45 ls_dir(".");
46 if (rmdir(".", 0777) < 0) {
47 perror("rmdir");
48 printf("keep going.\n");
49 }
50 if (rmdir("../d", 0777) < 0) {
51 perror("rmdir");
52 return 1;
53 }
54 ls_dir(".");
55 ls_file(".");
56 return 0;
57 }
koie@guriandgura% cc foo.c
koie@guriandgura% ./a.out
ls . {
./. ino=33552 nlink=2
./.. ino=33544 nlink=3
}
rmdir: Invalid argument
keep going.
ls . {
}
. ino=33552 nlink=0
koie@guriandgura%
$ uname -sr
Linux 2.6.18-194.32.1.el5
$ cc foo.c
$ uname -sr
Linux 2.6.18-194.32.1.el5
$ ./a.out
ls . {
./.. ino=64225281 nlink=4
./. ino=64225284 nlink=2
}
rmdir: Invalid argument
keep going.
ls . {
}
. ino=64225284 nlink=0
$
この結果からすると、ディレクトリのデータ部分(つまりディレクトリエントリ)は消えているが、ディレクトリ自身(=ディレクトリのメタデータ=inode)は消えてなくて、おそらくlookupで"."が特別扱いされいるためにディレクトリエントリを参照することなくカレントディレクトリを返しているのではないだろうか。
#正直なところおっさんにはカーネルソースを読む気力はすでにない。














