Jump to content

stat (system call)

This is a fully translated article. Click here for more information.
From DawoumWiki, the free Mathematics self-learning

stat command line

stat()inode에 대한 파일 속성을 반환하는 유닉스 시스템 호출입니다. stat() 의 의미는 운영 시스템마다 다릅니다. 예제로서, 유닉스 명령 ls는 이 시스템 호출을 다음을 포함하는 파일에 대한 정보를 검색하기 위해 사용합니다:

  • atime: 마지막 접근 시간 (ls -lu)
  • mtime: 마지막 수정 시간 (ls -l)
  • ctime: 마지막 상태 변경 시간 (ls -lc)

stat버전 1 유닉스에 등장했습니다. 그것은 버전 4그룹 허가권의 추가 및 더 큰 파일 크기를 갖도록 변경하기 위한 몇 안 되는 원래 유닉스 시스템 호출 중 하나입니다.[1]

stat() functions

POSIX 및 다른 유닉스-계열 운영 시스템에서 발견되는, C POSIX 라이브러리 헤더 sys/stat.hstat() 함수와 마찬가지로 fstat()lstat()라고 불리는 관련된 함수를 선언합니다. 그 함수는 파일 속성을 반환하기 위해 사용되는 struct stat 버퍼 인수를 취합니다. 성공하면, 함수가 영을 반환하고, 오류가 발생하면 −1이 반환되고 errno가 적절하게 설정됩니다.

stat()lstat() 함수는 파일이름 인수를 취합니다. 만약 파일이 심볼릭 링크이면, stat()은 링크의 최종 대상의 속성을 반환하지만, lstat()는 링크 자체의 속성을 반환합니다. fstat() 함수는 대신 파일 설명자 인수를 취하고, 그것이 식별하는 파일의 속성을 반환합니다.

함수의 가족은 대용량 파일 지원을 구현하기 위해 확장되었습니다. stat64(), lstat64()fstat64()라고 이름-지은 함수는 64비트 유형을 갖는 파일 크기를 나타내는 struct stat64 구조에서 속성을 반환하며, 함수에게 2GiB 이상 (최대 8EiB) 파일에서 작동하는 것을 허용합니다. _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);

stat structure

이 구조는 다음과 같이 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;
	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_blocksst_blksize 구성원을 요구하지 않습니다; 이들 필드는 단일 유닉스 사양에서 XSI 옵션의 일부로 정의됩니다.

이전 버전의 POSIX.1 표준에서, 시간-관련된 필드는 st_atime, st_mtimest_ctime으로 정의되었고, time_t 유형이었습니다. 표준의 2008 버전 이후로, 이들 구조가 더 높은 분해능 시간 단위를 제공하기 때문에, 이들 필드는 struce timespec 유형의, 각각, st_atim, st_mtimst_ctim으로 다시 이름-지어졌습니다. 호환성을 위해, 구현은 struct timespectv_sec 구성원의 관점에서 이전 이름을 정의할 수 있습니다. 예를 들어, st_atimest_atim.tv_sec로 정의될 수 있습니다.[2]

struct stat 구조는 적어도 다음 구성원을 포함합니다:

  • st_dev – 파일을 포함하는 디바이스의 식별자
  • st_ino – inode 번호
  • st_mode – 보호 모드; 역시 유닉스 허가권을 참조하십시오.
  • st_nlink – 하드 링크참조 카운트
  • st_uid – 소유자의 사용자 식별자
  • st_gid – 소유자의 그룹 식별자
  • st_rdev – (특수 파일이면) 디바이스 식별자
  • st_size – 바이트에서, 전체 파일 크기
  • st_atime – 마지막 접근 시각
  • st_mtime – 마지막 수정 시각
  • st_ctime – 마지막 상태 변경 시각
  • st_blksize – 시스템과 파일 시스템 유형 둘 다에 의존하는 파일 시스템 I/O에 대해 선호된 블록 크기[3]
  • st_blocks – DEV_BSIZE의 배수에서 할당된 블록의 숫자 (보통 512 바이트).

