리눅스 파일의 종류와 권한, 모드 알아내기 by 노랑양말

모든 것이 파일로 표현될 수 있다는 점과 다중사용자 운영체제라는 리눅스 운영체제의 특성상 파일의 종류와 권한,모드를 알아내는 것은 매우 중요하다. 파일을 다루는 프로그램을 작성할 경우 가장 먼저하는 일이 접근가능한 파일인지를 확인하는 일이다. 리눅스는 파일에 대한 정보를 얻어올 수 있는 stat라는 함수를 제공한다.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *file_name, struct stat *buf);

파일 이름 file_name를 인자로 주면, 그에 대한 정보를 stat구조체에 담아서 되돌려준다. stat에는 다음과 같은 파일 정보들이 담겨져 있다.

struct stat {
    dev_t         st_dev;      /* device */
    ino_t         st_ino;      /* inode */
    mode_t        st_mode;     /* protection */
    nlink_t       st_nlink;    /* number of hard links */
    uid_t         st_uid;      /* user ID of owner */
    gid_t         st_gid;      /* group ID of owner */
    dev_t         st_rdev;     /* device type (if inode device) */
    off_t         st_size;     /* total size, in bytes */
    blksize_t     st_blksize;  /* blocksize for filesystem I/O */
    blkcnt_t      st_blocks;   /* number of 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 change */
};


주석을 보는 정도로 각 멤버변수가 의미하는 바를 쉽게이해할 수 있을 것이다. 그러니 몇개 생소한 멤버변수들만을 설명하도록 하겠다.

st_ino  : 파일의 일련번호다. 이 번호는 하나의 장치에서 유일하게 존재하며, 파일과 파일을 구분하게 해준다. 하나의 장치에서만 유일하다는 것에 주의하기 바란다.
st_dev : 파일이 속한 장치의 식별번호다. st_ino 와 st_dev 의 쌍은 전체 시스템에서 유일하다.
st_nlink : 파일의 hard:::link(이하 하드링크)의 갯수를 알려준다. 하드링크에 대한 내용은 따로 자세히 다루도록 하겠다.
st_mode : 파일의 형식을 알려준다. 이 값을 이용해서, 파일이 디렉토리인지, 링크인지, 장치 파일인지등을 알아낼 수 있다. 이 값을 분석하기 위한 다음과 같은 메크로를 제공한다. 각 메크로는 검사하고자 하는 내용이 참이면 0이 아닌 값을 리턴한다.
S_ISDIR(st_mode) : 파일이 디렉토리(:12) 인지 검사한다.
S_ISCHR(st_mode) : 파일이 문자장치(:12) 파일인지 검사한다.
S_ISREG(st_mode) : 일반파일인지 검사한다.
S_ISFIFO(st_mode) : FIFO(:12) 혹은 pipe(:12) 파일인지 검사한다.
S_ISLNK(st_mode) : symbolic 링크 인지 검사한다.
S_ISSOCK(st_mode) : 소켓(:12) 파일인지 검사한다.

다음은 파일의 각종 정보를 읽어오는 프로그램이다. 프로그램의 이름은 stat.c로 하겠다.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <pwd.h>
#include <grp.h>

int main(int argc, char **argv)
{
    int return_stat;
    char *file_name;
    struct stat file_info;

    mode_t file_mode;

    if (argc != 2 )
    {
        printf("Usage : ./file_info [file name]\n");
        exit(0);
    }
    file_name = argv[1];

    if ((return_stat = stat(file_name, &file_info)) == -1)
    {
        perror("Error : ");
        exit(0);
    }

    file_mode = file_info.st_mode;
    printf("파일이름 : %s\n", file_name);
    printf("=======================================\n");
    printf("파일 타입 : ");
    if (S_ISREG(file_mode))
    {
        printf("정규파일\n");
    }
    else if (S_ISLNK(file_mode))
    {
        printf("심볼릭 링크\n");
    }
    else if (S_ISDIR(file_mode))
    {
        printf("디렉토리\n");
    }
    else if (S_ISCHR(file_mode))
    {
        printf("문자 디바이스\n");
    }
    else if (S_ISBLK(file_mode))
    {
        printf("블럭 디바이스\n");
    }
    else if (S_ISFIFO(file_mode))
    {
        printf("FIFO\n");
    }
    else if (S_ISSOCK(file_mode))
    {
        printf("소켓\n");
    }

    printf("OWNER : %d\n", file_info.st_uid);
    printf("GROUP : %d\n", file_info.st_gid);
    printf("dev   : %d\n", file_info.st_dev);
    printf("inode : %d\n", file_info.st_ino);
    printf("FILE SIZE IS : %d\n", file_info.st_size);
    printf("마지막 읽은 시간 : %d\n", file_info.st_atime);
    printf("마지막 수정 시간 : %d\n", file_info.st_mtime);
    printf("하드링크된 파일수 : %d\n", file_info.st_nlink);
}

테스트 삼아서 stat.c 에 대한 조사를 해보자.

$ ./stat stat.c
파일이름 : stat.c
=======================================
파일 타입 : 정규파일
OWNER : 1000
GROUP : 1000
dev   : 2051
inode : 6603353
FILE SIZE IS : 1692
마지막 읽은 시간 : 1196074251
마지막 수정 시간 : 1196074249
하드링크된 파일수 : 2

[출처] http://www.joinc.co.kr/modules/moniwiki/wiki.php/FrontPage

덧글

댓글 입력 영역