我的程序按时间顺序执行以下操作
open()
ed。clone()
并设置CLONE_FILES | CLONE_FS | CLONE_IO
标志,这意味着虽然它们使用单独的虚拟内存区域,但它们共享相同的文件描述符表(以及其他IO内容)。 / LI>
execve()
他们自己的程序(不使用FD_CLOEXEC
标志)。现在我希望每个衍生程序都读取上述文件的内容,但是在他们都读完文件之后,我希望它被关闭(出于安全原因)。
我正在考虑的一个可能的解决方案是进行步骤3a,其中每个子进程的文件的fd为dup()
一次,并且每个子进程都有自己的fd(作为argv
)。然后每个子程序只需close()
他们的fd,这样在指向文件的所有fds为close()
之后,“实际文件”就会关闭。
但这样做有用吗?这样做是否安全(即文件是否真的关闭)?如果没有,还有其他/更好的方法吗?
答案 0 :(得分:2)
正如我上面提到的那样使用dup()
可能就好了,我现在 - 在问这个问题后的第二天 - 意识到有一个更好的方法可以做到这一点,至少从这一点来看线程安全的观点。
所有dup()
合法文件描述符指向相同的文件位置指示符,这当然意味着当多个线程/进程可能同时尝试在读取操作期间更改文件位置时遇到麻烦(即使您自己的代码以线程安全的方式执行,同样不一定适用于您所依赖的库。
等等,为什么不在需要的文件上多次调用open()
(每个孩子一次),然后再删除root?来自open()
的手册:
对open()的调用会创建一个新的打开文件描述,这是系统范围的打开文件表中的一个条目。此条目记录文件偏移量和文件状态标志(可通过fcntl(2)F_SETFL操作修改)。文件描述符是对这些条目之一的引用;如果随后删除或修改路径名以引用其他文件,则此引用不受影响。新的打开文件描述最初不与任何其他进程共享,但可以通过fork(2)进行共享。
可以像这样使用:
int fds[CHILD_C];
for (int i = 0; i < CHILD_C; i++) {
fds[i] = open("/foo/bar", O_RDONLY);
// check for errors here
}
drop_privileges();
// etc
然后每个孩子通过argv
获得对其中一个fds的引用,并执行以下操作:
FILE *stream = fdopen(atoi(argv[FD_STRING_I]), "r")
stream
fclose(stream)
(这也会关闭基础文件描述符)免责声明:根据我所运行的一系列测试,这确实是安全可靠的。然而,我只用 O_RDONLY 测试了open()
。 使用O_RDWR或O_WRONLY可能安全,也可能不安全。