stat (системный вызов) - stat (system call)
stat () - это системный вызов Unix, который возвращает атрибуты файла для индексного дескриптора . Семантика stat () различается в зависимости от операционной системы . Например,команда ls в Unix использует этот системный вызов для получения информации о файлах, которая включает:
- atime: время последнего доступа ( ls -lu )
- mtime: время последней модификации ( ls -l )
- ctime: время последнего изменения статуса ( ls -lc )
stat
появился в версии 1 Unix . Это один из немногих оригинальных системных вызовов Unix, которые необходимо изменить, с добавлением в Версии 4 групповых разрешений и большего размера файла .
stat () функции
Библиотека C POSIX заголовок SYS / stat.h , найденный на POSIX и других Unix-подобных операционных систем, объявляет stat()
функции, а также связанные с ними функции , вызываемые fstat()
и lstat()
. Функции принимают struct stat
аргумент буфера, который используется для возврата атрибутов файла. В случае успеха функции возвращают ноль, а в случае ошибки возвращается -1, а значение errno устанавливается соответствующим образом.
Функции stat()
и lstat()
принимают аргумент имени файла . Если файл является символической ссылкой , stat()
возвращает атрибуты конечной цели ссылки, а lstat()
возвращает атрибуты самой ссылки. fstat()
Функция принимает дескриптор файла аргумент вместо этого, и возвращает атрибуты файла , который он идентифицирует.
Семейство функций было расширено для реализации поддержки больших файлов . Функции по имени stat64()
, lstat64()
и fstat64()
возвращаемые атрибутов в struct stat64
структуре, которая представляет размер файла с типом 64-битным, позволяя функции для работы с файлами 2 Гб и больше (до 8 EIB). Когда _FILE_OFFSET_BITS
макрос определен как 64, эти 64-битные функции доступны под исходными именами.
Функции определены как:
int stat(const char *filename, struct stat *buf);
int lstat(const char *filename, struct stat *buf);
int fstat(int filedesc, struct stat *buf);
структура статистики
Эта структура определена в заголовочном файле sys / stat.h следующим образом, хотя реализации могут определять дополнительные поля:
struct stat {
mode_t st_mode;
ino_t st_ino;
dev_t st_dev;
dev_t st_rdev;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
off_t st_size;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
blksize_t st_blksize;
blkcnt_t st_blocks;
};
POSIX.1 не требует st_rdev
, st_blocks
и st_blksize
членов; эти поля определены как часть опции XSI в спецификации Single Unix.
В более старых версиях стандарта POSIX.1 поля, связанные со временем, определялись как st_atime
, st_mtime
и st_ctime
, и имели тип time_t
. С версией стандарта 2008, эти поля были переименованы в st_atim
, st_mtim
и st_ctim
, соответственно, типе структуры timespec
, так как эта структура обеспечивает более высокое разрешение единицу времени. Для совместимости реализации могут определять старые имена в терминах tv_sec
члена struct timespec
. Например, st_atime
можно определить как st_atim.tv_sec
.
В struct stat
состав входят как минимум следующие члены:
-
st_dev
- идентификатор устройства, содержащего файл -
st_ino
- номер inode -
st_mode
- режим защиты ; см. также разрешения Unix -
st_nlink
- количество ссылок на жестких ссылок -
st_uid
- идентификатор пользователя владельца -
st_gid
- групповой идентификатор владельца -
st_rdev
- идентификатор устройства (если специальный файл ) -
st_size
- общий размер файла в байтах -
st_atime
- время последнего доступа -
st_mtime
- время последней модификации -
st_ctime
- время последнего изменения статуса -
st_blksize
- предпочтительный размер блока для ввода-вывода файловой системы, который может зависеть как от системы, так и от типа файловой системы -
st_blocks
- количество выделенных блоков кратноDEV_BSIZE
(обычно 512 байт).
st_mode
Поле представляет собой битовое поле . Он сочетает в себе режимы доступа к файлам, а также указывает любой специальный тип файла . Есть много макросов для работы с разными флагами режима и типами файлов.
Критика времени
Чтение файла изменяет его Atime в конечном счете требуя диск запись, которая подвергается критике , поскольку это не согласуется с только для чтения файловой системы. Кэш файловой системы может значительно сократить эту активность до одной записи на диск за очистку кеша.
Разработчик ядра Linux Инго Мольнар публично раскритиковал концепцию и влияние atime на производительность в 2007 году, а в 2009 году опция монтирования relatime стала по умолчанию, что устраняет эту критику. Поведение, стоящее за опцией монтирования relatime, обеспечивает достаточную производительность для большинства целей и не должно нарушать работу каких-либо значительных приложений, как это подробно обсуждалось. Изначально relatime обновлял atime , только если atime <mtime или atime <ctime; который впоследствии был изменен для обновления времени, которое было 24 часа или старше, чтобы tmpwatch и счетчик популярности Debian (popcon) работали должным образом.
Текущие версии ядра Linux поддерживают четыре варианта монтирования, которые можно указать в fstab :
- strictatime (ранее atime , а ранее по умолчанию; strictatime с 2.6.30) - всегда обновлять время, которое соответствует поведению, определенному POSIX
- relatime («относительное время», введенное в 2.6.20 и значение по умолчанию с 2.6.30) - обновлять время только при определенных обстоятельствах: если предыдущее время старше, чем mtime или ctime, или предыдущее время превышает 24 часа в прошлое
- nodiratime - никогда не обновлять время каталогов, но обновлять время других файлов
- noatime - никогда не обновлять время любого файла или каталога; подразумевает nodiratime ; высочайшая производительность, но наименее совместимая
- lazytime - обновить время в соответствии с конкретными обстоятельствами, изложенными ниже
Текущие версии Linux , macOS , Solaris , FreeBSD и NetBSD поддерживают параметр монтирования noatime в / etc / fstab , из-за которого поле atime никогда не обновляется. Отключение обновления atime нарушает соответствие POSIX и некоторые приложения, такие как mbox- управляемые уведомления о «новой почте » и некоторые утилиты для отслеживания использования файлов, в частности tmpwatch .
Параметр noatime в OpenBSD больше похож на Linux relatime .
Версия 4.0 основной ветки ядра Linux , выпущенная 12 апреля 2015 года, представила новую опцию монтирования lazytime . Он позволяет выполнять обновления времени в стиле POSIX в памяти и сбрасывать на диск вместе с некоторыми операциями ввода-вывода, не связанными со временем, в том же файле; Временные обновления также сбрасываются на диск при выполнении некоторых системных вызовов синхронизации или до того, как индексный дескриптор файла в памяти будет удален из кеша файловой системы. Кроме того, можно настроить, в течение какого времени изменения могут оставаться незаброшенными. Таким образом, lazytime сохраняет совместимость с POSIX, предлагая при этом улучшения производительности.
ctime
Заманчиво полагать, что ctime изначально означало время создания; однако, в то время как ранние версии Unix имели время модификации и создания, последнее было изменено на время доступа до того, как появилась какая-либо структура C, в которой можно было бы вызвать ctime . Файловые системы сохранили только время доступа ( atime ) и время модификации ( mtime ) до 6-й редакции Unix. CTime метка времени была добавлена в реструктуризации файловой системы , который произошел с 7 - е издание Unix, и всегда называют время изменения инода. Он обновляется любое время файла метаданные , хранящиеся в изменении индексных дескрипторов, такие как права доступа к файлам , права собственности файлов и создание и удаление жестких ссылок . В некоторых реализациях на ctime влияет переименование файла: как в оригинальном Unix, в котором переименование реализовано путем создания ссылки (обновление ctime ) и последующего отключения старого имени ( повторное обновление ctime ), так и в современном Linux, как правило, это делают.
В отличие от atime и mtime , ctime не может быть установлено произвольное значение с помощью utime () , как, например, используется утилитой touch . Вместо этого, когда используется utime () или для любого другого изменения inode, кроме обновления atime, вызванного доступом к файлу, значение ctime устанавливается на текущее время.
Детализация по времени
- time_t показывает время с точностью до одной секунды.
- Некоторые файловые системы обеспечивают более тонкую детализацию. Solaris 2.1 представил микросекундное разрешение с UFS в 1992 году и наносекундное разрешение с ZFS.
- В ядрах Linux 2.5.48 и выше структура stat поддерживает наносекундное разрешение для трех полей метки времени файла. Они отображаются как дополнительные поля в структуре статистики.
- Разрешение времени создания в файловой системе FAT составляет 10 миллисекунд, в то время как разрешение времени записи составляет две секунды, а время доступа имеет разрешение один день, поэтому оно действует как дата доступа.
Пример
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <sys/stat.h>
int
main(int argc, char *argv[])
{
struct stat sb;
struct passwd *pwuser;
struct group *grpnam;
if (argc < 2)
{
fprintf(stderr, "Usage: %s: file ...\n", argv[0]);
exit(EXIT_FAILURE);
}
for (int i = 1; i < argc; i++)
{
if (-1 == stat(argv[i], &sb))
{
perror("stat()");
exit(EXIT_FAILURE);
}
if (NULL == (pwuser = getpwuid(sb.st_uid)))
{
perror("getpwuid()");
exit(EXIT_FAILURE);
}
if (NULL == (grpnam = getgrgid(sb.st_gid)))
{
perror("getgrgid()");
exit(EXIT_FAILURE);
}
printf("%s:\n", argv[i]);
printf("\tinode: %u\n", sb.st_ino);
printf("\towner: %u (%s)\n", sb.st_uid, pwuser->pw_name);
printf("\tgroup: %u (%s)\n", sb.st_gid, grpnam->gr_name);
printf("\tperms: %o\n", sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
printf("\tlinks: %d\n", sb.st_nlink);
printf("\tsize: %ld\n", sb.st_size); /* you may use %lld */
printf("\tatime: %s", ctime(&sb.st_atim.tv_sec));
printf("\tmtime: %s", ctime(&sb.st_mtim.tv_sec));
printf("\tctime: %s", ctime(&sb.st_ctim.tv_sec));
printf("\n");
}
return 0;
}
Рекомендации
- IEEE Std 1003.1, 2004, документация для fstat (2) . Проверено 7 июня 2012.
- stat (2) Справочная страница Linux . Проверено 7 июня 2012.
- У. Ричард, Стивенс; Стивен А., Раго (24 мая 2013 г.). Расширенное программирование в среде UNIX (Третье изд.). Эддисон-Уэсли Профессионал . ISBN 978-0321637734. Проверено 27 февраля 2015 года .