Fgets () возвращает NULL с коротким буфером, совместимым?

В модульном тестировании функция, содержащаяfgets()наткнулся на неожиданный результат при размере буфераn < 2, Очевидно, что такой размер буфера глуп, но тест исследует угловые случаи.

Упрощенный код:

#include <error.h>
#include <stdio.h>

void test_fgets(char * restrict s, int n) {
  FILE *stream = stdin;
  s[0] = 42;
  printf("< s:%p n:%d stream:%p\n", s, n, stream);
  char *retval = fgets(s, n, stream);
  printf("> errno:%d feof:%d ferror:%d retval:%p s[0]:%d\n\n",
    errno, feof(stream), ferror(stream), retval, s[0]);
}

int main(void) {
  char s[100];
  test_fgets(s, sizeof s);  // Entered "123\n" and works as expected
  test_fgets(s, 1);         // fgets() --> NULL, feof() --> 0, ferror() --> 0
  test_fgets(s, 0);         // Same as above
  return 0;
}

Что удивительно в том, чтоfgets() возвращаетсяNULL а такжени feof() ниferror() являются1.

Спецификация C, ниже, кажется, молчит об этом редком случае.

Вопросы:

ВозвращаетсяNULL без настройкиfeof() ниferror() уступчивое поведение?Может ли другой результат быть совместимым поведением?Имеет ли это значение, еслиn равно 1 или меньше 1?

Платформа: gcc версия 4.5.3 Цель: i686-pc-cygwin

Вот выдержка из Стандарта C11, некоторые акценты мои:

7.21.7.2fgets функция

fgets функция читает не более, чем на число символов, указанноеn [...]

fgets функция возвращаетs если успешно. Если обнаружен конец файлаа также в массив не было прочитано ни одного символа, содержимое массива остается неизменным и возвращается нулевой указатель. Если во время операции возникает ошибка чтения, содержимое массива неопределенное и возвращается нулевой указатель.

Связанные сообщения
Как использовать feof и ferror для fgets (мини-оболочка в C)
Проблема создания оболочки в C (Seg-Fault и ferror)
fputs (), fgets (), ferror () вопросы и эквиваленты C ++
Возвращаемое значение fgets ()

[Редактировать] Комментарии к ответам

@Shafik Yaghmour хорошо представил общую проблему: поскольку в спецификации C не упоминается, что делать, когда он не читаетлюбой данные ни писатьлюбой данные дляs когда (n <= 0), это неопределенное поведение. Таким образом, любой разумный ответ должен быть приемлемым, например, возвратNULL, не устанавливайте флаги, оставляйте буфер в покое.

Что должно произойти, когдаn==1, Ответ @Oliver Matthews и комментарий @Matt McNabb указывают на недостаточную ясность спецификации C с учетом буфераn == 1, Спецификация Cкажется в пользу буфераn == 1 должен вернуть указатель буфера сs[0] == '\0', но не достаточно явно.

Ответы на вопрос(3)

Ваш ответ на вопрос