-
C/C++ stat(2), lstat(2), fstat(2)C,C++ & Linux 2020. 5. 17. 00:43728x90
stat 함수 기능
지정한 파일의 정보를 담고 있는 stat 구조체를 얻어주는 시스템 함수입니다.
stat(2)
파일을 filepath 로 지정합니다.
fstat(2)
파일을 fd 넘버로 지정합니다.
lstat(2)
파일을 filepath 로 지정하되 지정된 파일이 심볼릭 링크 파일이면 링크파일 자체에 대한 정보를 얻습니다.
stat(2) 함수로 심볼릭 링크 파일을 지정하게되면 링크파일이 가리키는 파일에 대한 정보를 얻습니다.
stat구조체
struct stat {
dev_t st_dev; // 디바이스 번호
ino_t st_ino; // inode 번호
mode_t st_mode; // 모드 (접근권한)
nlink_t st_nlink; // 하드링크 수
uid_t st_uid; // 소유자의 사용자 아이디
gid_t st_gid; // 소유자의 그룹 아이디
dev_t st_rdev; // 디바이스 아이디 (특수 파일인 경우)
off_t st_size; // 파일 크기(바이트)
blksize_t st_blksize; // 블록 크기
blkcnt_t st_blocks; // 512바이트 블록 갯수
time_t st_atime; // 최종 접근 시간 (access time)
time_t st_mtime; // 최종 수정 시간 (modification time)
time_t st_ctime; // 최종 상태 변경 시간 (change time)
};mode_t st_mode
파일 종류 비트 마스크
파일 종류 8진수 테스트 매크로 파일 종류 S_IFMT 0170000 파일 타입 비트 마스크 S_IFREG 0100000 S_ISREG() 일반 파일 S_IFDIR 0040000 S_ISDIR() 디렉토리 파일 S_IFCHR 0020000 S_ISCHR() 문자 디바이스 S_IFBLK 0060000 S_ISBLK() 블록 디바이스 S_IFFO 0010000 S_ISFIFO() FIFO, Pipe 파일 S_IFSOCK 0140000 S_ISSOCK() 소켓 S_IFLNK 0120000 S_ISLNK() 심볼릭 링크 S_IFDOOR 0150000 S_ISDOOR() 유효 사용자 및 접근 권한 매크로
테스트 매크로 8진수 내용 S_ISUID 0004000 set-user-id S_ISGID 0002000 set-group-id S_ISVTX 0001000 sticky bit S_IRWXU 0000700 소유자 권한 마스크 S_IRUSR 0000400 소유자 읽기 권한 S_IWUSR 0000200 소유자 쓰기 권한 S_IXUSR 0000100 소유자 실행 권한 S_IRWXG 0000070 그룹 권한 마스크 S_IRGRP 0000040 그룹 읽기 권한 S_IWGRP 0000020 그룹 쓰기 권한 S_IXGRP 0000010 그룹 실행 권한 S_IRWXO 0000007 기타 사용자 권한 마스크 S_IROTH 0000004 기타 사용자 읽기 권한 S_IWOTH 0000002 기타 사용자 쓰기 권한 S_IXOTH 0000001 기타 사용자 실행 권한 함수 원형
#include <unistd.h> #include <sys/stat.h> #include <sys/types.h> int stat(const char *filepath, struct stat *statbuf); int fstat(int fd, struct stat *statbuf); int lstat(const char *filepath, struct stat *statbuf);
매개변수
filepath
stat 을 얻고자 하는 파일의 경로
statbuf
stat 을 주입받을 주소
fd
stat을 얻고자 하는 파일의 파일 디스크립터
반환값
성공 시 0 리턴
에러 시 -1 리턴과 errno 설정
예제
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> int main(int argc, char *argv[]) { struct stat statbuf; if (stat(argv[1], &statbuf) < 0) { fprintf(stderr, "stat error\n"); exit(1); } // statbuf.st_size = 파일의 크기 printf("%s %ld bytes\n", argv[1], statbuf.st_size); exit(0); }
결과
예제2
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> struct stat statbuf; void ssu_checkfile(char* fname, time_t *time); int main(int argc, char* argv[]) { time_t intertime; if (argc != 2) { fprintf(stderr, "usage: %s <file>\n", argv[0]); exit(1); } if (stat(argv[1], &statbuf) < 0) { fprintf(stderr, "sttat error for %s\n", argv[1]); exit(1); } intertime = statbuf.st_mtime; while(1) { ssu_checkfile(argv[1], &intertime); sleep(10); } exit(0); } void ssu_checkfile(char* fname, time_t* time) { if (stat(fname, &statbuf) < 0) { fprintf(stderr, "Warning: ssu_checkfile() error!\n"); exit(1); } if (statbuf.st_mtime != *time) { printf("Warning: %s was modified!.\n", fname); *time = statbuf.st_mtime; } }
결과
a.out 실행 후 파일을 수정하면 변화가 감지되는 모습
예제
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> int main(int argc, char *argv[]) { struct stat file_info; char *str; int i; for (int i = 1; i < argc; i++) { if (lstat(argv[i], &file_info) < 0) { fprintf(stderr, "lstat error\n"); continue; } printf("name = %s, type = ", argv[i]); if (S_ISREG(file_info.st_mode)) str = "regular"; else if (S_ISDIR(file_info.st_mode)) str = "directory"; else if (S_ISCHR(file_info.st_mode)) str = "character special"; else if (S_ISBLK(file_info.st_mode)) str = "block special"; else if (S_ISFIFO(file_info.st_mode)) str = "FIFO"; else if (S_ISLNK(file_info.st_mode)) str = "symbolic link"; else if (S_ISSOCK(file_info.st_mode)) str = "socket"; else str = "unknown"; printf("%s\n", str); } exit(0); }
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> int main(int argc, char *argv[]) { struct stat file_info; char *str; int i; for (int i = 1; i < argc; i++) { if (lstat(argv[i], &file_info) < 0) { fprintf(stderr, "lstat error\n"); continue; } printf("name = %s, type = ", argv[i]); if ((S_IFMT & file_info.st_mode) == S_IFREG) str = "regular"; else if ((S_IFMT & file_info.st_mode) == S_IFDIR) str = "directory"; else if ((S_IFMT & file_info.st_mode) == S_IFCHR) str = "character special"; else if ((S_IFMT & file_info.st_mode) == S_IFBLK) str = "block special"; else if ((S_IFMT & file_info.st_mode) == S_IFIFO) str = "FIFO"; else if ((S_IFMT & file_info.st_mode) == S_IFLNK) str = "symbolic link"; else if ((S_IFMT & file_info.st_mode) == S_IFSOCK) str = "socket"; else str = "unknown"; printf("%s\n", str); } exit(0); }
결과
리눅스시스템프로그래밍 저자 : 홍지만
https://book.naver.com/bookdb/book_detail.nhn?bid=14623672
책에 기술된 예제 프로그램입니다. 책 내부에는 훨씬 더 많은 자료가 있습니다. (개인적으로 좋았습니다.)'C,C++ & Linux' 카테고리의 다른 글
C/C++ umask(2) (1) 2020.05.17 C/C++ access(2) (1) 2020.05.17 C/C++ sync(2), fsync(2), fdatasync(2) (0) 2020.05.16 C/C++ dup2() (0) 2020.05.16 C/C++ dup() (0) 2020.05.16