Получить имя файла из файлового дескриптора в C

StackOverflow https://stackoverflow.com/questions/1188757

  •  19-09-2019
  •  | 
  •  

Вопрос

Можно ли получить имя файла дескриптора файла (Linux) в C?

Это было полезно?

Решение

Вы можете использовать readlink на /proc/self/fd/NNN где NNN — дескриптор файла.Это даст вам имя файла в том виде, в каком оно было при его открытии, однако, если с тех пор файл был перемещен или удален, оно может быть неточным (хотя в некоторых случаях Linux может отслеживать переименования).Проверять, stat указанное имя файла и fstat тот fd, который у вас есть, и убедитесь, что st_dev и st_ino одинаковы.

Конечно, не все файловые дескрипторы относятся к файлам, и для них вы увидите странные текстовые строки, например: pipe:[1538488].Поскольку все настоящие имена файлов будут абсолютными путями, вы можете достаточно легко определить, какие из них являются.Кроме того, как отмечали другие, файлы могут иметь несколько жестких ссылок, указывающих на них - будет сообщаться только о той, с помощью которой они были открыты.Если вы хотите найти все имена для данного файла, вам просто нужно обойти всю файловую систему.

Другие советы

У меня была эта проблема в Mac OS X.У нас нет /proc виртуальная файловая система, поэтому принятое решение не может работать.

Вместо этого у нас есть F_GETPATH команда для fcntl:

 F_GETPATH          Get the path of the file descriptor Fildes.  The argu-
                    ment must be a buffer of size MAXPATHLEN or greater.

Итак, чтобы получить файл, связанный с файловым дескриптором, вы можете использовать этот фрагмент:

#include <sys/syslimits.h>
#include <fcntl.h>

char filePath[PATH_MAX];
if (fcntl(fd, F_GETPATH, filePath) != -1)
{
    // do something with the file path
}

Поскольку я никогда не помню, где MAXPATHLEN определено, я думал PATH_MAX из syslimits было бы хорошо.

В Windows с GetFileInformationByHandleEx, проходя ИмяФайлаИнформация, вы можете получить имя файла.

Как отмечает Тайлер, невозможно сделать то, что вам нужно, «напрямую и надежно», поскольку данный FD может соответствовать 0 именам файлов (в различных случаях) или > 1 (несколько «жестких ссылок» — это то, как обычно описывается последняя ситуация). ).Если вам все же нужен функционал со всеми ограничениями (по скорости И по возможности получить 0, 2,...результаты, а не 1), вот как это можно сделать:первый, фстат FD – это говорит вам о том, что в результате struct stat, на каком устройстве находится файл, сколько у него жестких ссылок, является ли это специальным файлом и т. д.Возможно, это уже ответ на ваш вопрос, например.если 0 жестких ссылок, вы ЗНАЕТЕ, что на диске фактически нет соответствующего имени файла.

Если статистика дает вам надежду, то вам придется «пройтись по дереву» каталогов на соответствующем устройстве, пока не найдете все жесткие ссылки (или только первую, если вам не нужно больше одной и подойдет любая). ).Для этой цели вы используете каталог чтения (и, конечно, opendir и т. д.), рекурсивно открывая подкаталоги, пока не найдете struct dirent таким образом получили тот же номер индексного дескриптора, который был у вас в оригинале struct stat (в этот момент, если вам нужен весь путь, а не только имя, вам нужно будет пройти по цепочке каталогов назад, чтобы восстановить его).

Если такой общий подход приемлем, но вам нужен более подробный код на С, сообщите нам, его не составит труда написать (хотя я бы предпочел не писать его, если он бесполезен, т.е.вы не можете выдержать неизбежно низкую производительность или возможность получения != 1 результата для целей вашего приложения ;-).

Прежде чем списывать это как невозможное, я предлагаю вам взглянуть на исходный код лсоф команда.

Могут быть ограничения, но lsof, похоже, способен определить дескриптор файла и имя файла.Эта информация существует в файловой системе /proc, поэтому к ней можно получить доступ из вашей программы.

Вы можете использовать fstat(), чтобы получить индексный дескриптор файла с помощью структуры stat.Затем, используя readdir(), вы можете сравнить найденный индексный дескриптор с теми, которые существуют (struct dirent) в каталоге (при условии, что вы знаете каталог, иначе вам придется искать по всей файловой системе) и найти соответствующее имя файла.Противный?

Невозможный.Дескриптор файла может иметь несколько имен в файловой системе или вообще не иметь имени.

Редактировать:Предполагая, что вы говорите о старой простой системе POSIX без каких-либо API-интерфейсов, специфичных для ОС, поскольку вы не указали ОС.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top