You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于SVN中文件描述符重用引发文件损坏的技术疑问

关于SVN代码中文件描述符处理的疑问解答

看到的SVN源码注释:

/* The following makes sure that file descriptors 0 (stdin), 1
(stdout) and 2 (stderr) will not be "reused", because if
e.g. file descriptor 2 would be reused when opening a file, a
write to stderr would write to that file and most likely
corrupt it. */

对应的源码实现:

if ((fstat(0, &st) == -1 && open("/dev/null", O_RDONLY) == -1) ||
    (fstat(1, &st) == -1 && open("/dev/null", O_WRONLY) == -1) ||
    (fstat(2, &st) == -1 && open("/dev/null", O_WRONLY) == -1))
  {
    if (error_stream)
      fprintf(error_stream, "%s: error: cannot open '/dev/null'\n",
              progname);
    return EXIT_FAILURE;
  }

问题1:重用文件描述符为何会导致文件损坏?

操作系统分配文件描述符时,会优先选用当前未被使用的最小编号。比如如果stderr对应的fd=2被关闭了,后续调用open()打开普通文件时,系统很可能把fd=2分配给这个新文件。这时程序里如果还有代码向stderr(也就是现在的fd=2)写入错误信息、日志,这些内容会直接写到那个普通文件里,打乱文件原有内容结构,最终导致文件损坏。

问题2:如何使用文件描述符2(stderr)打开文件?

准确来说是把目标文件关联到fd=2,常见两种实现方式:

  • 方法一:先关闭fd=2,再调用open()打开目标文件。系统会自动把最小可用的fd(也就是2)分配给新文件,此时fd=2就指向这个文件。
  • 方法二:先打开目标文件得到临时fd,再用dup2()将临时fd复制到fd=2。示例代码:
    int tmp_fd = open("target_file", O_WRONLY | O_CREAT, 0644);
    if (tmp_fd != -1) {
        dup2(tmp_fd, 2); // 将临时fd的关联复制到fd=2
        close(tmp_fd);   // 临时fd不再需要,关闭释放
    }
    

问题3:打开文件的操作为何会影响对stderr的写入?

如果stderr对应的fd=2处于未使用状态(比如被提前关闭),调用open()打开新文件时会复用这个fd。此时fd=2对应的已经不是原来的标准错误输出(通常是终端),而是新打开的文件。程序里所有向stderr(fd=2)的写入操作,都会被操作系统导向这个新文件,而不是原本的标准错误输出,自然就改变了stderr的写入行为。

内容的提问来源于stack exchange,提问作者user15787088

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:45:44