반응형
stat(2)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
파일의 크기, 파일의 권한, 파일의 생성일시, 파일의 최종 변경일 등, 파일의 상태나 파일의 정보를 얻는 함수입니다. stat(2) 함수는 symbolic link인 파일을 path로 넘기면 그 원본 파일의 정보를 얻습니다. lstat(2)함수는 symbolic link 파일 자신의 정보를 얻습니다. 나머지 기능은 stat(2)와 lstat(2)는 같습니다.
이 함수는 우리가 가장 많이 사용하는 명령어 중의 하나인 ls -al 명령어로 알 수 있는 내용들을 대부분 알 수 있습니다. stat(1) 명령어도 이 stat(2)와 비슷한 내용을 알 수 있습니다.
UNIX/LINX에서 manual을 보기 위해서는 man 2 stat 이라고 해야 stat(1)이 아닌 stat(2)함수를 볼 수 있습니다.
파라미터
path
- 파일 명 또는 파일에 대한 상대 경로 또는 절대경로
buf
- 파일의 상태 및 정보를 저장할 buf 구조체
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* 파일의 종류 및 접근권한 */
nlink_t st_nlink; /* hardlink 된 횟수 */
uid_t st_uid; /* 파일의 owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* 파일의 크기(bytes) */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
이 중에서 주요 내용을 보면,
st_mode : 파일의 종류와 file에 대한 access 권한 정보
파일의 종류 체크하는 POSIX macro입니다.
S_ISREG(buf.st_mode) : 일반 파일 여부
S_ISDIR(buf.st_mode) : 디렉토리 여부
S_ISCHR(buf.st_mode) : character device 여부
S_ISBLK(buf.st_mode) : block device 여부
S_ISFIFO(buf.st_mode) : FIFO 여부
S_ISLNK(buf.st_mode) : symbolic link 여부
S_ISSOCK(buf.st_mode) : socket 여부 (주로 AF_UNIX로 socket 생성된 경우)
st_mode는 파일의 유형값으로 직접 bit & 연산으로 여부를 확인가능합니다.
S_IFMT 0170000 파일 유형의 전체의 bit or 값
/* 파일 유형 */
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
/* 특수 권한 설정 bit */
S_ISUID 0004000 set-user-ID bit
S_ISGID 0002000 set-group-ID bit
S_ISVTX 0001000 sticky bit
접근 권한 값(chmod의 값과 같음)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
st_atime, st_mtime, st_ctime member 변수는 time관련 함수(time.h)를 이용하여 conversion후에
사용하면 쉽게 사용할 수 있습니다. localtime(3), ctime(3) 등
RETURN
0
- 정상적으로 파일의 정보를 조회하였습니다.
-1
- 오류가 발생하였으며, 상세한 오류내용은 errno 전역변수에 설정되었습니다.
EACCES : path를 구성하는 directory중에서 search 권한(x)이 없어서 접근할 수 없습니다.
EFAULT : path 변수 자체가 잘못된 주소입니다.
ELOOP : 너무 많은 symbolic link로 directory가 loop에 빠졌습니다.
ENAMETOOLONG : path가 너무 길거나 이름이 너무 깁니다.
ENOENT : path가 빈 문자열이거나 path를 구성하는 directory중에서 없는 directory가 있습니다.
ENOMEM : 메모리가 부족합니다.
ENOTDIR: path를 구성하는 directory중에서 directory가 아닌 것이 있습니다.
EOVERFLOW : 32bit OS에서 컴파일시에 -D_FILE_OFFSET_BITS=64 옵션없이 컴파일하여
파일크기나 inode번호가 64bit에 맞지 않은 경우
활용 예제
Sample
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
int main(int argc, char *argv[])
{
struct stat sb;
if (argc != 2) {
fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
return 1;
}
if (stat(argv[1], &sb) == -1) {
perror("stat");
return 1;
}
printf("File type: ");
switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n"); break;
case S_IFCHR: printf("character device\n"); break;
case S_IFDIR: printf("directory\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFLNK: printf("symlink\n"); break;
case S_IFREG: printf("regular file\n"); break;
case S_IFSOCK: printf("socket\n"); break;
default: printf("unknown?\n"); break;
}
printf("I-node number: %ld\n", (long) sb.st_ino);
printf("Mode: %lo (octal)\n", (unsigned long) sb.st_mode);
printf("Link count: %ld\n", (long) sb.st_nlink);
printf("Ownership: UID=%ld GID=%ld\n", (long) sb.st_uid, (long) sb.st_gid);
printf("Preferred I/O block size: %ld bytes\n", (long) sb.st_blksize);
printf("File size: %lld bytes\n", (long long) sb.st_size);
printf("Blocks allocated: %lld\n", (long long) sb.st_blocks);
printf("Last status change: %s", ctime(&sb.st_ctime));
printf("Last file access: %s", ctime(&sb.st_atime));
printf("Last file modification: %s", ctime(&sb.st_mtime));
return 0;
}
=================================================================================
실행:
$ ./sample sample.c
결과:
File type: regular file
I-node number: 421032
Mode: 100664 (octal)
Link count: 1
Ownership: UID=1000 GID=1000
Preferred I/O block size: 4096 bytes
File size: 1611 bytes
Blocks allocated: 8
Last status change: Sat Nov 5 18:07:33 2016
Last file access: Sat Nov 5 18:07:38 2016
Last file modification: Sat Nov 5 18:07:33 2016
반응형
'C언어 header > unistd.h' 카테고리의 다른 글
sync(2) - 전체 kernel buffer를 동기화 하기 (0) | 2019.10.01 |
---|---|
symlink(2) - 새로운 symbolic link 생성 (0) | 2019.10.01 |
sleep(3) - 설정된 초(second) 동안 대기 (0) | 2019.10.01 |
readlink(2) - symbolic link 값을 읽는 함수 (0) | 2019.10.01 |
pwrite(2) - 지정된 위치에 파일 쓰기 (0) | 2019.10.01 |