¿Cómo cerrar un archivo?

Me sentí en paz con Posix después de muchos años de experiencia.

Entonces leiesta mensaje de Linus Torvalds, circa 2002:

int ret;
do {
    ret = close(fd);
} while(ret == -1 && errno != EBADF);

NO.

Lo anterior es

(a) no portátil

(b) no es una práctica actual

La parte "no portátil" proviene del hecho de que (como alguien señaló), un entorno roscado en el que el núcleohace cierre el FD en caso de errores, el FD puede haber sido reutilizado válidamente (por el núcleo) para algún otro hilo, y cerrar el FD por segunda vez es un ERROR.

No solo se repite hastaEBADF inportable, pero cualquier bucle es, debido a una condición de carrera que probablemente habría notado si no hubiera "hecho las paces" al dar por sentado tales cosas.

Sin embargo, en la implementación de la biblioteca estándar GCC C ++,basic_file_stdio.cc, tenemos

    do
      __err = fclose(_M_cfile);
    while (__err && errno == EINTR);

El objetivo principal de esta biblioteca es Linux, pero parece no estar prestando atención a Linus.

Por lo que he llegado a entender,EINTR sucede solo después de una llamada al sistemabloques, lo que implica que el kernel recibió la solicitud para liberar el descriptor antes de comenzar cualquier trabajo que se interrumpiera. Entonces no hay necesidad de hacer un bucle. De hecho, elSA_RESTART el comportamiento de la señal no se aplica aclose y genera dicho bucle por defecto, precisamente porque no es seguro.

Este es un error de biblioteca estándar, ¿verdad? En cada archivo cerrado por una aplicación C ++.

EDITAR: Para evitar causar demasiada alarma antes de que algún gurú llegue con una respuesta, debo tener en cuenta queclose solo parece estar permitido bloquear bajo circunstancias específicas, tal vez ninguna de las cuales se aplique a archivos normales. No tengo claros todos los detalles, pero no deberías verEINTR declose sin optar por algo porfcntl osetsockopt. Sin embargo, la posibilidad hace que el código genérico de la biblioteca sea más peligroso.

Respuestas a la pregunta(1)

Su respuesta a la pregunta