Se o alvo for excluído, uma entidade em /proc/$PID/fd/ aparece como um link simbólico quebrado quando você usa ls(1) ou file(1) , mas na verdade age de forma diferente quando é aberto com open(2) .
No meu Debian 9 eu usei strace(1) para ver o que acontece quando tento ler um symlink. O comando é sudo strace cat "$symlink" . A linha relevante do stderr é
-
ou OK
open("$symlink", O_RDONLY) = 3 -
ou
ENOENTopen("$symlink", O_RDONLY) = -1 ENOENT (No such file or directory)
(nota: não estou dizendo que todos esses são resultados possíveis de open(2) em geral).
Os resultados:
| regular symlink | /proc/$PID/fd/$N |
---------------+-----------------+------------------+
exists, valid | OK | OK |
exists, broken | ENOENT | OK | <- the difference
doesn't exist | ENOENT | ENOENT |
---------------+-----------------+------------------+
Eu também aprendi que quando eu executo file "$symlink" , ele chama lstat(2) , readlink(2) e stat(2) . Essas são chamadas de sistema que se baseiam em caminhos, não em descritores de arquivos. Se o symlink existir (válido ou quebrado), open(2) nunca é chamado para abri-lo ou seu destino. ENOENT de stat(2) indica que o link está quebrado.
Minha conclusão é: "link quebrado" é uma propriedade derivada da saída de algumas chamadas do sistema; mas quando você abre um link de /proc/$PID/fd/ , open(2) apenas sabe o que fazer com ele e não se importa com o que outras ferramentas produziriam.
Observe que todo o /proc falsifica apenas um sistema de arquivos "normal". Algumas peculiaridades:
- Os arquivos podem ter conteúdo dinâmico, mas não estão sendo modificados com as chamadas do sistema (tente
inotifywait). - Os objetos podem (dis) aparecer, mas não estão sendo criados nem excluídos com as chamadas do sistema (novamente
inotifywait). - Em algum sentido, os objetos podem não existir até você interagir com eles. Execute
bashe aguarde alguns minutos. Invoquels -l /proc/$$/fdpara ver seus descritores de arquivos. Provavelmente ctimes mostrará "neste exato momento". No entanto, se você repetir o comando a cada poucos segundos, perceberá que os ctimes nunca mudam. (Curiosidades: no começo eu pensei que poderia responder a essa pergunta Determine por quanto tempo um arquivo foi aberto comstate links simbólicos em/proc/$PID/fd/, mas eu estava errado; agora você sabe o porquê).
/proc inteiro foi projetado para se comportar de maneira um pouco diferente. Eu suponho open(2) foi deliberadamente dada a capacidade de tirar proveito disso.