O sshfs usa o protocolo de transferência de arquivos SSH (SFTP). A solução alternativa que você ativou está trabalhando em torno da semântica de uma operação rename () sobre esse protocolo quando o nome "novo" já existir.
O comportamento POSIX para rename () neste caso é remover o arquivo existente e concluir a renomeação.
No protocolo SFTP, você pode renomear um arquivo com a operação SSH_FXP_RENAME; no entanto, seu comportamento quando o nome de destino já existe parece depender da versão do protocolo que você está usando e quais sinalizadores você passa. A página da wikipedia para o protocolo SFTP possui links para vários RFCs de rascunho para várias versões do protocolo. Em Rascunho 00 , o comportamento é listado como:
It is an error if there already exists a file with the name specified by newpath.
Em Rascunho 13 , o comportamento é listado como
If flags does not include SSH_FXP_RENAME_OVERWRITE, and there already exists a file with the name specified by newpath, the server MUST respond with SSH_FX_FILE_ALREADY_EXISTS.
If flags includes SSH_FXP_RENAME_ATOMIC, and the destination file already exists, it is replaced in an atomic fashion. I.e., there is no observable instant in time where the name does not refer to either the old or the new file. SSH_FXP_RENAME_ATOMIC implies SSH_FXP_RENAME_OVERWRITE.
Para lidar com a possível falha de uma operação rename () quando o nome de destino existir, sshfs fornece a seguinte solução alternativa (se ativada) :
if (err == -EPERM && sshfs.rename_workaround) {
size_t tolen = strlen(to);
if (tolen + RENAME_TEMP_CHARS < PATH_MAX) {
int tmperr;
char totmp[PATH_MAX];
strcpy(totmp, to);
random_string(totmp + tolen, RENAME_TEMP_CHARS);
tmperr = sshfs_do_rename(to, totmp);
if (!tmperr) {
err = sshfs_do_rename(from, to);
if (!err)
err = sshfs_unlink(totmp);
else
sshfs_do_rename(totmp, to);
}
}
}
Neste código, "de" é o nome existente do arquivo que queremos renomear e "to" é o novo nome que queremos. Colocando parte do comprimento do caminho e da escrituração de erros de lado, esse trabalho gira em torno de
- Renomeia "para" para "totmp"
- Renomeia "de" para "para"
- Desvincula (exclui) "totmp"
Isso evita o conflito "arquivo já existe", mas também altera a semântica das operações rename (), e é por isso que você não deseja fazê-lo por padrão.