이 글은 <시스템 프로그래밍 리눅스 & 유닉스(이종원 지음)> 책을 공부하며 정리한 것입니다!
리눅스에서 파일은

하나씩 파보자 !
파일명은 사용자가 파일에 접근할 때 사용하며, 파일명과 관련된 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()
: 디렉터리 스트림의 위치를 디렉터리 시작 지점으로 이동시킴
: 아무것도 리턴하지 않음