¿Es fgets () devuelve NULL con un búfer corto compatible?

En la unidad que prueba una función que contienefgets(), se encontró con un resultado inesperado cuando el tamaño del búfern < 2. Obviamente, un tamaño de búfer de este tipo es una tontería, pero la prueba está explorando casos de esquina.

Código simplificado

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

Lo sorprendente es quefgets() devolucionesNULL yninguno feof() niferror() son1.

La especificación C, a continuación, parece silenciosa en este caso raro.

Preguntas:

Esta volviendoNULL sin establecerfeof() niferror() comportamiento conforme?¿Podría un resultado diferente ser un comportamiento conforme?¿Hay alguna diferencia sin es 1 o menos de 1?

Plataforma: gcc versión 4.5.3 Objetivo: i686-pc-cygwin

Aquí hay un resumen del Estándar C11, algo de énfasis mío:

7.21.7.2 Elfgets función

losfgets la función lee como máximo uno menos que el número de caracteres especificado porn [...]

losfgets la función vuelves si tiene éxito. Si se encuentra el final del archivoy no se han leído caracteres en la matriz, el contenido de la matriz permanece sin cambios y se devuelve un puntero nulo. Si se produce un error de lectura durante la operación, el contenido de la matriz es indeterminado y se devuelve un puntero nulo.

Publicaciones relacionadas
Cómo usar feof y ferror para fgets (minishell en C)
Problemas para crear un shell en C (Seg-Fault y ferror)
fputs (), fgets (), preguntas de ferror () y equivalentes de C ++
Valor de retorno de fgets ()

[Editar] Comentarios sobre respuestas

@Shafik Yaghmour presentó bien el problema general: dado que la especificación C no menciona qué hacer cuando no leealguna datos ni escrituraalguna datos as cuando (n <= 0), es un comportamiento indefinido. Por lo tanto, cualquier respuesta razonable debe ser aceptable, como la devoluciónNULL, no establezca banderas, deje el búfer solo.

En cuanto a lo que debería suceder cuandon==1, La respuesta de @Oliver Matthews y el comentario de @Matt McNabb indican la falta de claridad de una especificación C considerando un amortiguador den == 1. La especificación Cparece para favorecer un búfer den == 1 debería devolver el puntero del búfer cons[0] == '\0', pero no es lo suficientemente explícito.

Respuestas a la pregunta(3)

Su respuesta a la pregunta