st_mode 필드는 비트 필드입니다. 그것은 파일 접근 모드를 결합하고 임의의 특수 파일 유형도 나타냅니다. 다른 모드 플래그와 파일 유형과 함께 작동하는 많은 매크로가 있습니다.

Criticism of atime

파일을 읽는 것은 결국 디스크 쓰기를 요구하는 atime을 변경하며, 이것은 읽기 전용 파일 시스템과 일치하지 않는다는 비판을 받아왔습니다. 파일 시스템 캐시는 이 활동을 캐시 플러시당 하나의 디스크 쓰기로 상당히 줄일 수 있습니다.

리눅스 커널 개발자 Ingo Molnár는 2007년에 atime의 개념과 성능 영향을 공개적으로 비판했고,[4][5] 2009년에, relatime 마운트 옵션이 기본값이 되었으며, 이러한 비판을 해결했습니다.[6] relatime 마운트 옵션 뒤에 있는 동작은 대부분의 목적에 충분한 성능을 제공하고 광범위하게 논의된 것처럼 임의의 중요한 응용 프로그램을 중단시키지 않아야 합니다.[7] 처음에, relatime은 오직 atime < mtime 또는 atime < ctime이면 atime을 업데이트했습니다; tmpwatch와 데비안의 인기도 카운터 (popcon)가 제대로 작동하도록 24시간 이전의 atime을 업데이트하기 위해 이후에 수정되었습니다.[8]

현재 버전의 리눅스 커널은 fstab에서 지정될 수 있는 4가지 마운트 옵션을 지원합니다:

  • strictatime (공식적으로 atime, 및 공식적으로 기본값; 2.6.30부터 strictatime) – POSIX에 의해 정의된 행위를 준수하는 항상 atime를 업데이트
  • relatime ("상대적 atime", 2.6.20에서 소개되었고 2.6.30부터 기본값) – 특정 상황 아래에서 오직 atime을 업데이트: 만약 이전 atime이 mtime 또는 ctime보다 오래되었거나, 이전 atime이 과거 24시간 이상 지났으면
  • nodiratime – 디렉토리의 atime을 업데이트하지 말고, 다른 파일의 atime을 업데이트
  • noatime – 임의의 파일 또는 디렉토리의 atime을 업데이트하지 않습니다; nodiratime을 의미합니다; 최고 성능이지만 가장 낮은 호환성
  • lazytime – 아래에 명시된 특정 상황에 따른 atime을 업데이트

현재 버전의 리눅스, macOS, Solaris, FreeBSDNetBSD/etc/fstab에서 noatime 마운트 옵션을 지원하며, 이것은 atime 필드를 결코 업데이트되지 않는 원인이 됩니다. atime 업데이트를 끄면 POSIX 규정 준수와 mbox-기반 "새로운 메일" 알림,[9] 및 일부 파일 사용 감시 유틸리티, 특히 tmpwatch와 같은 일부 응용 프로그램을 깨뜨립니다.

OpenBSD에서 noatime 옵션은 리눅스 relatime과 비슷합니다.[10]

2015년 4월 12일에 출시된, 리눅스 커널 메인라인 버전 4.0은 새로운 마운트 옵션 lazytime을 도입했습니다. 그것은 POSIX-스타일의 atime 업데이트를 메모리 내에서 수행되고 같은 파일에서 시간과 관련되지 않은 일부 I/O 연산과 함께 디스크로 플러시되는 것을 허용니다; atime 업데이트는 역시 일부 sync 시스템 호출이 실행될 때, 또는 파일의 메모리 내 inode가 파일시스템 캐시에서 제거되기 전에 디스크로 플러시됩니다. 대안적으로, 수정 사항이 플러시되지 않은 상태로 유지될 수 있는 atime을 구성하는 것이 가능합니다. 그 방법, lazytime은 성능 향상을 제공하면서 POSIX 호환성을 유지합니다.[11][12]

ctime

