Observando o código-fonte do mv, link :
/*
* If rename fails because we're trying to cross devices, and
* it's a regular file, do the copy internally; otherwise, use
* cp and rm.
*/
if (lstat(from, &sb)) {
warn("%s", from);
return (1);
}
return (S_ISREG(sb.st_mode) ?
fastcopy(from, to, &sb) : copy(from, to));
...
int
fastcopy(char *from, char *to, struct stat *sbp)
{
...
while ((to_fd =
open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)) < 0) {
if (errno == EEXIST && unlink(to) == 0)
continue;
warn("%s", to);
(void)close(from_fd);
return (1);
}
Na primeira passagem pelo loop while, open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)
falhará com EEXIST. Então, /dev/null
será desvinculado e o loop será repetido.
Mas como você apontou em seu comentário, arquivos regulares não podem ser criados em /dev
, então na próxima passagem pelo loop, open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)
ainda irá falhar.
Eu arquivaria um relatório de bug com a Apple. O código-fonte mv
está praticamente inalterado em relação à versão do FreeBSD, mas como o devfs do OSX tem esse comportamento não-POSIX com arquivos regulares, a Apple deve corrigir seu mv
.