Он может удалять файлы, но каталоги не являются «файлами».
➜ lab touch file
➜ lab mkdir dir
➜ lab ln -sfT /home file
➜ lab ln -sfT /home dir
ln: dir: cannot overwrite directory
Это видно в источнике :
if (remove_existing_files || interactive || backup_type != no_backups)
{
dest_lstat_ok = (lstat (dest, &dest_stats) == 0);
if (!dest_lstat_ok && errno != ENOENT)
{
error (0, errno, _("failed to access %s"), quoteaf (dest));
return false;
}
}
[...]
if (dest_lstat_ok)
{
if (S_ISDIR (dest_stats.st_mode))
{
error (0, 0, _("%s: cannot overwrite directory"), quotef (dest));
return false;
}
if (interactive)
{
fprintf (stderr, _("%s: replace %s? "), program_name, quoteaf (dest));
if (!yesno ())
return true;
remove_existing_files = true;
}
dest_lstat_ok
логическое значение, которое начинается как false, становится истинным, первый оператор if вызывается , поскольку remove_existing_files
истинно из-за флага - force
, который, в свою очередь, позволяет проверить второй оператор if. Он отказывается удалять каталоги, потому что ожидает файл .
Если вы не установите -T
, что заставляет ln не обрабатывать каталог как не каталог , ln просто создаст символическую ссылку под каталог с базовым именем источник.
Причина в том, что ttyname (3)
не является системным вызовом , это функция библиотеки C. Вы можете ознакомиться с его реализацией, например . в glibc
, чтобы увидеть, какие системные вызовы он использует сам (и это вы затем увидите в выводе strace
).
Для отслеживания вызовов библиотеки в Linux можно использовать ltrace (который также может отслеживать системные вызовы). (Спасибо Marki555 за предложение.)