stringtranslate.com

стат (системный вызов)

statкомандная строка

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

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

функции стат()

Заголовок библиотеки C POSIX sys/stat.h , найденный в POSIX и других Unix-подобных операционных системах, объявляет функции, а также связанные функции, называемые и . Функции принимают аргумент буфера, который используется для возврата атрибутов файла. В случае успеха функции возвращают ноль, а в случае ошибки возвращается −1, и errno устанавливается соответствующим образом.stat()fstat()lstat()struct stat

Функции stat()и lstat()принимают аргумент имени файла . Если файл является символической ссылкой , stat()возвращает атрибуты конечной цели ссылки, а также lstat()атрибуты самой ссылки. Вместо этого fstat()функция принимает аргумент дескриптора файла и возвращает атрибуты файла, который она идентифицирует.

Семейство функций было расширено для реализации поддержки больших файлов . Функции с именем stat64()и lstat64()возвращают fstat64()атрибуты в struct stat64структуре, которая представляет размеры файлов 64-битного типа, что позволяет функциям работать с файлами размером 2 ГиБ и больше (до 8 EiB). Если _FILE_OFFSET_BITS макросу присвоен номер 64, эти 64-битные функции доступны под исходными именами.

Функции определяются как:

int stat ( const char * имя файла , struct stat * buf ); int lstat ( const char * имя файла , struct stat * buf ); int fstat ( int filedesc , struct stat * buf );                 

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

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

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 ; структура timespec st_atim ; структура timespec st_mtim ; структура timespec st_ctim ; blksize_t st_blksize ; blkcnt_t st_blocks ; };      

POSIX.1 не требует st_rdev, st_blocksи st_blksizeчленов; эти поля определены как часть опции XSI в Единой спецификации Unix.

В старых версиях стандарта POSIX.1 поля, связанные со временем, определялись как st_atime, st_mtimeи st_ctime, и имели тип time_t. Начиная с версии стандарта 2008 года, эти поля были переименованы в st_atimи st_mtimсоответственно st_ctimтипа struct timespec, поскольку эта структура обеспечивает единицу времени с более высоким разрешением. В целях совместимости реализации могут определять старые имена в терминах tv_secчлена struct timespec. Например, st_atimeможно определить как st_atim.tv_sec. [2]

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

Поле st_modeпредставляет собой битовое поле . Он объединяет режимы доступа к файлам , а также указывает любой специальный тип файла . Существует множество макросов для работы с различными флагами режимов и типами файлов.

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

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

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

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

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

Опция noatime в OpenBSD больше похожа на relatime в Linux . [10]

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

ctime

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

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

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

Пример

#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 []) {   структура стат сб ; структура passwd * pwuser ; структурная группа * grpnam ;      if ( argc < 2 ) { fprintf ( stderr , "Использование: %s: файл ... \n " , argv [ 0 ]); выход ( EXIT_FAILURE ); }     for ( int i = 1 ; i < argc ; i ++ ) { if ( -1 == stat ( argv [ i ], & sb )) { perror ( "stat()" ); выход ( EXIT_FAILURE ); }            if ( NULL == ( pwuser = getpwuid ( sb . st_uid ))) { perror ( "getpwuid()" ); выход ( EXIT_FAILURE ); }     if ( NULL == ( grpnam = getgrgid ( sb . st_gid ))) { perror ( "getgrgid()" ); выход ( EXIT_FAILURE ); }     printf ( "%s: \n " , argv [ i ]); printf ( " \t inode: %u \ n " , sb.st_ino ) ; printf ( " \t владелец: %u (%s) \n " , sb . st_uid , pwuser -> pw_name ); printf ( " \t группа: %u (%s) \n " , sb . st_gid , grpnam -> gr_name ); printf ( " \t perms: %o \n " , sb . st_mode & ( S_IRWXU | S_IRWXG | S_IRWXO )); printf ( " \ t ссылки: %d \n " , sb.st_nlink ) ; printf ( " \t size: %ld \ n " , sb.st_size ) ; /* вы можете использовать %lld */ printf ( " \t atime: %s" , ctime ( & sb . st_atim . tv_sec )); printf ( " \t mtime: %s" , ctime ( & sb . st_mtim . tv_sec )); printf ( " \t ctime: %s" , ctime ( & sb . st_ctim . tv_sec ));                   printf ( " \n " ); }вернуть 0 ; } 

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

  1. ^ Макилрой, доктор медицины (1987). Читатель Research Unix: аннотированные выдержки из Руководства программиста, 1971–1986 (PDF) (Технический отчет). CSTR. Лаборатории Белла. 139.
  2. ^ ab Stevens & Rago 2013, стр. 94.
  3. ^ "<sys/stat.h>". Базовые спецификации открытой группы, выпуск 6 — стандарт IEEE 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/[email protected]/msg24912.html "монитор оболочки $MAIL... зависит от atime, произнося новое электронное письмо с помощью atime($MAIL) < mtime($ ПОЧТА)"
  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. ^ "Версия BSTJ документа C.ACM Unix" .
  14. ^ «Пиши, пиши - пиши в файл» . После успешного завершения, если nbyte больше 0, write() помечает для обновления метки времени последней модификации данных и последнего изменения статуса файла.
  15. ^ «stat(2) — страница руководства Linux». man7.org . Проверено 27 февраля 2015 г.
  16. ^ Андреас Йегер (2 декабря 2002 г.), структура stat.h с наносекундным разрешением, почтовый архив списка рассылки [email protected] для проекта glibc.
  17. ^ MSDN: Время файлов

Внешние ссылки