Главная » 2017 » Ноябрь » 19 » man 2 fstat
22:08
man 2 fstat

SEO sprint - Всё для максимальной раскрутки!





ИМЯ


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 и старее */ _BSD_SOURCE
|| /* начиная с glibc 2.20 */ _DEFAULT_SOURCE
|| _XOPEN_SOURCE >= 500
|| /* начиная с 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() идентичен stat(), но в случае, если pathname является символьной
ссылкой, то возвращается информация о самой ссылке, а не о файле, на который она
указывает.

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

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

struct stat {
dev_t st_dev; /* ID устройства с файлом */
ino_t st_ino; /* номер иноды */
mode_t st_mode; /* тип файла и режим доступа */
nlink_t st_nlink; /* количество жёстких ссылок */
наносекунд в следующих полям меток времени.
Подробней о версиях до 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

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)
Не выполнять автоматическое монтирование конечного компонента («basename»)
pathname, если этот каталог является точкой автоматического монтирования.
Это позволяет вызывающему получить атрибуты точки автоматического
монтирования (а не расположения, где её предполагалось смонтировать).
Начиная с Linux 4.14, также не создаётся несуществующее имя в каталоге по
требованию, например в неявных картах автоматического монтировщика. Этот
флаг можно использовать в инструментах, сканирующих каталоги, для
предотвращения массового автоматического монтирования каталогов в их точки
автоматического монтирования. Флаг AT_NO_AUTOMOUNT не учитывается, если к
точке уже была выполнено монтирование. Этот флаг есть только Linux; для его
получения нужно задать _GNU_SOURCE. Вызовы stat() и lstat() работают, как
если бы был установлен флаг AT_NO_AUTOMOUNT.

AT_SYMLINK_NOFOLLOW
Если значение pathname является символьной ссылкой, не разыменовывать её, а
вернуть информацию о самой ссылке, как это делается в lstat(). (По
умолчанию, fstatat() разыменовывает символьные ссылки как и stat().)

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



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


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



ОШИБКИ


EACCES Запрещён поиск в одном из каталогов пути pathname (смотрите также
path_resolution(7)).

EBADF Значение fd не является правильным открытым файловым дескриптором.


ENOMEM Не хватает памяти (например, памяти ядра).

ENOTDIR
Компонент в префиксе пути pathname не является каталогом.

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

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

EBADF Значение dirfd не является правильным файловым дескриптором.

EINVAL Указано неверное значение в flags.

ENOTDIR
Значение 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.
Внутренние ядерные структуры 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 <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 содержащего устройства: [%lx,%lx]\n",
(long) major(sb.st_dev), (long) minor(sb.st_dev));

printf("Тип файла: ");

switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("блочное устройство\n"); break;
printf("номер inode: %ld\n", (long) sb.st_ino);

printf("Режим доступа: %lo (octal)\n",
(unsigned long) sb.st_mode);

printf("Кол-во ссылок: %ld\n", (long) sb.st_nlink);
printf("Владелец: UID=%ld GID=%ld\n",
(long) sb.st_uid, (long) sb.st_gid);

printf("Предпоч. размер бл. в/в: %ld байт\n",
(long) sb.st_blksize);
printf("Размер файла: %lld байт\n",
(long long) sb.st_size);
printf("Выделено блоков: %lld\n",
(long long) 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), utime(2),
capabilities(7), inode(7), symlink(7)



Категория: (2) Системные вызовы ядра (функции языка Си) | Просмотров: 629 | Добавил: Администратор | Рейтинг: 0.0/0
Всего комментариев: 0
avatar