Scroll to navigation

STAT(2) Руководство программиста Linux STAT(2)

ИМЯ

stat, fstat, lstat, fstatat - считывает состояние файла

СИНТАКСИС

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);
#include <fcntl.h>           /* определения констант AT_* */
#include <sys/stat.h>
int fstatat(int dirfd, const char *pathname, struct stat *statbuf,
            int flags);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

lstat():

/* glibc 2.19 and earlier */ _BSD_SOURCE
|| /* Since glibc 2.20 */ _DEFAULT_SOURCE
|| _XOPEN_SOURCE >= 500
|| /* Since glibc 2.10: */ _POSIX_C_SOURCE >= 200112L

fstatat():

Начиная с glibc 2.10:
_POSIX_C_SOURCE >= 200809L
До glibc 2.10:
_ATFILE_SOURCE

ОПИСАНИЕ

Данные системные вызовы возвращают информацию о файле в буфер, на который указывает statbuf. Для этого не требуется иметь права доступа к самому файлу, но — в случае stat(), fstatat() и lstat() — потребуются права выполнения (поиска) на все каталоги, указанные в полном имени файла pathname.

Вызовы stat() и fstatat() возвращают информацию о файле, указанном в pathname; различия с fstatat() описаны далее.

lstat() is identical to stat(), except that if pathname is a symbolic link, then it returns information about the link itself, not the file that the link refers to.

Вызов fstat() идентичен stat(), но опрашиваемый файл задаётся в виде файлового дескриптора fd.

Структура stat

Все эти системные вызовы возвращают структуру stat, которая содержит следующие поля:


