- 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 |