Stat (системный вызов) - Stat (system call)

stat () это Unix системный вызов что возвращается атрибуты файла о индекс. Семантика stat () варьироваться между операционные системы. В качестве примера, Unix команда ls использует этот системный вызов для получения информации о файлах, которые включают:

  • atime: время последнего доступа (ls -lu)
  • mtime: время последней модификации (ls -l)
  • ctime: время последнего изменения статуса (ls -lc)

стат появился в Версия 1 Unix. Это один из немногих оригинальных Unix системные вызовы изменить, с Версия 4 добавление разрешения группы и больше размер файла.[1]

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 ЭиБ). Когда _FILE_OFFSET_BITS макрос определено как 64, эти 64-битные функции доступны под исходными именами.

Функции определены как:

int стат(const char *имя файла, структура стат *бух);int lstat(const char *имя файла, структура стат *бух);int fstat(int filedesc, структура стат *бух);

структура статистики

Эта структура определена в sys / stat.h заголовочный файл следующим образом, хотя реализации могут определять дополнительные поля:[2]

структура стат {	mode_t			st_mode;	Я не			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;	структура время	st_atim;	структура время	st_mtim;	структура время 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соответственно типа struct время, поскольку эта структура обеспечивает более высокое разрешение единицы времени. Для совместимости реализации могут определять старые имена в терминах tv_sec член struct timespec. Например, st_atime можно определить как st_atim.tv_sec.[2]

В struct stat В состав входят как минимум следующие члены:

В st_mode поле это битовое поле. Он сочетает в себе доступ к файлам режимы а также указывает на любые специальный тип файла. Есть много макросов для работы с разными флагами режима и типами файлов.

Критика времени

Чтение файла меняет его время в конечном итоге требуется диск записывать, который подвергся критике, поскольку он несовместим с файловой системой только для чтения. Кэш файловой системы может значительно сократить эту активность до одной записи на диск за очистку кеша.

Ядро Linux разработчик Инго Мольнар публично критиковал концепцию и влияние atime на производительность в 2007 году,[4][5] а в 2009 г. относительность Параметр mount стал параметром по умолчанию, который устраняет эту критику.[6] Поведение за относительность Параметр mount обеспечивает достаточную производительность для большинства целей и не должен нарушать работу каких-либо значительных приложений, поскольку он подробно обсуждался.[7] Первоначально, относительность обновляется только atime, если atime tmpwatch и счетчик популярности Debian (popcon) будет вести себя правильно.[8]

Текущие версии ядра Linux поддерживают четыре варианта монтирования, которые можно указать в fstab:

  • строгость (ранее время, и ранее по умолчанию; строгость с версии 2.6.30) - всегда обновлять время, которое соответствует поведению, определенному POSIX
  • относительность («относительное время», введенное в 2.6.20 и значение по умолчанию с 2.6.30) - обновлять время только при определенных обстоятельствах: если предыдущее время старше, чем mtime или ctime, или предыдущее время превышает 24 часа в прошлый
  • nodiratime - никогда не обновляйте время каталогов, но обновляйте время других файлов
  • noatime - никогда не обновляйте время любого файла или каталога; подразумевает nodiratime; высочайшая производительность, но наименее совместимая
  • Время лени - обновить время в соответствии с конкретными обстоятельствами, изложенными ниже

Текущие версии Linux, macOS, Солярис, FreeBSD, и NetBSD поддержать noatime вариант монтирования в / etc / fstab, что приводит к тому, что поле atime никогда не обновляется. Отключение перерывов на обновление времени POSIX соответствие, и некоторые приложения, такие как mbox -приводной "новый Почта "уведомления,[9] и некоторые утилиты для наблюдения за использованием файлов, в частности tmpwatch.

В noatime вариант на OpenBSD ведет себя больше как Linux относительность.[10]

Версия 4.0 Основная линия ядра Linux, выпущенный 12 апреля 2015 г., представил новую опцию крепления Время лени. Это позволяет выполнять обновления времени в стиле POSIX в памяти и сбрасывать на диск вместе с некоторыми операциями ввода-вывода, не связанными со временем, в том же файле; atime обновления также сбрасываются на диск, когда некоторые из синхронизировать системные вызовы выполняются или до того, как inode файла в памяти будет исключен из кеша файловой системы. Кроме того, можно настроить, как долго изменения могут оставаться не сброшенными. Таким образом, lazytime сохраняет совместимость с POSIX, предлагая при этом улучшения производительности.[11][12]

ctime

Заманчиво полагать, что ctime изначально означало время создания;[13] однако, в то время как ранний Unix имел время модификации и создания, последнее было изменено на время доступа до того, как появилась какая-либо структура C, в которой можно было бы вызывать что-либо ctime. Файловые системы сохранили только время доступа (время) и время модификации (время) через 6-ю редакцию Unix. В ctime временная метка была добавлена ​​при реструктуризации файловой системы, которая произошла в 7-й редакции Unix, и всегда относилась ко времени изменения inode. Он обновляется каждый раз при изменении метаданных файла, хранящихся в индексном дескрипторе, например права доступа к файлам, владение файлом, и создание и удаление жестких ссылок. В некоторых реализациях ctime зависит от переименования файла: оба оригинальных Unix, которые реализовали переименование, сделав ссылку (обновление ctime), а затем отключение старого имени (обновление ctime снова), и современные Linux склонны делать это.

В отличие от время и время, ctime не может быть установлено произвольное значение с помощью utime (), как используется трогать утилита, например. Вместо этого, когда utime () используется, или для любого другого изменения inode, кроме обновления время вызванный доступом к файлу, ctime значение установлено на текущее время.

Детализация по времени

  • time_t обеспечивает время с точностью до одной секунды.
  • Некоторые файловые системы обеспечивают более тонкую детализацию. Solaris 2.1 представил микросекундное разрешение с UFS в 1992 году.[нужна цитата ] и наносекундное разрешение с ZFS.[нужна цитата ]
  • В ядрах Linux 2.5.48 и выше структура stat поддерживает наносекундное разрешение для трех полей временных меток файла. Они отображаются как дополнительные поля в структуре статистики.[14][15]
  • Разрешение создания времени на Файловая система FAT составляет 10 миллисекунд, в то время как разрешение его времени записи составляет две секунды, а время доступа имеет разрешение одного дня, поэтому оно действует как дата доступа.[16]

Пример

#включают <stdio.h>#включают <stdlib.h>#включают <time.h>#включают <sys/types.h>#включают <pwd.h>#включают <grp.h>#включают <sys/stat.h>intглавный(int argc, char *argv[]){	структура стат сб;	структура пароль *pwuser;	структура группа *grpnam;	если (argc < 2)	{		fprintf(stderr, "Использование:% s: файл ... п", argv[0]);		выход(EXIT_FAILURE);	}	за (int я = 1; я < argc; я++)	{		если (-1 == стат(argv[я], &сб))		{			перрор("stat ()");			выход(EXIT_FAILURE);		}		если (НОЛЬ == (pwuser = getpwuid(сб.st_uid)))		{			перрор("getpwuid ()");			выход(EXIT_FAILURE);		}		если (НОЛЬ == (grpnam = Getgrgid(сб.st_gid)))		{			перрор("getgrgid ()");			выход(EXIT_FAILURE);		}		printf("% s: п", argv[я]);		printf(" тиндекс:% u п", сб.st_ino);		printf(" твладелец:% u (% s) п", сб.st_uid, pwuser->pw_name);		printf(" тгруппа:% u (% s) п", сб.st_gid, grpnam->gr_name);		printf(" тзавивка:% o п", сб.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));		printf(" тссылки:% d п", сб.st_nlink);		printf(" тразмер:% ld п", сб.st_size); / * вы можете использовать% lld * /		printf(" тatime:% s ", ctime(&сб.st_atim.tv_sec));		printf(" тmtime:% s ", ctime(&сб.st_mtim.tv_sec));		printf(" тctime:% s ", ctime(&сб.st_ctim.tv_sec));		printf(" п");	}	возвращаться 0;}

Рекомендации

  1. ^ Макилрой, М.Д. (1987). Читатель Research Unix: аннотированные выдержки из Руководства программиста, 1971–1986 (PDF) (Технический отчет). CSTR. Bell Labs. 139.
  2. ^ а б Стивенс и Раго 2013, п. 94.
  3. ^ "". Базовые спецификации Open Group, выпуск 6 - IEEE Std 1003.1, издание 2004 г.. Открытая группа. 2004 г.
  4. ^ Ловушка ядра: Linux: замена atime на relatime, Джереми, 7 августа 2007 г.
  5. ^ Давным-давно, LWN, Джонатан Корбет, 8 августа 2007 г.
  6. ^ Ядро Linux 2.6.30, Новички в ядре Linux
  7. ^ Этот массивный поток файловой системы, LWN, Джонатан Корбет, 31 марта 2009 г.
  8. ^ Обзор Relatime, Валери Аврора
  9. ^ http://www.mail-archive.com/mutt-users@mutt.org/msg24912.html "монитор $ MAIL оболочки ... зависит от времени, объявляет новое письмо с atime ($ MAIL)
  10. ^ "mount (2) - страницы руководства OpenBSD". openbsd.org. 27 апреля 2018 г.. Получено 26 сентября, 2018.
  11. ^ «Ядро Linux 4.0, раздел 1.5. Параметр 'lazytime' для лучшего обновления меток времени файлов». kernelnewbies.org. 1 мая 2015 г.. Получено 2 мая, 2015.
  12. ^ Джонатан Корбет (19 ноября 2014 г.). "Представляем ленивое время". LWN.net. Получено 2 мая, 2015.
  13. ^ https://www.bell-labs.com/usr/dmr/www/cacm.html
  14. ^ "stat (2) - страница руководства Linux". man7.org. Получено 27 февраля, 2015.
  15. ^ Андреас Джагер (2 декабря 2002 г.), struct stat.h с наносекундным разрешением, почтовый архив списка рассылки libc-alpha@sources.redhat.com для проекта glibc.
  16. ^ MSDN: время файлов

внешняя ссылка