【问题标题】:Why doesn't dup2 occur in sequential order?为什么 dup2 不按顺序出现?
【发布时间】:2016-12-07 22:21:51
【问题描述】:

这是一个代码 sn-p。

int saved_stdout = dup(1);
int fd = open("file.txt", O_WRONLY | O_CREAT, 0640);

close(1);
dup(fd);
close(fd);

printf("This text should go into the file\n");

//restore stdout
dup2(saved_stdout, 1);
printf("stdout restore");

我正在尝试了解 dup 和 dup2。所以我最初将我的 file.txt 连接到标准输出。因此,每当我使用 printf 时,我都应该写入 file.txt 而不是 stdout。但是,一旦我用完这种用法,我也想恢复它,所以我最后也使用 dup2。

问题是文本“此文本应该进入文件\n”实际上从未进入文件,而是打印在标准输出上。为什么这样?我寻找它,却发现 dup2 调用发生在 printf("This text..."); 之前。声明,为什么会这样?

【问题讨论】:

    标签: c process sequence dup2 dup


    【解决方案1】:

    问题可能是由于输出缓冲造成的。如果stdout 没有写入终端,则它会被完全缓冲,因此当您使用dup() 将其重定向到文件时,它将被缓冲。尝试在printf() 之后刷新输出。

    printf("This text should go into the file\n");
    fflush(stdout);
    

    【讨论】:

    • 这就是我要找的。谢谢
    • 虽然fflush()“有效”,但我怀疑这是出于错误的原因。这里有一些更微妙的事情,因为简单地将任何printf() 放在open() 之后也可以。问题是文件描述符和 FILE 结构的混合,这可能是未定义的领域,这意味着您可能会在不同的系统上得到不同的结果。做你想做的事情的正确方法是freopen("file.txt", "w", stdout)。该操作已明确定义。
    • @gilez 我认为只要你在写东西和更改文件描述符之间保持同步,你应该是安全的。虽然我承认我对这个答案有点犹豫,因为我怀疑缓冲是在打开 stdin 时初始化的,而不是在 printf() 发生时初始化的。但它可能是懒惰的,并且在第一次写入时就这样做了。
    • @Barmar,我怀疑 stdout FILE * 在使用之前没有完全初始化,因此操作顺序也很重要,因此我的 printf() 选项使其“工作”。您对缓冲也可能是正确的。这有点狡猾:-)
    【解决方案2】:

    我删除了我之前的答案,因为它是错误的......但是当您使用printf() 时,您使用的是FILE * 代表stdout,其中有一个描述符或指向终端的东西。更改 fd 1 显然不会改变这一点。

    我的测试结果不一致,所以在这里放弃。我只想补充一点,将这一行放在open() 之后使它对我有用,这突出了晦涩的行为:

    printf("fileno is %i\n", fileno(stdout));
    

    不要将FILE * 操作(例如printf())与文件描述符操作混用。您应该将write() 与描述符一起使用。

    【讨论】:

    • dup() 确实使用了第一个可用的描述符。他的代码是在添加dup2() 之前所做的事情。
    • @Barmar,我认为混淆在于“第一次可用”的含义。是 1 是因为它已关闭,还是 4 是因为它从未使用过?
    • @posixKing,原来它在我的系统上使用 4,也许还有 OP。为何要”?在 linux 上,手册页中的描述并不准确。
    • 在我的系统 (OS X) 上,手册页显示“进程当前未使用的最低编号描述符。”
    • @Barmar,这类似于我的 Linux 系统。但它并没有像我们预期的那样做。它在您的系统上打开 1 还是 4?请参阅 pastebin.com/tQbGrMLe 以获取可编译的副本。
    猜你喜欢
    • 2013-10-27
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2022-06-11
    • 2017-11-23
    • 1970-01-01
    相关资源
    最近更新 更多