Можно ли получить имя файла дескриптора файла (Linux) на C?
Можно ли получить имя файла дескриптора файла (Linux) на C?
Ответы:
Вы можете использовать readlinkна /proc/self/fd/NNNгде NNN является дескриптор файла. Это даст вам имя файла, которое было при его открытии - однако, если файл был перемещен или удален с тех пор, он может быть неточным (хотя Linux может отслеживать переименования в некоторых случаях). Чтобы проверить, statукажите имя файла и fstatимеющийся у вас fd и убедитесь, что st_devи st_inoсовпадают.
Конечно, не все файловые дескрипторы относятся к файлам, и для них вы увидите некоторые странные текстовые строки, например pipe:[1538488]. Поскольку все настоящие имена файлов будут абсолютными путями, вы можете легко определить, какие из них. Кроме того, как отмечали другие, файлы могут иметь несколько жестких ссылок, указывающих на них - это будет сообщать только о той, с которой он был открыт. Если вы хотите найти все имена для данного файла, вам просто нужно пройти через всю файловую систему.
fdтакой ссылкой будет открытый файл ), номер inode не может быть использован повторно. Любое программное обеспечение, использующее номер inode после закрытия файла или перед его открытием, по своей сути подвержено условиям гонки.
setuid()трюки, это /proc/self/fdможет быть недоступно для вашего процесса. См .: permalink.gmane.org/gmane.linux.kernel/1302546
У меня была эта проблема в 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 будет хорошо.
getsockname.
В Windows с GetFileInformationByHandleEx , передавая FileNameInfo , вы можете получить имя файла.
Как указывает Тайлер, невозможно сделать то, что вам нужно, «прямо и надежно», поскольку данный FD может соответствовать 0 имен файлов (в различных случаях) или> 1 (несколько «жестких ссылок» - это то, как обычно описывается последняя ситуация. ). Если вам все еще нужна функциональность со всеми ограничениями (по скорости И по возможности получения результатов 0, 2, ..., а не 1), вот как вы можете это сделать: во-первых, fstat FD - это говорит вам , в результате struct stat, на каком устройстве находится файл, сколько жестких ссылок у него есть, является ли он специальным файлом и т. д. Это может уже ответить на ваш вопрос - например, если 0 жестких ссылок, вы ЗНАЕТЕ, что на самом деле нет соответствующего имени файла на диске.
Если статистика вселяет надежду, то вам нужно «пройтись по дереву» каталогов на соответствующем устройстве, пока вы не найдете все жесткие ссылки (или только первую, если вам не нужно больше одной, и подойдет любая ). Для этой цели вы используете readdir (и, конечно, opendir & c), рекурсивно открывая подкаталоги до тех пор, пока вы не найдете в struct direntполученном таким образом том же индексном узле, который был у вас в оригинале struct stat(в этот момент, если вам нужен весь путь, а не только имя, вам нужно будет пройти по цепочке каталогов назад, чтобы восстановить ее).
Если этот общий подход приемлем, но вам нужен более подробный код на C, сообщите нам, его будет нетрудно написать (хотя я бы предпочел не писать его, если он бесполезен, т.е. вы не можете противостоять неизбежно низкой производительности или возможность получения! = 1 результата для вашего приложения ;-).
Прежде чем списать это на невозможное, предлагаю вам взглянуть на исходный код команды lsof .
Могут быть ограничения, но lsof, похоже, способен определять дескриптор файла и имя файла. Эта информация существует в файловой системе / proc, поэтому ее можно будет получить из вашей программы.
Вы можете использовать fstat (), чтобы получить индексный дескриптор файла с помощью struct stat. Затем, используя readdir (), вы можете сравнить найденный inode с теми, которые существуют (struct dirent) в каталоге (при условии, что вы знаете каталог, иначе вам придется искать по всей файловой системе) и найти соответствующее имя файла. Противно?
Невозможно. Файловый дескриптор может иметь несколько имен в файловой системе или вообще не иметь имени.
Изменить: предполагая, что вы говорите о простой старой системе POSIX без каких-либо API-интерфейсов, специфичных для ОС, поскольку вы не указали ОС.