stat은 파일의 상태정보를 알려주는 system call
System call: stat(2)
#include <sys/stat.h>
int stat(const char *pathname, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
세가지 모두 파일의 상태정보를 제공하는것은 똑같음. (return 0 on success, -1 on error)
- stat : pathname을 통해 정보를 얻음
- fstat : 파일 디스크립터 값을 통해 정보를 얻음
- lstat : symbolic link파일의 정보를 얻음
- 만약 File A가 File B에대한 symlink 파일일경우, fstat(A),stat(A)를 하면 파일 B에대한 정보를 얻음, 반면
lstat(A)는 A에대한 정보를 얻을 수 있음
struct stat
struct stat{
mode_t st_mode;
ino_t st_ino;
dev_t st_dev;
dev_t st_rdev;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
off_t st_size;
time_t st_atime;
time_t st_mtile;
time_t st_ctime;
blksize_t st_blksize;
blkcnt_t st_blocks;
};
Directories, File Systems and Special Files
File System and Directory
- File system
- directory 역시도 파일이다. 파일 시스템은 disk에 있는 디렉토리, 파일들을 사용자가 사용할 수 있게 계층적으로 만든 시스템
- 파일 시스템은 root라는 directory부터 시작되며 root는 "/"로 표시함
- Working directory
- 워킹 디렉토리는 모든 프로세스에 존재함 (해당 프로세스의 워킹 디렉토리를 current working directory라 함)
- 상대 경로로 표시되는 directory
- Home directory
- 로그인할때, 워킹 디렉토리는 가장 먼저 홈 디렉토리를 set함 ( 첫 실행 프로세스: bash, bash의 워킹 디렉토리 -> home)
- Pathname
- 절대경로 : root부터 시작하는것 ex) /home/file1/file2
- 상대경로 : 현재 워킹 디렉토리 file2
The Implementation of Directory
Directory
- 디렉토리는 파일에 대한 엔트리를 가짐
- 디렉토리와 일반 파일의 차이
- 디렉토리는 file에 대한 시스템 콜이 대부분 작동함 (file이니까)
- 하지만 write는 불가능 -> write한다는 것은 디렉토리 안의 파일내용도 바꾼다는 것을 의미 -> 디렉토리 구조가 망가짐
- open, creat 시스템 콜로 directory를 생성 할 수 없음
- 있는 파일을 O_RDWR, O_WRONLY flag를 set하고 open하면 error (write가 안되니까)
- directory 자체를 write 할 수도없음
- 오직 커널만이 directory를 write할 수 있음
- 디렉토리는 directory 엔트리를 가짐. 엔트리에 각각의 파일과 서브디렉토리들은 다음과 같은 내용을 담고 있음
- i-node 번호
- character field

- link를 한다는것 = 파일에 또다른 이름을 부여한다는 것 = directory entry에 새롭게 추가한다는 것
- 만약 link("abc","xyz"); 을 하게 되면 entry는 다음과 같아짐

- unlink도 같음
Dot, and double-dot
- "." : current working directory
- ".." : parent directory
Example: Directory Structure

