perror и strerror с участием close (2) - PullRequest
0 голосов
/ 27 мая 2020

У меня есть этот код с реализованным close (2), как многие из вас знают (включая меня), это закрывает стандартную ошибку, но каковы основные последствия ее закрытия?

И почему "main : Успех "напечатан?" Не в каждом каталоге должен быть символ "." 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;
}

Это ничего не печатает, есть идеи, почему?

Ответы [ 2 ]

4 голосов
/ 27 мая 2020

Стандартная ошибка - это место, где должны печататься сообщения об ошибках. Итак, perror() печатает сообщение об ошибке при стандартной ошибке. Если вы закроете стандартную ошибку, она не сможет распечатать сообщение.

Почему печатается «main: Success»? Не в каждом каталоге должен быть символ "." dir, который можно открыть?

Да, открывает. Вы не получили сообщение об ошибке при вызове fopen(), поэтому errno == 0, и сообщение для этого: Success.

Если вы хотите распечатать сообщение об ошибке при сбое fopen(), вам нужно для проверки NULL:

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

Обратите внимание, что при открытии файлов используемый FD является самым низким доступным FD. Поскольку вы закрыли FD 2, он, скорее всего, будет использован при открытии .. Таким образом, стандартная ошибка теперь указывает на каталог ., в который вы не можете писать, а perror() получит сообщение об ошибке при попытке записи в него. Но он не может сообщить об этой ошибке (где бы он сообщил об этом?).

0 голосов
/ 27 мая 2020

каковы основные последствия его закрытия?

Undefined Behavior. Стандарт C говорит: «Поведение не определено в следующих случаях: [...] Значение указателя на объект FILE используется после закрытия связанного файла», а POSIX сообщает » Ожидается, что поток stderr будет открыт для чтения и записи. "

...