ctime이 원래 생성 시간을 의미했다고 믿는 것이 유혹적입니다;[13] 어쨌든, 초기 유닉스는 수정 및 생성 시간을 가졌지만, 후자는 무엇이든 ctime을 호출하는 임의의 C 구조가 있기 전에 접근 시간으로 변경되었습니다. 파일 시스템은 유닉스 6판까지 접근 시간 (atime)과 수정 시간 (mtime)만 유지했다. ctime 타임스탬프는 유닉스 7판에서 발생된 파일 시스템 구조 조정에 추가되었고, 항상 inode 변경 시간을 참조했습니다. 파일 허가권, 파일 소유권, 및 하드 링크의 생성과 삭제와 같이 inode에 저장된 파일 메타데이터를 변경될 때마다 업데이트됩니다. 일부 구현에서, ctime은 파일 이름 변경에 영향을 받습니다; 링크를 만들고 (ctime을 업데이트) 이전 이름을 연결 해제 (다시 ctime을 업데이트)함으로써 이름 바꾸기를 구현했었던 원래 Unix와 최신 리눅스는 모두 이 작업을 수행하는 경향이 있습니다.

atimemtime과 달리, ctime은 예를 들어 touch 유틸리티에 의해 사용될 때, utime()과 함께 임의의 값으로 설정될 수 없습니다. 대신, utime()이 사용되거나, 파일 접근함으로써 인해 atime 업데이트 이외의 다른 inode에 대한 임의의 다른 변경에 대해, ctime 값이 현재 시간으로 설정됩니다.

Time granularity

  • time_t는 1초까지 정확한 시간을 제공합니다.
  • 일부 파일 시스템은 더 세밀한 단위를 제공합니다. Solaris 2.1은 1992년에 UFS와 함께 마이크로초 해상도와 ZFS를 사용한 나노초 해상도를 도입했습니다.[citation needed]
  • 리눅스 커널 2.5.48 이상에서, stat 구조는 3개의 파일 타임스탬프 필드에 대해 나노초 해상도를 지원합니다. 이것들은 stat 구조에서 추가 필드로 노출됩니다.[14][15]
  • FAT 파일 시스템에서 생성 시간의 분해능은 10ms이지만, 쓰기 시간의 분해능은 2초이고, 접근 시간은 하루의 분해능을 가고 따라서 그것은 접근 날짜로 작용합니다.[16]

Example

#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;
}

References

  1. ^ McIlroy, M. D. (1987). A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 (PDF) (Technical report). CSTR. Bell Labs. 139.
  2. ^ a b Stevens & Rago 2013, p. 94.
  3. ^ "<sys/stat.h>". The Open Group Base Specifications Issue 6—IEEE Std 1003.1, 2004 Edition. The Open Group. 2004.
  4. ^ Kernel Trap: Linux: Replacing atime With relatime, by Jeremy, August 7, 2007
  5. ^ Once upon atime, LWN, by Jonathan Corbet, August 8, 2007
  6. ^ Linux kernel 2.6.30, Linux Kernel Newbies
  7. ^ That massive filesystem thread, LWN, by Jonathan Corbet, March 31, 2009
  8. ^ Relatime Recap, Valerie Aurora
  9. ^ http://www.mail-archive.com/mutt-users@mutt.org/msg24912.html "the shell's $MAIL monitor ... depends on atime, pronouncing new email with atime($MAIL) < mtime($MAIL)"
  10. ^ "mount(2) - OpenBSD manual pages". openbsd.org. April 27, 2018. Retrieved September 26, 2018.
  11. ^ "Linux kernel 4.0, Section 1.5. 'lazytime' option for better update of file timestamps". kernelnewbies.org. May 1, 2015. Retrieved May 2, 2015.
  12. ^ Jonathan Corbet (November 19, 2014). "Introducing lazytime". LWN.net. Retrieved May 2, 2015.
  13. ^ https://www.bell-labs.com/usr/dmr/www/cacm.html
  14. ^ "stat(2) - Linux manual page". man7.org. Retrieved February 27, 2015.
  15. ^ Andreas Jaeger (December 2, 2002), struct stat.h with nanosecond resolution, mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.
  16. ^ MSDN: File Times

External links