【问题标题】:Is it possible to rescue file descriptor from FILE*?是否可以从 FILE* 中拯救文件描述符?
【发布时间】:2014-04-11 09:38:00
【问题描述】:

我必须使用某个跨平台库来传递FILE* 对象。

我从另一个源(继承)获得一个文件描述符,我想在fork'd 进程中保持相同的fd。

我目前使用fdopen 将文件描述符转换为FILE* 对象。

我的问题是 fclose 用于清理 FILE* 对象关闭连接的文件描述符。

我非常希望在使用此文件描述符后保留它。

有没有办法从FILE* 拯救文件描述符?

有没有办法把它拆下来?

或者用虚拟对象替换FILE* 中的文件描述符?

附:这需要是跨平台的,无论如何都要跨 POSIX。

【问题讨论】:

    标签: c file posix fclose fdopen


    【解决方案1】:

    假设 fd 是您的文件描述符,而 f 您的 FILE* 是从中获取的。也许像下面这样的东西可以解决问题:

    fd2 = dup(fd);
    fclose(f);
    dup2(fd2, fd);
    close(fd2);
    

    【讨论】:

      【解决方案2】:

      我的问题是 fclose 用于清理 FILE* 对象关闭 连接的文件描述符。

      您可以使用dup(2) 来获取描述符的副本。那么fclose(3) 所做的close(2) 将不会做任何事情。

      我需要保持完全相同的 fd 编号

      然后在fclose之后再次调用dup2:dup2(savedfd, rescuedfd)

      【讨论】:

      • 请再读一遍,由于fork的原因,我需要保持完全相同的fd号码
      • 嘿,这可能真的有效。但它不是线程安全的,因为另一个线程可能会在 close 和 dup2 之间分配这个 fd 编号。 dup3 将突出显示此案例,但不会解决它。我会考虑的!
      • @qarma 还有其他技巧可以帮助你,比如劫持fclose 等。不过我不会走那条路。
      【解决方案3】:

      当您从另一个来源获取文件描述符时,请尝试从该文件描述符中获取其文件名。 (有人说它可以使用特定于平台的方法。-google it。)

      一旦你得到文件名,然后再次 fopen 并得到 FILE* 并完成你的工作并使用 fclose 清理它。

      您的原始文件不会受到干扰。

      【讨论】:

      • +1 聪明的主意,我可以在 linux 上用open("/proc/self/fd/9") 做到这一点,但不是 OSX 或任何 BSD 克隆。
      【解决方案4】:

      这是一个不可移植的想法(如果您认为这是好的/最好的,请投票):

      GNU libc 提供fopencookie,BSD 提供等效的funopen。

      这些返回真正的FILE* 句柄,但实现是你自己的:

      然后将 read/write/seek/close 函数映射到底层系统调用相对简单:

      read/readfn(cookie, buf, size){ return read((int)cookie, buf, size); }
      write/writefn(cookie, buf, size) { return write((int)cookie, buf, size); }
      seek/seekfn(cookie, offs, arg) { return seek((int)cookie, offs, arg); } // may require arg mapping to whence
      close/closefn(cookie) {} // that's the whole point!
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-16
        • 2010-12-03
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        • 2010-11-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多