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
ENOENT
open("$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
bash
e aguarde alguns minutos. Invoquels -l /proc/$$/fd
para 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 comstat
e 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.