涉及 close(2) 的 perror 和 strerror

perror and strerror with close(2) involved

我有这段代码实现了 close(2),你们很多人(包括我自己)都知道这会关闭标准错误,但是关闭它的主要影响是什么?

为什么要打印 "main: Success"?不应该每个目录都有“。”可以打开的目录?

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>


int main() {
    close(2);
    if (fopen(".","r")) 
    {
        printf("main: %s \n", strerror(errno));
    }
    return 0;
}

另一方面

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main() {
    close(2);
    if (fopen(".","r")) 
    {
        perror("main");
    }  
    return 0;
}

这不打印任何东西,知道为什么吗?

标准错误是应该打印错误消息的地方。所以 perror() 在标准错误上打印错误信息。如果关闭标准错误,则无法打印消息。

Why is "main: Success" printed? Shouldn't every directory have the "." dir that can be opened?

是的,确实如此。调用 fopen() 时没有出现错误,所以 errno == 0,消息是 Success.

如果想在fopen()失败时打印错误信息,需要测试NULL:

if (fopen(".") == NULL) {
    printf("main: %s \n", strerror(errno));
}

请注意,打开文件时,使用的 FD 是最低的可用 FD。由于您关闭了 FD 2,因此很可能在打开 . 时使用它。所以标准错误现在指向 . 目录,你不能写入,而 perror() 试图在那里写入时会出错。但是报错不了(报到哪里去?)

what are the main repercussions of closing it?

未定义的行为。 C 标准表示 "The behavior is undefined in the following circumstances: [...] The value of a pointer to a FILE object is used after the associated file is closed" 和 POSIX says "The stderr stream is expected to be open for reading and writing."