使用 rmdir() 删除目录后 opendir() 的行为
我试图了解如何从 C 程序中删除当前工作目录。我使用《Unix 环境中的高级编程》一书作为参考。首先,我进行以下调用序列(/tmp
是一个现有目录):
// 1. Create a test directory
if (mkdir("/tmp/foo", DIR_PERM) < 0){
printf("mkdir error\n");
}
else
printf("mkdir succeeded\n");
// 2. Change cwd to the test directory
if (chdir("/tmp/foo") < 0)
printf("chdir error\n");
else
printf("chdir succeeded\n");
// (2.5) Check the cwd
if (getcwd(cwd, sizeof(cwd)) != NULL)
printf("Current working directory: %s\n", cwd);
else
printf("getcwd error\n");
// 3. Remove the test directory
if (rmdir("/tmp/foo") < 0)
printf("rmdir error\n");
else
printf("rmdir succeeded\n");
// (3.5) Check current working directory
if (getcwd(cwd, sizeof(cwd)) != NULL)
printf("Current working directory: %s\n", cwd);
else
printf("getcwd error\n");
这正如我所期望的那样。 mkdir
、chdir
和 rmdir
成功,(2.5) 中的 getcwd
返回 /tmp/foo (3.5) 中的
路径名和 getcwd
失败。
我不明白的是随后使用 "."
, " 在
和 /tmp/foo
目录上使用 opendir
的行为../foo""/tmp/foo"
作为路径名:
// 4. Open the removed directory using "."
if ((dp = opendir(".")) == NULL)
printf("1. opendir error\n");
else{
printf("1. opendir succeeded\n");
while((dirp = readdir(dp)) != NULL)
printf("%s\n", dirp->d_name);
}
// 5. Open the removed directory using "../foo"
if ((dp = opendir("../foo")) == NULL)
printf("2. opendir error\n");
else
printf("2. opendir succeeded\n");
// 6. Open the removed directory using "/tmp/foo"
if ((dp=opendir("/tmp/foo")) == NULL)
printf("3. error\n");
else
printf("3. opendir succeeded\n");
上述代码片段的输出是
- opendir 成功
- 打开目录错误
- 打开目录错误
为什么 opendir(".")
可以工作,而 opendir("../foo")
却不能?据我了解,/tmp/foo
目录的链接计数在rmdir
之后变为0。点和点-点条目在该函数返回之前被删除,并且在成功调用 opendir
后读取 4. 中的目录不会打印任何内容。如果在 rmdir
期间删除了该条目,opendir
如何知道点代表什么?如果它可以解析点,为什么它不能解析点呢?
I'm trying to understand how removing the current working directory works from a C program. I'm using the Advanced Programming in Unix Enviroment book as a reference. First, I make the following sequence of calls (/tmp
is an existing directory):
// 1. Create a test directory
if (mkdir("/tmp/foo", DIR_PERM) < 0){
printf("mkdir error\n");
}
else
printf("mkdir succeeded\n");
// 2. Change cwd to the test directory
if (chdir("/tmp/foo") < 0)
printf("chdir error\n");
else
printf("chdir succeeded\n");
// (2.5) Check the cwd
if (getcwd(cwd, sizeof(cwd)) != NULL)
printf("Current working directory: %s\n", cwd);
else
printf("getcwd error\n");
// 3. Remove the test directory
if (rmdir("/tmp/foo") < 0)
printf("rmdir error\n");
else
printf("rmdir succeeded\n");
// (3.5) Check current working directory
if (getcwd(cwd, sizeof(cwd)) != NULL)
printf("Current working directory: %s\n", cwd);
else
printf("getcwd error\n");
This works as I would expect. mkdir
, chdir
, and rmdir
succeed, getcwd
in (2.5) returns the /tmp/foo
pathname and getcwd
in (3.5) fails.
What I don't understand is the behavior of using opendir
afterward on the /tmp/foo
directory using "."
, "../foo"
, and "/tmp/foo"
as pathnames:
// 4. Open the removed directory using "."
if ((dp = opendir(".")) == NULL)
printf("1. opendir error\n");
else{
printf("1. opendir succeeded\n");
while((dirp = readdir(dp)) != NULL)
printf("%s\n", dirp->d_name);
}
// 5. Open the removed directory using "../foo"
if ((dp = opendir("../foo")) == NULL)
printf("2. opendir error\n");
else
printf("2. opendir succeeded\n");
// 6. Open the removed directory using "/tmp/foo"
if ((dp=opendir("/tmp/foo")) == NULL)
printf("3. error\n");
else
printf("3. opendir succeeded\n");
The output of the above code snippet is
- opendir succeeded
- opendir error
- opendir error
Why does opendir(".")
work but opendir("../foo")
doesn't? As I understand it, the link count of the /tmp/foo
directory becomes 0 after rmdir
. The dot and dot-dot entries are removed before that function returns and reading the directory in 4. after the successful opendir
call doesn't print anything. How does opendir
know what dot stands for if that entry was removed during rmdir
? And why wouldn't it resolve dot-dot if it can resolve dot?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,程序的当前工作目录仍然指向那里。它就像一个开放的索引节点。
内核跟踪进程并跟踪进程当前工作目录,并且它知道什么是
.
。它解析
..
。它不解析../foo
,删除后..
处没有foo
。opendir('..')
应该仍然可以工作。No, your program's current working directory still points there. It's like an open inode.
Kernel keeps track of processes and keeps track of processes current working directories and it knows what is
.
.It resolves
..
. It does not resolve../foo
, there is nofoo
at..
after it was deleted.opendir('..')
should still work.