Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Regla 0x4003h: Utilizá errno, perror y strerror para reportar fallos del sistema operativo de manera precisa

Archivos y E/S (0x40XX)

Universidad Nacional de Río Negro

0x4003h: Utilizá errno, perror y strerror para reportar fallos del sistema operativo de manera precisa

Enunciado normativo

DEBE reportarse todo fallo de E/S con un mensaje que incluya la causa informada por el sistema, usando errno, perror o strerror en lugar de un texto genérico.

Un mensaje que solo dice “Error” obliga a adivinar; el mensaje del sistema distingue “no existe” de “permiso denegado” de “demasiados archivos abiertos”.

¿Por qué existe esta regla?

El problema

La biblioteca C comunica la causa de los fallos del sistema operativo por una variable global, errno, declarada en <errno.h>. Cuando una llamada como fopen, fread o fwrite falla, el sistema operativo deposita allí un código entero (ENOENT, EACCES, EMFILE, etc.). Ese código no sirve de nada si el programa lo ignora y se limita a imprimir “no se pudo abrir”.

errno tiene dos propiedades que hay que respetar. Primero, solo es válido inmediatamente después de una llamada que falló: las funciones exitosas no lo limpian, así que mirarlo sin que hubo fallo puede reportar un error viejo. Segundo, cualquier otra llamada que falle puede sobreescribirlo: si entre el fallo y el reporte se invoca otra función, hay que guardar el valor antes.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Diagnóstico inútilEl usuario no puede distinguir un archivo ausente de uno sin permisos.
Depuración lentaEl equipo pierde tiempo reproduciendo fallos que el sistema ya describió.
Bug silenciosoUn errno consultado tarde reporta la causa de otra operación distinta.
Mala experienciaUn programa robusto parece roto cuando en realidad solo faltaba un permiso.

Fundamento en el estándar y en la cátedra

ISO/IEC 9899:2011 §7.5 declara errno como objeto modificable con alcance de hilo. §7.21.10.4 define perror, que imprime a stderr el mensaje asociado al errno actual precedido por el texto del llamador. §7.24.6.2 define strerror, que traduce un código a una cadena legible. La cátedra exige usarlos porque el diagnóstico preciso es parte de la robustez, no un adorno.

Alcance y excepciones

Aplica a todo reporte de fallo de E/S y de llamadas de biblioteca que informen por errno. No exige formato fijo: perror alcanza para mensajes simples y strerror permite componer mensajes con datos adicionales. Conviene enviar el diagnóstico a stderr, no a stdout, para no mezclarlo con la salida normal.

Ejemplos exhaustivos

❌ Contraejemplo 1 — Mensaje genérico sin causa del sistema

FILE *f = fopen("config.txt", "r");
if (f == NULL) {
    printf("No se pudo abrir el archivo\n");
}

Por qué falla: el programador y el usuario quedan sin saber si el archivo no existe, si falta permiso o si se agotaron los descriptores. La información ya estaba disponible en errno y se descartó.

❌ Contraejemplo 2 — Consultar errno después de otra llamada

FILE *f = fopen(ruta, "r");
if (f == NULL) {
    fclose(otro_flujo);
    fprintf(stderr, "%s\n", strerror(errno));
}

Por qué falla: fclose puede fallar y sobreescribir errno, de modo que el mensaje describe la segunda operación y no la apertura. Hay que copiar errno a una variable local antes de cualquier otra llamada.

✅ Ejemplo conforme 1 — perror inmediatamente después del fallo

#include <stdio.h>

FILE *f = fopen(ruta, "r");
if (f == NULL) {
    perror(ruta);
    return -1;
}

perror lee el errno vigente y escribe a stderr un mensaje del estilo archivo.txt: No such file or directory, con la causa exacta y sin código extra.

✅ Ejemplo conforme 2 — Guardar errno y componer con strerror

#include <errno.h>
#include <stdio.h>
#include <string.h>

FILE *f = fopen(ruta, "r");
if (f == NULL) {
    int motivo = errno;
    fprintf(stderr, "no se pudo abrir '%s': %s\n", ruta, strerror(motivo));
    return -1;
}

Copiar errno a motivo antes de otras llamadas preserva la causa, y strerror permite enriquecer el mensaje con la ruta y el contexto. Incluye las cabeceras correctas (ver 0x500Bh: Inclusión obligatoria de cabeceras estándar para funciones de la biblioteca C).

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cRegla 0x4003h: rama de error sin perror/strerror.
gccgcc -Wall -Wextra -std=c11 archivo.cSin señal directa; requiere revisión.
cppcheckcppcheck --enable=all archivo.cunreadVariable sobre errno o mensajes genéricos.

Checklist de autocontrol

Reglas relacionadas