0. 시작하기전에
- 이번 포스팅에서는 파일 시스템과 관련된 시스템 콜에 대해서 알아보자.
1. inode 파일 시스템
- 리눅스는 inode라는 파일 시스템을 사용한다.
- 이 파일 시스템을 이해하는데 가장 큰 도움이 되는 것은 inode의 구조체를 이해하는 것이다.
- 다음 사진에서 빨간색 네모로 표시된 inode의 구조체를 살펴보자.
- 프로세스는 pid로 구분되고, 프로세스의 상태를 나타내는 pcb를 가지고 있다.
- 이처럼 파일도 inode번호로 구분되고, 각 inode번호에 대응하는 구조체를 갖고 있다.
▶ Mode
- 파일 종류, 권한
▶ Owner Info
- 소유자, 소유 그룹
▶ Size
- 파일의 사이즈
▶ Timestamps
- 파일의 생성, 수정 등의 시간정보
▶ Direct Blocks
- 파일은 가변적인 크기를 갖는다. 어떤 파일은 1바이트, 어떤 파일은 몇 기가의 크기를 가질 수 있다.
- 이처럼 가변적인 크기를 갖는 파일이 저장위치를 나타내는 직접주소(데이터 위치)를 표현한다.
▶ Single, Double, Triple indirect
- 파일의 간접주소를 표현를 표현한다.
a) stat() - inode 메타 데이터를 가져오는 시스템 콜
- 위에서 설명했듯이, 각 파일에는 inode 구조체를 가지고 있다.
- 이 inode 구조체가 가진 정보를 inode 메타데이터라고 부른다.
- stat() 함수는 이 inode 메타데이터를 한번에 불러오는 시스템 콜이다.
- 다음 stat() 함수의 원문을 살펴보자.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf); // 파일 이름(경로)를 이용해 inode 메타데이터를 가져온다
int fstat(int filedes, struct stat *buf); // file descriptor를 이용해 inode 메타데이터를 가져온다.
b) stat 구조체
- stat 구조체는 다음과 같은 inode의 메타데이터를 가져온다.
c) 실습예제 - inode 메타 데이터 출력하기
#include <stdio.h>
#include <sys/stat.h>
int main() {
int ret = 0;
struct stat buf;
ret = stat("link.txt", &buf);
if(ret < 0) {
printf("ERROR\n");
return 0;
}
printf("deviceID[%ld], inodenum[%ld], hardlinkcount[%ld], filesize[%ld], blocksize[%ld], blockcount[%ld] \n", buf.st_dev, buf.st_ino, buf.st_nlink, buf.st_size, buf.st_blksize, buf.st_blocks);
return 0;
}
* 참고로 filesize의 경우, 실제 파일이 차지하고 있는 영역과 추가될 것을 대비하여 예약되어 있는 영역을 포함하여 계산된다.
* 참고로 blockcount의 경우, 1개의 블럭을 512Byte로 기준으로 하여 몇개의 블럭이 사용되는지를 계산한다.
2. 표준 입출력 관련 시스템 콜
- 앞서 표준 입출력은 다음 세가지 스트림으로 구분된다는 것을 배웠다.
▶ 표준 입력 스트림(Standard Input Stream) - stdin
▶ 표준 출력 스트림(Standard Output Stream) - stdout
▶ 오류 출력 스트림(Standard Error Stream) - stderr
- 이 세가지 스트림이 프로그램에서 어떻게 사용되는지 예제를 통해 알아보자.
a) 실습예제
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char** argv) {
char buf[255];
FILE* fp;
if(argc == 2) { // 인자가 들어오는 경우
fp = fopen(argv[1], "r"); // 인자를 오픈해서 fp에 저장한다.
if(fp == NULL) {
fputs("file open error", stderr);
exit(0);
}
} else {
fp = stdin; // 인자가 없는 경우, 인자를 받는다.(표준입력)
}
while(fgets(buf, 255, fp) != NULL) { // 인자를 255만큼의 크기를 입력 받은 경우
fputs(buf, stdout); // 인자를 출력한다. (표준출력)
}
}
- 이처럼 파일 디스크립터를 이용하여 표준 입출력이 작동한다는 것을 확인할 수 있다.
'컴퓨터공학기초 개념 > 시스템 프로그래밍' 카테고리의 다른 글
36. 시스템 프로그래밍 - mmap 사용방법 (0) | 2021.09.27 |
---|---|
35. 시스템 프로그래밍 - 메모리 & mmap (3) | 2021.09.27 |
34. 스레드 - detach와 mutex (0) | 2021.09.25 |
33. 스레드 - 이해와 기본 (0) | 2021.09.24 |
32. 쉘 스크립트 - 현업 예제(backup, log, tar, find) (0) | 2021.09.24 |
댓글