номер
Это не правда, что fstat
следует за символическими ссылками. Вместо этого open
следует за символическими ссылками. Как только вы доберетесь до fstat
, будет слишком поздно и информация исчезнет.
Скажите нам , почему вы должны знать, и мы можем помочь с этой проблемой. (Откройте другой вопрос.)
Как работают файлы:
Вот код псевдо-C / shell:
system("echo 'Hello, World!' >A.txt");
system("ln A.txt B.txt");
system("ln -s A.txt C.txt");
fdes = open("C.txt");
unlink("A.txt");
unlink("C.txt");
data = read(fdes);
write(stdout, data);
Результат: ваша программа печатает "Hello, world!"
. Состояние мира выглядит так:
+--Application--+ +--Kernel--+ +-------Disk-------+
| | | | | |
| fdes --------------> file ---------> inode #973 <-------+
| | | | | "Hello World!" | |
+---------------+ +----------+ | | |
| directory ---------+
| "B.txt" |
| |
+------------------+
Что касается ядра, файл открывается "inode # 973". Структура данных в памяти ядра имеет некоторую дополнительную информацию, такую как текущая позиция, но она НЕ знает путь. Ядро не должно знать эту информацию.
Если вы спросите ядро, каков путь, оно может сказать «у вас открыт B.txt». Но вы никогда не открывали «B.txt», вы открывали «C.txt», который был символической ссылкой на «A.txt», и «A.txt» и «C.txt» были удалены (они были просто именами для начать с).
Простая аналогия:
Вам позвонил старый друг. Он спрашивает: «Я посмотрел твой номер в телефонном справочнике, запомнил ли я, или мне нужно было попросить кого-нибудь узнать твой номер?»
У вас нет возможности узнать ответ. Все, что вы знаете, это кто на другом конце линии. Точно так же, как открытый файл не хранит информацию о том, как он был назван (жесткая ссылка или символическая ссылка), он просто содержит информацию о разрешениях и данных.
Решение: Просто используйте lstat
(да, есть условие гонки). Если вы не открыли файл самостоятельно (например, вы получили его из родительского процесса или через сокет), то более или менее невозможно узнать, был ли он открыт по символической ссылке.