Você está confuso. rmdir
simplesmente não se importa com as contagens de links. A lógica é bastante simples.
Quando um arquivo tiver uma contagem de links de 0 e, além disso, nenhum processo em execução com uma referência (descritor de arquivo ou diretório atual), ele será realmente excluído. Esse é o ponto em que o espaço em disco pode ser reutilizado para outra coisa [*].
Diretórios são um arquivo. Mas desvincular (removê-los de seus pais) requer mais consideração do que outros tipos de arquivos. Devemos nos certificar de que cada filho do diretório também esteja desvinculado. Caso contrário, poderíamos perder a chance de atualizar a contagem de links das crianças. Nós perderíamos esse espaço em disco permanentemente.
Portanto, não permitimos que os usuários chamem unlink
em um diretório. Em vez disso, eles devem usar a finalidade especial rmdir
. Chamar rmdir
difere de unlink
em apenas duas maneiras
- Exige que o diretório esteja "vazio", o que significa que seus únicos filhos são as entradas padrão
.
e..
. - Certifica-se de desvincular essas duas entradas restantes, antes de executar
unlink
no próprio diretório.
Isso é . Não há outra mágica. rmdir
não é adiada até que a condição no ponto 1 seja válida. rmdir
tem sucesso ou falha no momento em que é chamado. Nem a condição é baseada na contagem de links de qualquer forma.
Acho interessante o efeito da entrada .
na contagem de links, mesmo que não seja um caso especial. É um link rígido para o diretório pai e, portanto, aumenta a contagem de links. Esta é a explicação de por que um DIR de diretório recém-criado tem uma contagem de links de 2. Se você chamar rmdir DIR
, a contagem de links retornará para 0, pois removerá os dois links DIR/.
e DIR
.
O Linux na verdade permite que você observe o acima executando um shell dentro do diretório e executando ls -ld
após o diretório ter sido desvinculado (removido de seu pai).
É claro que ls -ld
é uma abreviação de ls -ld .
. .
e ..
continuam trabalhando mesmo depois que a entrada de diretório é removida; na verdade, o Linux moderno não depende realmente dessas entradas de diretório em disco. Espero que a implementação original do Unix não suporte isso. No entanto, acredito que as contagens de referência ainda funcionavam conforme descrito acima e não possuíam um caso especial para a remoção de um diretório.
(Como ..
continua a funcionar é ainda mais interessante. Discutido no comentário abaixo).
Na verdade, seria muito fácil olhar o código original do Unix para rmdir
. Foi implementado como um programa do usuário executado com privilégios especiais . Código unix histórico é fácil de encontrar online. É uma das razões pelas quais estou tão confiante sobre isso.
[*] Assim, você pode ver se um arquivo foi excluído procurando uma diferença nos blocos de disco usados em df .
(ou i-nodes em df -i .
). Essa abordagem funciona muito bem em sistemas de arquivos como o Linux ext4
. Sistemas de arquivos menos tradicionais podem ter otimizações mais complexas, o que pode dificultar a observação.