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

 

 


see also : lstat(2)  fstat(2)

    File 속성 정보 및 파일 관리 Library

    Directory 정보 조회 및 관리 Library

    System Call File I/O Library

    Stream File I/O Library

 

블로그 이미지

사용자 자연&사람

행복한 개발자 programmer since 1995.

댓글을 달아 주세요