【发布时间】:2017-05-17 20:14:18
【问题描述】:
我想知道为什么取消注释以下程序中的第一个 printf 语句会改变其后续行为:
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main() {
//printf("hi from C \n");
// Close underlying file descriptor:
close(STDOUT_FILENO);
if (write(STDOUT_FILENO, "Direct write\n", 13) != 13) // immediate error detected.
fprintf(stderr, "Error on write after close(STDOUT_FILENO): %s\n", strerror(errno));
// printf() calls continue fine, ferror(stdout) = 0 (but no write to terminal):
int rtn;
if ((rtn = printf("printf after close(STDOUT_FILENO)\n")) < 0 || ferror(stdout))
fprintf(stderr, "Error on printf after close(STDOUT_FILENO)\n");
fprintf(stderr, "printf returned %d\n", rtn);
// Only on fflush is error detected:
if (fflush(stdout) || ferror(stdout))
fprintf(stderr, "Error on fflush(stdout): %s\n", strerror(errno));
}
如果没有第一个 printf,后续的 printf rtns 34 就好像没有发生错误,即使从标准输出用户缓冲区到底层 fd 的连接已经关闭。只有在手动 fflush(stdout) 上才会报告错误。 但是当第一个 printf 打开时,下一个 printf 会像我预期的那样报告错误。 当然,在任何一种情况下关闭 STDOUT_FILENO fd 后,都不会向终端写入任何内容(通过 printf)。
我知道close(STDOUT_FILENO) 首先在这里很愚蠢;这是我偶然发现的一个实验,我认为在这些领域知识渊博的人可能会从中看到对我们有启发性的东西..
我在 Linux 上使用 gcc。
【问题讨论】:
-
stdout处于错误状态,因为您关闭了底层描述符STDOUT_FILENO事情与fclose(stdout)正常工作。