¿Qué sucede con un identificador de archivo abierto en Linux si, mientras tanto, el archivo señalado obtiene:
- Se mudó -> ¿El identificador del archivo sigue siendo válido?
- Eliminado -> ¿Esto conduce a un EBADF, lo que indica un identificador de archivo no válido?
- Reemplazado por un nuevo archivo -> ¿El archivo maneja que apunta a este nuevo archivo?
- Reemplazado por un enlace fijo a un nuevo archivo -> ¿Mi archivo maneja "seguir" este enlace?
- Reemplazado por un enlace suave a un nuevo archivo -> ¿Mi identificador de archivo llega a este archivo de enlace suave ahora?
Por qué hago estas preguntas: estoy usando hardware de conexión en caliente (como dispositivos USB, etc.). Puede suceder que el usuario u otro Gremlin vuelva a conectar el dispositivo (y también su archivo / dev /).
¿Cuál es la mejor práctica para lidiar con esto?
Los identificadores de archivo apuntan a un inodo, no a una ruta, por lo que la mayoría de sus escenarios aún funcionan como asume, ya que el identificador aún apunta al archivo.
Específicamente, con el escenario de eliminación, la función se llama "desvincular" por una razón, destruye un "vínculo" entre un nombre de archivo (un dentry) y un archivo. Cuando abre un archivo y luego lo desvincula, el archivo todavía existe hasta que su recuento de referencias llega a cero, que es cuando cierra el identificador.
Editar: En el caso del hardware, ha abierto un identificador para un nodo de dispositivo específico, si desconecta el dispositivo, el kernel fallará en todos los accesos, incluso si el dispositivo regresa. Deberá cerrar el dispositivo y volver a abrirlo.
fuente
No estoy seguro de las otras operaciones, pero en cuanto a la eliminación: la eliminación simplemente no se lleva a cabo (físicamente, es decir, en el sistema de archivos) hasta que se cierra el último identificador abierto del archivo. Por lo tanto, no debería ser posible eliminar un archivo debajo de su aplicación.
Algunas aplicaciones (que no me vienen a la mente) se basan en este comportamiento, al crear, abrir y eliminar inmediatamente archivos, que luego viven exactamente tanto como la aplicación, lo que permite que otras aplicaciones conozcan el ciclo de vida de la primera aplicación sin necesidad de hacerlo. mire mapas de procesos y demás.
Es posible que se apliquen consideraciones similares a las otras cosas.
fuente
si desea verificar si el controlador de archivos (descriptor de archivo) está bien, puede llamar a esta función.
fuente
if(!fcntl(fd, F_GETFL)) {
verificación? Supongo que estás buscandoEBADF
ahí. (Probablemente también olvidó inicializarerrno
a 0).open(O_WRONLY|O_APPEND)
- st_nlink siempre permanece> = 1 mientras mi descriptor está abierto.La información en la memoria de un archivo eliminado (todos los ejemplos que da son instancias de un archivo eliminado), así como los inodos en el disco permanecen hasta que se cierra el archivo.
El hardware que se conecta en caliente es un problema completamente diferente, y no debe esperar que su programa permanezca activo por mucho tiempo si los inodos o metadatos en el disco han cambiado en absoluto .
fuente
El siguiente experimento muestra que la respuesta de MarkR es correcta.
code.c:
datos:
Úselo
gcc code.c
para producira.out
. Corre./a.out
. Cuando vea el siguiente resultado:Use
rm data
para eliminardata
. Pero./a.out
continuará ejecutándose sin errores y producirá el siguiente resultado completo:Hice el experimento en Ubuntu 16.04.3.
fuente
En el directorio / proc / encontrará una lista de todos los procesos actualmente activos, solo busque su PID y todos los datos relacionados están allí. Una información interesante es la carpeta fd /, encontrará todos los controladores de archivos abiertos actualmente por el proceso.
Eventualmente encontrará un enlace simbólico a su dispositivo (bajo / dev / o incluso / proc / bus / usb /), si el dispositivo se cuelga, el enlace estará muerto y será imposible actualizar este identificador, el proceso debe cerrarse y ábralo de nuevo (incluso con la reconexión)
Este código puede leer el estado actual del enlace de su PID
Este código final es simple, puedes jugar con la función linkat.
fuente