Directory Permissions
-
디렉토리의 권한은 일반파일 권한과 똑같이 구성됨
-
그러나 각각의 권한은 조금 다르게 해석이됨
- read
- 디렉토리 안의 어떤것들이 있는지 list 할 수 있게하는 권한을 부여함
- write
- directory 안의 파일을 만들거나 삭제할 권한을 부여함.
이때 앞의 디렉토리는 write를 할 수 없다는 말에 의문을 가질 수 있는데, 앞에서의 write는 write 시스템 콜을 이용해 파일을 바꿀 수 없다는 것을 의미하고, write permission은 write 시스템 콜이 아닌, 다른 시스템 콜을 이용해 파일을 만들거나 삭제할 수 있다는 것을 의미함
ex) /home/ex 에있다고 할 때 ex라는 디렉토리에 write 권한을 부여한다는 것은 ex에서 open("file2", ...) 이것은 가능하지만, open("ex", ...) 이것은 불가능 하다는 것을 의미
- execute
- 그 디렉토리로 직접 들어갈 수 있을 권한을 부여함. 즉, working directory를 해당 디렉토리로 바꿀 수 있음을 의미
ex) /usr/include/stdio.h를 open하기 위해서는, '/', '/usr', '/usr/include'에 대한 execute 권한이 있어야 한다.
read 권한과 execute 권한은 다르다 read는 그안의 내용을 list만 얻어오는것이고, execute는 직접 들어갈 수 있어야 함.
-
save-text-image (sticky bit): S_ISVTX
-
만약 sticky bit이 디렉토리에 set됐을 경우, 디렉토리에 write permission있을 때, file 생성만 되고 삭제는 안되게 할 수 있다.
-
삭제는 file의 소유자, directory의 소유자, superuser만이 가능하다.
Programming with Directories
Structure: dirent
#include <dirent.h>
struct dirent {
ino_t d_ino;
chsr d_name[NAME_MAX+1];
}
- 만약 d_ino가 0이면, 삭제됐다는 것을 의미. 새로 만들면 d_ino가 0인 곳에 값을 넣어줌
System Call: mkdir(2)
#include <sys/stat.h>
int mkdir(const char *pathname, mode_t mode);
- mkdir은 directory를 만드는 system call (return 0 on success, -1 on error)
- mode_t mode = permission을 의미 umask의 영향을 받음
- mkdir은 '.'과 '..'을 자동으로 부여
- 일반적으로 execute 권한은 주고 시작한다.
System Call: rmdir(2)
#include <unistd.h>
int rmdir(const char *pathname);
- rmdir은 empty 디렉토리를 지운다. (return 0 on success, -1 on error)
- empty 디렉토리라는 것은, 디렉토리 엔트리에 '.', '..' 두개만 있는 것을 의미함.
Function: opendir(3)
#include <dirent.h>
DIR *opendir(const char *dirname);
- directory를 위한 open function (directory는 open system call 사용 불가능)
- dirname을 가진 directory를 open (return pointer of dir on success, NULL on error)
Function: closedir(3)
#include <dirent.h>
int closedir(DIR *dirptr);
- 디렉토리를 종료 반환받은 dirptr을 파라미터로 받음 (return 0 on success, -1 on error)
Function readdir(3)
#include <dirent.h>
struct dirent *readdir(DIR *dirptr);
- directory를 read하는 함수. read는 directory entry를 보는것을 의미. 따라서 readdir(dir)하면 첫번째 entry의 dirent 구조체를 반환, 한번더 readdir(dir)하면, 두번째 entry dirent 구조체를 반환....
- while문으로 readdir()호출하면, 디렉토리의 모든 dirent를 return. 이때 다시 첫번째 entry로 다시가는법-> rwinddir
Function rewinddir(3)
#include <dirent.h>
void rewinddir(DIR *dirptr);
- dirptr을 directory의 첫번째 엔트리로 가게 하는 함수 ( return 0 on success, -1 on error)
The Current Working Directory
- linux에서 모든 프로세스는 자기 자신의 커렌트 워킹 디렉토리를 가짐
- user와 관련된 커렌트 워킹 디렉토리는 사용자가 명령어를 입력하는 shell이다.
System Call: chdir(2)
#include <unistd.h>
int chdir(const char *path);
- cd명령어는 실제로 chdir system call을 호출
- chdir은 커랜트 워킹 디렉토리를 바꿈 (return 0 on success, -1 on error)
- Error case
- path를 잘못 쓸경우
- path에 있는 모든 디렉토리에 대한 execute permission이 있어야 한다.
Function: getcwd(3)
#include <unistd.h>
char *getcwd(char *name, size_t size);
- 커랜트 워킹 디렉토리의 이름을 리턴 (return NULL on error)
- size_t size는 name의 size보다 커야함
Function: ftw(3)
#include <unistd.h>
int ftw(const char *path, int(*func)(), int nopenfd);
- 시작점으로부터 모든 디렉토리에대해 function을 수행
- Argument
- path : directory의 path
- depth(nopenfd) : 동시에 몇개의 file을 execute할 수 있는지
- func : 수행될 함수