Что означает POSIX, когда говорится, что stderr должен быть открыт для чтения и записи? - PullRequest
10 голосов
/ 28 мая 2020
Страница

POSIX на stderr, stdin, stdout - стандартные потоки ввода-вывода говорит следующее:

Ожидается, что поток stderr будет открыт для чтение и письмо.

Насколько сильным "ожидается быть"? Нарушает ли это неопределенное поведение? И чья это ответственность, система или приложение?

Рассмотрим эту программу:

#include <stdio.h>

int main(void) {
    printf("feof is %d and ferror is %d\n", feof(stderr), ferror(stderr));
    printf("fgetc is %d\n", fgetc(stderr));
    printf("feof is %d and ferror is %d\n", feof(stderr), ferror(stderr));
}

Когда я запускаю это без перенаправления stderr (так что он указывает на мой терминал, как stdin) , он немедленно выводит это, не дожидаясь ввода:

feof is 0 and ferror is 0
fgetc is -1
feof is 0 and ferror is 1

Означает ли это, что моя система не совместима с POSIX?

Кроме того, если это моя ответственность, то предположим, что у меня есть файл с разрешениями 620, и что я в группе, но не владелец. Означает ли это, что someprogram 2>saidfile является неопределенным поведением, поскольку в этом случае вы не можете читать из stderr ни при каких обстоятельствах?

1 Ответ

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

POSIX уточняет это в спецификации для execve:

Если дескриптор файла 0, 1 или 2 в противном случае был бы закрыт после успешного вызова одного из Для семейства функций exe c реализации могут открывать неуказанный файл для файлового дескриптора в новом образе процесса. Если стандартная утилита или соответствующее приложение выполняется с файловым дескриптором 0, не открытым для чтения, или с файловым дескриптором 1 или 2, не открытым для записи, среда, в которой выполняется утилита или приложение, считается несоответствующей, и, следовательно, утилита или приложение могут вести себя не так, как описано в этом стандарте.

Для ваших собственных приложений они должны быть готовы к тому, что реализация откроет для них новый stdin / out / err, если они попытаются выполнить c с любым из них закрытым, и может устанавливать свои собственные правила (в том числе считать это нарушением контракта, приводящим к катастрофически неправильному поведению) для того, как они справляются с этим, если стандартные файловые дескрипторы не открываются при запуске.

Для стандартных утилит приведенный выше текст охватывает это.

Документ , который вы процитировали, просто указывает, что они связаны с этими файловыми дескрипторами. Я согласен, что это недостаточно ясно, но разумной интерпретацией было бы то, что если соответствующие файловые дескрипторы не открыты или не открыты для соответствующих режимов при входе в приложение, результаты будут теми, которые указаны для этого условия (обычно EBADF) в соответствующих функциях. . Например, fgetc указывает:

[EBADF]

[CX] [Option Start] Базовый поток файлового дескриптора не является допустимым файловым дескриптором, открытым для чтения. [Конец опции]

Относительно «ожидаемого» текста:

Ожидается, что поток stderr будет открыт для чтения и записи.

Я не думаю, что «ожидается» определено где-либо в стандарте. Однако здесь используется слово поток , а не файл / дескриптор файла, поэтому я бы прочитал это как режим FILE (как в режимах fopen) для потока stderr таков, что ни функции чтения, ни записи на нем не приводят к неопределенному поведению, пока соблюдаются правила переключения между ними. Без этого текста, например, без POSIX наверху, fgetc(stderr) потенциально может привести к неопределенному поведению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...