더 많은 정보를 담은 리눅스 교재를 배포했습니다. 아래의 페이지에서 리눅스 교재를 받아가세요.

https://reakwon.tistory.com/233

 

리눅스 프로그래밍 note 배포

티스토리에 리눅스에 관한 내용을 두서없이 여지껏 포스팅했었데요. 저도 제 포스팅을 찾기가 어렵기도 하고 티스토리에서 코드삽입을 하게 되면 이게 일자로 쭉 쓰여져있는 x같은 현상이 생겨

reakwon.tistory.com

 

파일 정보 얻어오기

 

파일에 대한 정보를 얻어올때는 lstat시스템 콜을 사용하면 됩니다. 사실 stat, lstat, fstat등 여러가지 시스템 콜이 있는데요, 가장 간단하게 사용할 수 있는 시스템 콜이기 때문에 여기서는 lstat을 사용하겠습니다.

 

우선 lstat에 관한 시스템 콜 원형부터 보겠습니다.

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

lstat은 두개의 인자를 받게 되어있군요.

filename : 말 그대로 파일의 이름입니다. 하지만 경로를 명시하지 않을때는 현재 디렉토리를 기준으로 파일을 찾습니다. 절대경로나 상대경로를 줄 수 있다는 점은 알고 잇으세요.

buf : 파일의stat구조체를 저장합니다. stat??

무엇일까요. 구조체부터 보도록 하지요. vi 편집기를 사용한다면 lstat에서 3+K(shift)를 입력하면 시스템 콜을 볼 수 있습니다. 조금 더 밑으로 내려가다 보면 stat구조체를 만나볼 수 있게 되는데요. 아래와 같습니다.

struct stat

{

dev 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 */

unsigned long st_blksize;    /* blocksize for filesystem I/O */

unsigned long 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는 inode를 말하는 것이고 st_mode는 파일이 디렉토리인가, 단순 파일인가, 케릭터 디바이스인가를 알 수 있는 것이겠구요.

uid, gid도 알 수 있고 파일의 사이즈도 알 수 있습니다. 더군다나 파일이 언제 수정되고 접근되었는지에 대한 시간 정보도 알 수 있군요! 굿!!

 

그 중에서 ls명령어에 사용되는 st_mode는 어떤 파일의 타입인지 저장되어 있습니다. 어떤 파일 타입인지 알아보기 위해서 매크로 함수를 제공하는데요. 이것에 대해서 조금 더 알아보기 위해서 표로 준비해보았습니다.

 

모드  설명 
 S_ISLNK(m) 심볼릭 링크 파일인지 확인합니다. 
 S_ISREG(m) 단순 파일인지 확인합니다. 
 S_ISDIR(m)  디렉토리인지 확인합니다. 
 S_ISCHR(m)  문자 디바이스인지 확인합니다. 
 S_ISBLK(m)  블록 디바이스인지 확인합니다. 
 S_ISFIFO(m)  FIFO파일인지 확인합니다. 선입선출 구조의 파일인지 확인하는 것이죠. 
 S_ISSOCK(m)  네트워크 통신에 필요한 소켓파일인지 확인합니다. 

 

반환값 : 성공시 0이 반환되고 실패시 -1이 반환됩니다. 에러가 발생했다면 적절한 값으로 설정된다고 하는데 에러에 대해서는 구글형님께 물어봅시다.

 

구현

이제 대충 알아보았으니 코드를 직접 짜보도록하겠습니다. 우선 코드부터 보시죠. 

#include <stdio.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <time.h> 
#define BUF_SIZE 1024     
void printType(const char *name,const struct stat *buf){
        if(S_ISDIR(buf->st_mode))   
                printf("%s is DIR \n",name);  
        else if(S_ISREG(buf->st_mode))  
                printf("%s is FILE\n", name);  
        else if(S_ISSOCK(buf->st_mode))    
                printf("%s is SOCKET\n",name);   
        else if(S_ISCHR(buf->st_mode))   
                printf("%s is CHARACTER DEVICE\n",name);    
        else if(S_ISFIFO(buf->st_mode))    
                printf("%s is FIFO\n",name);     
        else if(S_ISBLK(buf->st_mode))   
                printf("%s is BLOCK DEVICE\n",name);   
        else if(S_ISLNK(buf->st_mode))   
                printf("%s is LINK\n",name); 
}  

void printTime(struct stat *buf){       
        struct tm *mtime;      
        mtime=localtime(&buf->st_mtime);     
        printf("%04d-%02d-%02d %02d:%02d\n",
                        mtime->tm_year+1900, mtime->tm_mon+1,
                        mtime->tm_mday, mtime->tm_hour,  
                        mtime->tm_min); 
}   

void printFileSize(const char *name, struct stat *buf){      
        printf("%s size: %ld\n",name,buf->st_size); 
}  

int main(){      
        char filename_dir[128]="dir";     
        char filename_file[128]="aaa";   
        struct stat file;       
        struct stat dir;     

        lstat(filename_dir,&dir);     
        lstat(filename_file,&file);  

        printType(filename_dir,&dir);     
        printTime(&dir); 
        printFileSize(filename_dir,&dir);    
        printf("\n");

        printType(filename_file,&file);    
        printTime(&file);  
        printFileSize(filename_file, &file); 
}

 

 

printType의 함수는 파일이 어떤 종류의 파일인지 알아오는 함수입니다. 그러니까 이 파일이 정규파일인지, 디렉토리인지, 블록 디바이스 파일인지 등등 알아오는 함수지요. 매개변수는 stat구조체의 포인터를 매개변수로 받아야 알 수 있겠죠? 파일의 이름과 같아 받게 됩니다.
 
printTime은 파일이 언제 수정되었는지에 대해서 알아오는 함수입니다. 역시 stat구조체를 매개변수로 받습니다. 시간을 우리가 더 잘알아보기 위해서 localtime이라는 함수를 사용합니다. 그래서 tm구조체의 포인터를 반환하죠.
 
printFileSize는 파일의 크기를 알아오는 함수입니다. 역시 파일의 이름과 stat구조체를 매개변수로 받고 있습니다. 파일의 크기를 알아오는 변수는 st_size입니다.
 
이제 코드를 컴파일시키고 파일을 만들어 실험해봅시다.
# gcc lstat.c
# mkdir dir
# touch aaa

 

 
이제 파일의 크기를 조금 변경시켜보도록 하겠습니다. vi 편집기를 열어 aaa파일에 ABCDEF라는 문자열을 입력하고 저장합니다.
# vi aaa
ABCDEF
:wq
 
이제 컴파일된 파일을 실행시킵니다.
# ./a.out
dir is DIR
2018-11-19 00:06
dir size : 6

aaa is FILE
2018-11-19 00:46
aaa size : 7
 
그 후에 ls 명령어로 두 파일과 디렉토리를 보게되면 같은 정보를 확인할 수가 있습니다.
반응형
블로그 이미지

REAKWON

와나진짜

,