涉及到perror和strerror的close(2)。

问题描述 投票:1回答:1

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

还有为什么会打印 "main: Success "打印出来?是不是每个目录都应该有可以打开的". "dir?

#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;
}

这不打印任何东西,有什么想法吗?

c system-calls errno unistd.h strerror
1个回答
4
投票

标准错误是应该打印错误信息的地方。所以 perror() 在标准错误上打印其错误信息。如果你关闭标准错误,它就不能打印信息。

为什么打印 "main: Success "打印出来了?是不是每个目录都应该有可以打开的". "dir?

是的,它有。当你调用 fopen()所以 errno == 0,而这一信息是 Success.

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

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

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


0
投票

关闭它的主要影响是什么?

未定义行为。C标准说:"在下列情况下,行为是未定义的。[......]FILE对象指针的值在相关文件关闭后被使用",以及: POSIX说 "stderr流预计将被打开进行读写。"

© www.soinside.com 2019 - 2024. All rights reserved.