반응형

lstat(2)

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int lstat(const char *path, struct stat *buf);

파일의 크기, 파일의 권한, 파일의 생성일시, 파일의 최종 변경일 등, 파일의 상태나 파일의 정보를 얻는 함수입니다. stat(2)는 symbolic link인 파일을 넘기면 link되어 있는 원본 파일의 정보를 얻지만, lstat(2) 함수는 symbolic link인 파일을 path로 넘기면 symbolic link인 파일 자체의 정보를 얻습니다.  나머지 기능은 stat(2)와 같습니다.

 

이 함수는 우리가 가장 많이 사용하는 명령어 중의 하나인 ls 명령어로 알 수 있는 내용들을 대부분 알 수 있습니다.

 

 

파라미터

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 (lstat(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 sample2.c
결과:
File type:                symlink
I-node number:            421025
Mode:                     120777 (octal)
Link count:               1
Ownership:                UID=1000   GID=1000
Preferred I/O block size: 4096 bytes
File size:                8 bytes
Blocks allocated:         0
Last status change:       Sat Nov  5 22:40:32 2016
Last file access:         Sat Nov  5 22:40:34 2016
Last file modification:   Sat Nov  5 22:40:32 2016

 


see also :  stat(2) fstat(2)

    File 속성 정보 및 파일 관리 Library

    Directory 정보 조회 및 관리 Library

    System Call File I/O Library

    Stream File I/O Library

 

반응형
블로그 이미지

자연&사람

행복한 개발자 programmer since 1995.

,