O sshfs usa o protocolo SFTP (SSH File Transfer Protocol). A solução alternativa que você ativou está contornando a semântica de uma operação rename () sobre esse protocolo quando o nome "novo" já existir.
O comportamento do POSIX para renomear () 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 do destino já existe parece depender da versão do protocolo que você está usando e dos sinalizadores que você passa. A página da wikipedia para o protocolo SFTP possui links para vários rascunhos de RFCs para várias versões do protocolo. No rascunho 00, o comportamento é listado como:
É um erro se já existir um arquivo com o nome especificado por newpath.
No rascunho 13 , o comportamento é listado como
Se os sinalizadores não incluem SSH_FXP_RENAME_OVERWRITE, e já existe um arquivo com o nome especificado por newpath, o servidor DEVE responder com SSH_FX_FILE_ALREADY_EXISTS.
Se os sinalizadores incluírem SSH_FXP_RENAME_ATOMIC e o arquivo de destino já existir, ele será substituído de maneira atômica. Ou seja, não há um instante observável no tempo em que o nome não se refira ao arquivo antigo ou ao novo. SSH_FXP_RENAME_ATOMIC implica SSH_FXP_RENAME_OVERWRITE.
Para lidar com a possível falha de uma operação rename () quando o nome do destino existe, o 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);
}
}
}
Nesse código "from" é o nome existente do arquivo que queremos renomear e "to" é o novo nome que queremos. Deixando de lado algum comprimento do caminho e a contabilização de erros, esta solução
- Renomeia "para" para "totmp"
- Renomeia "de" para "para"
- Desvincula (exclui) "totmp"
Isso evita o conflito "o 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.