이 글은 <시스템 프로그래밍 리눅스 & 유닉스(이종원 지음)> 책을 공부하며 정리한 것입니다!
리눅스에서 파일은
하나씩 파보자 !
파일명은 사용자가 파일에 접근할 때 사용하며, 파일명과 관련된 inode가 반드시 있어야 한다.
< 파일명과 관련한 여러 사항들 >
1. 파일명이나 디렉터리명으로 /(디렉터리 구분)와 Null(경로 이름의 끝을 나타냄)을 사용할 수 없음
2. 혼동을 줄 수 있는 특수문자는 사용 자제
3. 알파벳은 대소문자를 구분함
4. 파일명과 디렉터리명이 '.'으로 시작하면 '숨김파일'로 간주
inode는 파일에 대한 정보를 저장하고 있는 객체로 실제 디스크에 저장되어있다.
inode의 첫 번째 부분에는 파일에 관한 정보가 저장되는데,
ls -l
명령으로 확인 가능
inode의 두 번째 부분에는 파일의 실제 데이터가 저장되어 있는 데이터 블록의 위치를 나타내는 주소가 저장된다 !
ls -i
명령으로 확인 가능
데이터블록은 실제로 데이터가 저장되는 하드 디스크의 공간
리눅스에서 파일은 크게 세 종류가 있다.
ls -l
명령을 사용하자!
명령의 결과로 나온 첫 글자
가 장치의 종류를 의미한다.
- : 일판 파일
d : 디렉터리
b : 블록 장치 특수 파일
c : 문자 장치 특수 파일
l : 심벌릭 링크
자 그럼, 하나씩 파보자!
리눅스에서 사용하는 대부분의 파일 이 여기에 해당한다.
대부분의 파일이라고 한다면 ,
리눅스에서 통신을 하거나 터미널, 디스크 등의 장치를 사용할 때는 특수 파일을 사용해야함.
장치 관련 특수 파일을 장치 파일이라고 하는데,
이 장치 파일은 데이터 블록을 사용하지 않고 장치 번호를 inode에 저장한다.
리눅스에서는 디렉터리도
파일
로 취급한다!
디렉터리와 연관된 데이터 블록은 해당 디렉터리에 속한 파일의 목록과 inode를 저장한다.
디렉터리를 생성하려면 mkdir
, 삭제하려면 rmdir
혹은 rm -r
, 복사하려면 cp -r
명령을 사용한다.
디렉터리를 생성할 때는 mkdir()
함수를 사용하고 삭제할 때는 rmdir()
함수를
사용한다
추가로, 이 함수들은 디렉터리를 생성화고 삭제할 때 사용하는 명령과 이름이 같아서
man -s 2
이렇게 검색해야한다.
저기서 2
가 뜻하는 것은 시스템 호출 섹션의 mkdir, rmdir을 찾겠다는 것을 의미하며
섹션 1
은 리눅스에서 사용하는 일반적인 명령, 섹션 3
은 라이브러리 함수를 의미한다
함수 원형: int mkdir(const char *pathname, mode_t mode);
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
int main(){
if(mkdir("han", 0755) == -1) {
perror("han");
exit(1);
}
}
함수 원형: int rmdir(const char *pathname);
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
int main(){
if(rmdir("han") == -1) {
perror("han");
exit(1);
}
}
현재 작업 디렉터리의 위치를 알아낼 때 사용하는 함수는
요렇게 세 개이다.
cf. 현재 디렉터리의 위치를 알려주는 명령은 pwd
함수 원형: char *getcwd(char *buf, size_t size);
getcwd()에서 인자를 지정하는 방법은 세 가지정도가 있는데,
malloc()
함수로 버퍼가 할당되므로 사용 후 free()
함수로 메모리를 해제해야함. getcwd()
에서 저장할 경로가 버퍼의 크기를 넘으면 NULL
을 리턴한다!#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(){
char *cwd;
char wd1[BUFSIZ];
char wd2[10];
getcwd(wd1, BUFSIZ);
printf("wd1 = %s\n", wd1);
cwd = getcwd(NULL, BUFSIZ);
printf("cwd1 = %s\n", cwd);
free(cwd);
cwd = getcwd(NULL, 0);
printf("cwd2 = %s\n", cwd);
free(cwd);
if(getcwd(wd2,10) == NULL){
perror("getcwd"); // Numerical result out of range
exit(1);
}
}
함수 원형: char *get_current_dir_name(void);
인자로 아무것도 전달하지 않으며,
시스템이 메모리를 자동으로 할당해 경로를 저장하고 리턴한다.
#define _GNU_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(){
char *cwd;
cwd = get_current_dir_name();
printf("cwd = %s\n", cwd);
free(cwd);
}
함수 원형: int rename(const *oldpath, const char *newpath);
#include <sys/path.h>
#include <stdlib.h>
#include <stdio.h>
int main(){
if (rename("han", "bit") == -1){
perror("rename");
exit(1);
}
}
함수 원형: int chdir(const *path);
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
char *cwd;
cwd = getcwd(NULL, BUFSIZ);
printf("1. current dir: %s\n", cwd); // /home/jw/src/ch2
chdir("bit");
cwd = getcwd(NULL, BUFSIZ);
printf("2. current dir: %s\n", cwd); // /home/jw/src/ch2/bit
free(cwd);
}
pwd
명령으로 확인하면 현재 디렉터리가 바뀐 것은 아님을 알 수 있다.(여전히 /home/jw/src/ch2)함수 원형: int fchdir(int fd);
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
char *cwd;
int fd;
cwd = getcwd(NULL, BUFSIZ);
printf("1. current dir: %s\n", cwd); // /home/jw/src/ch2
fd = open("bit", O_RDONLY);
fhdir(fd);
cwd = getcwd(NULL, BUFSIZ);
printf("2. current dir: %s\n", cwd); // /home/jw/src/ch2/bit
close(fd);
free(cwd);
}
pwd
명령으로 확인하면 현재 디렉터리가 바뀐 것은 아님을 알 수 있다.(여전히 /home/jw/src/ch2)디렉터리 열고 닫기, 내용 읽기, 오프셋 이동하는 함수에 대해 알아보자!
함수 원형: DIR *opendir(const char *name);
함수 원형: int closedir(DIR *dirp);
함수 원형: struct dirent *readdir(DIR *drip);
인자로 지정한 DIR 객체가 가리키는 디렉터리의 내용을 한번에 하나씩 읽는다
디렉터리 내용을 차례로 읽고 더 이상 읽을 것이 없으면 NULL을 리턴
readdir()는 디렉터리에 있는 항목의 정보를 가리키는 dirent 구조체의 포인터를 리턴
struct dirent {
ino_t d_ino; //해당 항목의 inode 번호
off_t d_off; // 디렉터리 오프셋의 위치
unsigned short d_reclen; //해당 항목의 레코드 길이
unsigned char d_type; //파일의 종류
char d_name[256]; //항목의 이름
};
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
int main(){
DIR *dp;
struct dirent *dent;
dp = opendir(".");
while ((dent = readdir(dp))) {
printf("Name = %s ", dent->d_name);
printf("Inode: %d\n", (int)dent->d_ino);
}
}
closedir(dp);
telldir(), seekdir(), rewinddir()
#include <sys/types.h>
#include <dirent.h>
long telldir(DIR *dirp);
void seekdir(DIR *dirp, long loc);
void rewinddir(DIR *dirp);
telldir()
: 인자가 가리키는 디렉터리 스트림에서 현재 위치 리턴
: 오류가 발생하면 -1 리턴
seekdir()
: 디렉터리 스트림에서 readdir() 함수가 다음 항목을 읽을 수 있는 위치로 오프셋을 이동시킨다.
: loc에 지정하는 값은 telldir()함수가 리턴한 값이어야 한다.
: 아무것도 리턴하지 않음
rewinddir()
: 디렉터리 스트림의 위치를 디렉터리 시작 지점으로 이동시킴
: 아무것도 리턴하지 않음