Главная » 2017 » Ноябрь » 24 » man 2 stat
05:33
man 2 stat

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; /* количество жёстких ссылок */
uid_t st_uid; /* идентификатор пользователя-владельца */
gid_t st_gid; /* идентификатор группы-владельца */

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
Метка времени последнего доступа к файлу.

st_mtime
информации, и может выполнить работу за 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 не является правильным открытым файловым дескриптором.

EFAULT Неправильный адрес.

ELOOP Во время определения пути встретилось слишком много символьных ссылок.

ENAMETOOLONG

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.

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

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;
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;
(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) Системные вызовы ядра (функции языка Си) | Просмотров: 680 | Добавил: Администратор | Рейтинг: 0.0/0
Всего комментариев: 0
avatar