O que acontece com um identificador de arquivo aberto no Linux se o arquivo apontado obtiver:
- Movido -> O identificador de arquivo permanece válido?
- Excluído -> Isso leva a um EBADF, indicando um identificador de arquivo inválido?
- Substituído por um novo arquivo -> O identificador de arquivo está apontando para este novo arquivo?
- Substituído por um link físico para um novo arquivo -> Meu arquivo "segue" este link?
- Substituído por um link simbólico para um novo arquivo -> Meu identificador de arquivo acessou este arquivo de link simbólico agora?
Por que estou fazendo essas perguntas: estou usando hardware hot-plugged (como dispositivos USB, etc.). Pode acontecer que o dispositivo (e também seu / dev / arquivo) seja reanexado pelo usuário ou outro Gremlin.
Qual é a melhor prática para lidar com isso?
Os identificadores de arquivo apontam para um inode e não para um caminho, portanto, a maioria dos seus cenários ainda funcionam como você supõe, pois o identificador ainda aponta para o arquivo.
Especificamente, com o cenário de exclusão - a função é chamada de "desvincular" por uma razão, ela destrói um "vínculo" entre um nome de arquivo (dentry) e um arquivo. Quando você abre um arquivo e, em seguida, desvincula-o, o arquivo realmente ainda existe até que sua contagem de referência chegue a zero, que é quando você fecha o identificador.
Editar: No caso de hardware, você abriu um identificador para um nó de dispositivo específico, se você desconectar o dispositivo, o kernel falhará em todos os acessos a ele, mesmo se o dispositivo voltar. Você terá que fechar o dispositivo e reabri-lo.
fonte
Não tenho certeza sobre as outras operações, mas quanto à exclusão: a exclusão simplesmente não ocorre (fisicamente, ou seja, no sistema de arquivos) até que o último identificador aberto para o arquivo seja fechado. Portanto, não deve ser possível excluir um arquivo do seu aplicativo.
Alguns aplicativos (que não vêm à mente) contam com esse comportamento, criando, abrindo e excluindo imediatamente arquivos, que duram exatamente o mesmo tempo que o aplicativo - permitindo que outros aplicativos estejam cientes do ciclo de vida do primeiro aplicativo sem precisar veja mapas de processos e outros.
É possível que considerações semelhantes se apliquem a outras coisas.
fonte
se você quiser verificar se o manipulador de arquivo (descritor de arquivo) está correto, você pode chamar esta função.
fonte
if(!fcntl(fd, F_GETFL)) {
verificação? Eu acho que você está procurando porEBADF
lá. (Você provavelmente também se esqueceu de inicializarerrno
em 0).open(O_WRONLY|O_APPEND)
- st_nlink sempre fica> = 1 enquanto meu descritor é aberto.As informações na memória de um arquivo excluído (todos os exemplos fornecidos são instâncias de um arquivo excluído), bem como os inodes no disco, permanecem até que o arquivo seja fechado.
Hardware sendo hotplug é uma questão completamente diferente, e você não deve esperar que o seu programa para se manter vivo por muito tempo se os inodes em disco ou metadados mudaram em tudo .
fonte
O seguinte experimento mostra que a resposta do MarkR está correta.
code.c:
dados:
Use
gcc code.c
para produzira.out
. Corra./a.out
. Quando você vê a seguinte saída:Use
rm data
para excluirdata
. Mas./a.out
continuará a ser executado sem erros e produzirá a seguinte saída completa:Eu fiz o experimento no Ubuntu 16.04.3.
fonte
No diretório / proc / você encontrará uma lista de todos os processos atualmente ativos, apenas encontre seu PID e todos os dados relacionados a ele. Uma informação interessante é a pasta fd /, você encontrará todos os gerenciadores de arquivos atualmente abertos pelo processo.
Eventualmente você encontrará um link simbólico para o seu dispositivo (em / dev / ou mesmo / proc / bus / usb /), se o dispositivo travar o link ficará inativo e será impossível atualizar este identificador, o processo deve ser fechado e abra-o novamente (mesmo com a reconexão)
Este código pode ler o status atual do link do seu PID
Este código final é simples, você pode brincar com a função linkat.
fonte