Является ли close / fclose на stdin правильным? - PullRequest
6 голосов
/ 13 ноября 2008

Кажется, что следующие вызовы делают то, что вы ожидаете (закройте поток и не допускать дальнейшего ввода - все, что ожидает ввода в потоке, возвращает ошибку), но гарантированно будет ли оно корректным для всех компиляторов / платформ

close(fileno(stdin));
fclose(stdin);

Ответы [ 3 ]

20 голосов
/ 08 мая 2011

fclose(stdin) вызывает дальнейшее использование stdin (явное или неявное) для вызова неопределенного поведения, что является очень плохой вещью . Он не «запрещает ввод».

close(fileno(stdin)) вызывает любые дальнейшие попытки ввода с stdin после того, как текущий буфер был исчерпан, с ошибкой EBADF, но только до тех пор, пока вы не откроете другой файл, в этом случае этот файл станет fd # 0 и произойдут плохие вещи .

Более надежный подход может быть:

int fd = open("/dev/null", O_WRONLY);
dup2(fd, 0);
close(fd);

с несколькими добавленными проверками ошибок. Это гарантирует, что все чтения (после того, как текущий буфер истощится) приведут к ошибкам. Если вы просто хотите, чтобы они приводили к EOF, а не к ошибке, используйте O_RDONLY вместо O_WRONLY.

14 голосов
/ 13 ноября 2008

НЕ ЗАКРЫВАЙТЕ ФИЛЬНО (ФАЙЛ *). ФАЙЛ является буферным объектом. Изучение его реализации и вмешательство в его состояние сопряжено со всеми предостережениями и опасностями, которые могут возникнуть при аналогичном поведении в любом другом программном модуле.

Не делай этого.

AGH. Шутки в сторону. Противный.

3 голосов
/ 13 ноября 2008

Ничто не гарантируется правильно во всех возможных операционных системах. Тем не менее, вызов fclose (stdin) будет работать в любой POSIX-совместимой операционной системе, а также в операционных системах Windows, поэтому в настоящий момент вы должны использовать практически все, что обычно используется.

Как указано в предыдущем ответе и моем комментарии, нет необходимости вызывать close для дескриптора файла. fclose () правильно закроет все для вас.

...