- bullseye-backports 4.18.0-1~bpo11+1
 - testing 4.18.0-1
 - unstable 4.18.0-1
 
| 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);
lstat():
|| /* 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:
- st_dev
 - Устройство, на котором расположен файл (для разбора идентификатора этого поля могут пригодиться макросы major(3) и minor(3)).
 - st_ino
 - Номер иноды файла.
 - st_mode
 - Тип файла и режим доступа. Дополнительную информацию смотрите в inode(7).
 - st_nlink
 - Количество жёстких ссылок на файл.
 - st_uid
 - Пользовательский идентификатор владельца файла.
 - st_gid
 - Групповой идентификатор владельца файла.
 - st_rdev
 - Устройство, который этот файл (инода) представляет.
 - st_size
 - Размер файла (если он обычный или является символьной ссылкой) в байтах. Размер символьной ссылки равен длине пути файла, на который она ссылается, без конечного нулевого байта.
 - st_blksize
 - «Предпочтительный» размер блока для эффективного ввода/вывода в файловой системе.
 - st_blocks
 - Количество блоков (по 512 байт), выделенных для файла (может быть меньше, чем st_size/512, когда в файле есть пропуски (holes)).
 - st_atime
 - This is the time of the last access of file data.
 - st_mtime
 - This is the time of last modification of file data.
 - st_ctime
 - 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, или включать один или более следующих флагов:
- AT_EMPTY_PATH (начиная с Linux 2.6.39)
 - Если значение pathname равно пустой строке, то выполнять действие над файлом, на который указывает dirfd (который может быть получен с помощью open(2) с флагом O_PATH). В этом случае dirfd может указывать на файл любого типа, а не только на каталог и поведение fstatat() подобно fstat(). Если dirfd равно AT_FDCWD, то вызов выполняет действие над текущим рабочим каталогом. Этот флаг есть только в Linux; для получения его определения определите _GNU_SOURCE.
 - AT_NO_AUTOMOUNT (начиная с Linux 2.6.38)
 - 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.
 
- AT_SYMLINK_NOFOLLOW
 - Если значение pathname является символьной ссылкой, не разыменовывать её, а вернуть информацию о самой ссылке, как это делается в lstat(). (По умолчанию, fstatat() разыменовывает символьные ссылки как и stat().)
 
Смотрите в openat(2) объяснение необходимости fstatat().
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.
ОШИБКИ¶
- EACCES
 - Запрещён поиск в одном из каталогов пути pathname (смотрите также path_resolution(7)).
 - EBADF
 - Значение fd не является правильным открытым файловым дескриптором.
 - EFAULT
 - Неправильный адрес.
 - ELOOP
 - Во время определения пути встретилось слишком много символьных ссылок.
 - ENAMETOOLONG
 - Слишком длинное значение аргумента pathname.
 - ENOENT
 - Компонент пути pathname не существует или является повисшей символьной ссылкой.
 - ENOENT
 - Значение pathname равно пустой строке и в flags не указано значение AT_EMPTY_PATH.
 - ENOMEM
 - Не хватает памяти (например, памяти ядра).
 - ENOTDIR
 - Компонент в префиксе пути pathname не является каталогом.
 - EOVERFLOW
 - Значение pathname или fd ссылаются на файл, чей размер, номер inode или количество блоков не может быть представлено с помощью типов off_t, ino_t или blkcnt_t, соответственно. Эта ошибка может возникнуть, если, например, приложение собрано на 32-битной платформе без флага -D_FILE_OFFSET_BITS=64 при вызове stat() для файла, чей размер превышает (1<<31)-1 байт.
 
В fstatat() дополнительно могут возникнуть следующие ошибки:
ВЕРСИИ¶
Вызов 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
 - Самая первая версия структуры со слегка узкими полями и без заполнителей.
 - stat
 - Увеличенное поле st_ino и добавлены заполнители в различные части структуры для расширения в дальнейшем.
 - stat64
 - Ещё раз увеличенное поле 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 |