我正在与某人讨论以下代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <string.h>
int main() {
// creates a new file having full read/write permissions
int fd = open("myfile", O_RDWR | O_CREAT, 0666);
write(fd, "hahan", 5);
close(fd); // line 6
fd = open("myfile", O_RDWR); // line 7
close(0);
close(1);
dup(fd);
dup(fd);
if (fork() == 0) {
char s[100];
dup(fd);
scanf("%s", s);
printf("hellon");
write(2, s, strlen(s)); // line 18
}
wait(NULL);
printf("Father finishedn");
close(fd);
return 0;
}
他声称我们两次关闭同一个文件导致了错误,但我看不出。
子进程有自己的指向FDT的指针,当他关闭其中一个指针时,他可以毫无问题地关闭其他指针(即使其他指针可能指向相同的FDT(
另外,这也不会影响父亲。我错了吗?你认为这方面有什么问题吗?
首先,连续或同时打开同一个文件两次都不是错误。关闭任何打开的文件描述符也不是错误,无论它指的是什么文件
但我认为你的争议实际上是关于所有dup
ing和fork
ing的效果。假设这个代码片段中的所有函数调用都成功了(你真的应该测试一下,尤其是因为它会解决你的争议(。。。
fd = open("myfile", O_RDWR); // line 7 close(0); close(1); dup(fd); dup(fd);
。。。之后将有三个不同的文件句柄,它们都引用相同的打开文件描述。关闭其中一个会解除文件描述符与基础打开文件描述的关联,但这不会使其他描述符无效,并且当任何文件描述符与之关联时,基础打开文件说明不会关闭。
当该进程成功分叉时,新的子进程将获得其自己的、与无关的文件描述符,这些描述符具有相同的数值,所有这些描述符都与父进程的相同打开文件描述相关联。也就是说,当您在第二个dup
之后成功分叉时,就会有六个打开文件描述符,它们都与相同的底层打开文件描述相关联——三个在父级,三个在子级。父级和子级中的文件描述符编号相同这一事实无关紧要。文件描述符编号是每个进程的属性。
然后,子级再次dup()
的文件描述符fd
,生成(成功时(与打开的文件描述相关联的第七个文件描述符。然后,子级从if
块的底部掉出来,并关闭其文件描述符fd
。它正常终止,结果是它所有其他打开的文件描述符也被关闭。
所有这些都不会直接影响父级,只是父级将从其wait()
中唤醒并继续。然后,它将关闭自己的打开文件描述符,其中一个显式关闭,其余的在自己终止时隐式关闭。
不存在对同一文件描述符的多次关闭,但同样,如果您担心这一点,则可以检查close()
的返回值,以确定它是否成功完成。