struct stat {

dev_t st_dev; /* ID устройства с файлом */
ino_t st_ino; /* номер иноды */
mode_t st_mode; /* тип файла и режим доступа */
nlink_t st_nlink; /* количество жёстких ссылок */
uid_t st_uid; /* идентификатор пользователя-владельца */
gid_t st_gid; /* идентификатор группы-владельца */
dev_t st_rdev; /* идентификатор устройства
(для специального файла) */
off_t st_size; /* общий размер в байтах */
blksize_t st_blksize; /* размер блока ввода-вывода файловой системы */
blkcnt_t st_blocks; /* количество выделенных 512Б блоков */
/* Начиная с Linux 2.6, ядро поддерживает точность до
наносекунд в следующих полям меток времени.
Подробней о версиях до Linux 2.6, смотрите ЗАМЕЧАНИЯ. */
struct timespec st_atim; /* время последнего доступа */
struct timespec st_mtim; /* время последнего изменения */
struct timespec st_ctim; /* время последней смены состояния */ #define st_atime st_atim.tv_sec /* для обратной совместимости */ #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec };

Замечание: порядок полей структуры stat для разных архитектур отличается. Также, в определении выше не показаны дополняющие байты, которые для различных архитектур могут присутствовать между некоторыми полями Если необходимы подробности, то посмотрите исходный код glibc и ядра.

Замечание: Для простоты и производительности различные поля структуры stat могут содержать информацию о состоянии из разных моментов работы системного вызова. Например, если st_mode или st_uid изменились другим процессом с помощью вызова chmod(2) или chown(2), то stat() может вернуть старое значение st_mode вместе с новым st_uid, или старое значение st_uid вместе с новым st_mode.

Поля структуры stat:

Устройство, на котором расположен файл (для разбора идентификатора этого поля могут пригодиться макросы major(3) и minor(3)).
Номер иноды файла.
Тип файла и режим доступа. Дополнительную информацию смотрите в inode(7).
Количество жёстких ссылок на файл.
Пользовательский идентификатор владельца файла.
Групповой идентификатор владельца файла.
Устройство, который этот файл (инода) представляет.
Размер файла (если он обычный или является символьной ссылкой) в байтах. Размер символьной ссылки равен длине пути файла, на который она ссылается, без конечного нулевого байта.
«Предпочтительный» размер блока для эффективного ввода/вывода в файловой системе.
Количество блоков (по 512 байт), выделенных для файла (может быть меньше, чем st_size/512, когда в файле есть пропуски (holes)).
This is the time of the last access of file data.
This is the time of last modification of file data.
This is the file's last status change timestamp (time of last change to the inode).

Дополнительную информацию об этих полях смотрите в inode(7).

fstatat()

Системный вызов fstatat() представляет собой обобщённый интерфейс доступа к файловой информации, и может выполнить работу за stat(), lstat() и fstat().

Если в pathname задан относительный путь, то он считается относительно каталога, на который ссылается файловый дескриптор dirfd (а не относительно текущего рабочего каталога вызывающего процесса, как это делается в stat() и lstat()).

Если в pathname задан относительный путь и значение dirfd равно AT_FDCWD, то pathname рассматривается относительно текущего рабочего каталога вызывающего процесса (как stat() и lstat()).

Если в pathname задан абсолютный путь, то dirfd игнорируется.

Значение flags может быть 0, или включать один или более следующих флагов:

Если значение pathname равно пустой строке, то выполнять действие над файлом, на который указывает dirfd (который может быть получен с помощью open(2) с флагом O_PATH). В этом случае dirfd может указывать на файл любого типа, а не только на каталог и поведение fstatat() подобно fstat(). Если dirfd равно AT_FDCWD, то вызов выполняет действие над текущим рабочим каталогом. Этот флаг есть только в Linux; для получения его определения определите _GNU_SOURCE.
Don't automount the terminal ("basename") component of pathname if it is a directory that is an automount point. This allows the caller to gather attributes of an automount point (rather than the location it would mount). Since Linux 4.14, also don't instantiate a nonexistent name in an on-demand directory such as used for automounter indirect maps. This flag has no effect if the mount point has already been mounted over.
Both stat() and lstat() act as though AT_NO_AUTOMOUNT was set.
The AT_NO_AUTOMOUNT can be used in tools that scan directories to prevent mass-automounting of a directory of automount points.
Данный флаг существует только в Linux; для его получения определите _GNU_SOURCE.
Если значение pathname является символьной ссылкой, не разыменовывать её, а вернуть информацию о самой ссылке, как это делается в lstat(). (По умолчанию, fstatat() разыменовывает символьные ссылки как и stat().)

Смотрите в openat(2) объяснение необходимости fstatat().

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

ОШИБКИ

Запрещён поиск в одном из каталогов пути pathname (смотрите также path_resolution(7)).
Значение fd не является правильным открытым файловым дескриптором.
Неправильный адрес.
Во время определения пути встретилось слишком много символьных ссылок.
Слишком длинное значение аргумента pathname.
Компонент пути pathname не существует или является повисшей символьной ссылкой.
Значение pathname равно пустой строке и в flags не указано значение AT_EMPTY_PATH.
Не хватает памяти (например, памяти ядра).
Компонент в префиксе пути pathname не является каталогом.
Значение pathname или fd ссылаются на файл, чей размер, номер inode или количество блоков не может быть представлено с помощью типов off_t, ino_t или blkcnt_t, соответственно. Эта ошибка может возникнуть, если, например, приложение собрано на 32-битной платформе без флага -D_FILE_OFFSET_BITS=64 при вызове stat() для файла, чей размер превышает (1<<31)-1 байт.

В fstatat() дополнительно могут возникнуть следующие ошибки:

dirfd не является правильным файловым дескриптором.
Указано неверное значение в flags.
Значение pathname содержит относительный путь и dirfd содержит файловый дескриптор, указывающий на файл, а не на каталог.

ВЕРСИИ

Вызов fstatat() был добавлен в ядро Linux версии 2.6.16; поддержка в glibc доступна с версии 2.4.

СООТВЕТСТВИЕ СТАНДАРТАМ

stat(), fstat(), lstat(): SVr4, 4.3BSD, POSIX.1-2001, POSIX.1.2008.

fstatat(): POSIX.1-2008.

Согласно POSIX.1-2001, lstat() для символьной ссылки требует вернуть корректную информацию только в поле st_size и в типе файла в поле st_mode структуры stat. В POSIX.1-2008 более жёсткая спецификация, требующая, чтобы lstat() возвращал корректную информацию во всех полях кроме битов режима в st_mode.

Использование полей st_blocks и st_blksize может усложнить перенос на другие платформы. (Эти поля появились из BSD. Их смысл различается в разных системах и, вероятно, даже в одной системе при использовании NFS).

ЗАМЕЧАНИЯ

Поля с отметками времени

В старых ядрах и стандартах нет поддержки полей времени в наносекундах. Вместо них есть три поря времени — st_atime, st_mtime и st_ctime — с типом time_t, который имеет секундную точность.

Начиная с ядра 2.5.48, в структуре stat поддерживается наносекундная точность для всех трёх полей времени. Наносекундные компоненты каждой метки времени доступны под именами вида st_atim.tv_nsec, если определён подходящий макрос тестирования свойств. Наносекундные метки времени стандартизованы в POSIX.1-2008, и, начиная с версии 2.12, в glibc также есть поддержка имён наносекундных компонент, если определён _POSIX_C_SOURCE со значением 200809L или более, или _XOPEN_SOURCE со значением 700 или более. До glibc 2.19 включительно определения наносекундных компонент также доступны, если определён _BSD_SOURCE или _SVID_SOURCE. Если ни один из вышеупомянутых макросов не определён, то наносекундные значения доступны под именами вида st_atimensec.

Отличия между библиотекой C и ядром

В течении долгого времени увеличение размера структуры stat привело к появлению трёх новых версий stat(): sys_stat() (слот __NR_oldstat), sys_newstat() (слот __NR_stat) и sys_stat64() (слот __NR_stat64) на 32-битных платформах, например, i386. Первые две версии уже существовали в Linux 1.0 (но под другими именами); последняя была добавлена в Linux 2.4. Подобное замечание применимо к fstat() и lstat().

Внутренние ядерные структуры stat в разных версиях:

__old_kernel_stat
Самая первая версия структуры со слегка узкими полями и без заполнителей.
Увеличенное поле st_ino и добавлены заполнители в различные части структуры для расширения в дальнейшем.
Ещё раз увеличенное поле st_ino, увеличены поля st_uid и st_gid для работы с увеличенными в Linux-2.4 UID и GID до 32 бит, увеличены другие поля, дальнейшее добавление заполнителей в структуру (различные байты заполнения в дальнейшем были задействованы в Linux 2.6 с появлением 32-битных ID устройств и наносекундной части в полях временных отметок).

Обёрточная функция glibc stat() прячет эти подробности от приложений, вызывая самую новую версию системного вызова, предоставляемого ядром, и перепаковывая возвращаемую информацию, если это нужно для старых программ.

В современных 64-битных системах жизнь упростилась: единственный системный вызов stat() и ядро работает со структурой stat, в которой поля достаточного размера.

Нижележащий системный вызов, используемый обёрточной функцией fstatat() в glibc, на самом деле называется fstatat64() или, на некоторых архитектурах, newfstatat().

ПРИМЕРЫ

Следующая программа вызывает lstat() и показывает некоторые поля из полученной структуры stat.

#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysmacros.h>
int
main(int argc, char *argv[])
{

struct stat sb;
if (argc != 2) {
fprintf(stderr, "Использование: %s <путь>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (lstat(argv[1], &sb) == -1) {
perror("lstat");
exit(EXIT_FAILURE);
}
printf("ID содержащего устройства: [%jx,%jx]\n",
(uintmax_t) major(sb.st_dev),
(uintmax_t) minor(sb.st_dev));
printf("Тип файла: ");
switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("блочное устройство\n"); break;
case S_IFCHR: printf("символьное устройство\n"); break;
case S_IFDIR: printf("каталог\n"); break;
case S_IFIFO: printf("FIFO/канал\n"); break;
case S_IFLNK: printf("символьная ссылка\n"); break;
case S_IFREG: printf("обычный файл\n"); break;
case S_IFSOCK: printf("сокет\n"); break;
default: printf("неизвестно?\n"); break;
}
printf("номер inode: %ju\n", (uintmax_t) sb.st_ino);
printf("Режим доступа: %jo (octal)\n",
(uintmax_t) sb.st_mode);
printf("Link count: %ju\n", (uintmax_t) sb.st_nlink);
printf("Ownership: UID=%ju GID=%ju\n",
(uintmax_t) sb.st_uid, (uintmax_t) sb.st_gid);
printf("Preferred I/O block size: %jd bytes\n",
(intmax_t) sb.st_blksize);
printf("File size: %jd bytes\n",
(intmax_t) sb.st_size);
printf("Blocks allocated: %jd\n",
(intmax_t) sb.st_blocks);
printf("Посл. изм. состояния: %s", ctime(&sb.st_ctime));
printf("Посл. доступ к файлу: %s", ctime(&sb.st_atime));
printf("Посл. изм. файла: %s", ctime(&sb.st_mtime));
exit(EXIT_SUCCESS); }

СМ. ТАКЖЕ

ls(1), stat(1), access(2), chmod(2), chown(2), readlink(2), statx(2), utime(2), capabilities(7), inode(7), symlink(7)

ЗАМЕЧАНИЯ

Эта страница является частью проекта Linux man-pages версии 5.10. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Alexander Golubev <fatzer2@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Hotellook, Nikita <zxcvbnm3230@mail.ru>, Spiros Georgaras <sng@hellug.gr>, Vladislav <ivladislavefimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

13 августа 2020 г. Linux