File System Jo, Heeseung
유닉스파일의특징 [1] 파일 유닉스에서파일은데이터저장, 장치구동, 프로세스간통신등에사용 일반파일, 디렉토리, 특수파일 일반파일 텍스트파일, 실행파일, 라이브러리, 이미지등유닉스에서사용하는대부분의파일 디렉토리 디렉토리도파일로취급 디렉토리에속한파일의목록과 inode 를가진파일 특수파일 - 장치파일 장치를파일로표현 예 : /dev/sda1 2
유닉스파일의특징 [1] 3
유닉스파일의특징 [2] 파일의종류구분 ls l 명령으로파일의종류확인 - 결과의맨앞글자로구분 # ls -l /usr/bin/vi -r-xr-xr-x 5 root bin 193968 2007 9 월 14 일 /usr/bin/vi 파일종류식별문자 4
유닉스파일의특징 [3] 파일의구성요소 파일명 inode 파일명, inode, 데이터블록 사용자가파일에접근할때사용 파일명과관련된 inode 가반드시존재 최대 255 자까지가능 대소문자를구분 '.' 으로시작하면숨김파일 번호로표시 두부분으로나누어정보저장 - 파일정보를저장하는부분 ( 메타데이터 ) - 데이터블록의주소저장하는부분 ls i 명령으로 inode 번호확인 데이터블록 실제로데이터가저장되는부분 5
파일정보검색 [1] 파일명으로파일정보검색 : stat(2) #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> int stat(const char *restrict path, struct stat *buf); inode 에저장된파일정보검색 path 에검색할파일의경로지정 - 검색한정보를 buf 에저장 stat 구조체 struct stat { dev_t ino_t mode_t nlink_t uid_t gid_t dev_t off_t time_t time_t time_t blksize_t blkcnt_t char }; st_dev; st_ino; st_mode; st_nlink; st_uid; st_gid; st_rdev; st_size; st_atime; st_mtime; st_ctime; st_blksize; st_blocks; st_fstype[_st_fstypsz]; 6
[ 예제 3-1] 파일명으로 inode 정보검색하기 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <stdio.h> 04 05 int main(void) { 06 struct stat buf; 07 08 stat("unix.txt", &buf); 09 10 printf("inode = %d\n", (int)buf.st_ino); 11 printf("mode = %o\n", (unsigned int)buf.st_mode); 12 printf("nlink = %o\n",(unsigned int) buf.st_nlink); 13 printf("uid = %d\n", (int)buf.st_uid); 14 printf("gid = %d\n", (int)buf.st_gid); 15 printf("size = %d\n", (int)buf.st_size); 16 printf("atime = %d\n", (int)buf.st_atime); 17 printf("mtime = %d\n", (int)buf.st_mtime); 18 printf("ctime = %d\n", (int)buf.st_ctime); 19 printf("blksize = %d\n", (int)buf.st_blksize); 20 printf("blocks = %d\n", (int)buf.st_blocks); 21 //printf("fstype = %s\n", buf.st_fstype); 22 23 return 0; 24 } # ex3_1.out Inode = 192 Mode = 100644 Nlink = 1 UID = 0 GID = 1 SIZE = 24 Atime = 1231397228 Mtime = 1231397228 Ctime = 1231397228 Blksize = 8192 Blocks = 2 UNIX time: 1970/1/1 00:00:00 (UTC) 부터경과한초 7
파일정보검색 [2] 파일기술자로파일정보검색 : fstat(2) #include <sys/types.h> #include <sys/stat.h> int fstat(int fd, struct stat *buf); fd 로지정한파일의정보를검색하여 buf 에저장 8
파일접근권한제어 stat 구조체의 st_mode 항목에파일의종류와접근권한정보저장 st_mode 값의구조 9
파일접근권한제어 chmod 명령어 파일 / 디렉토리의접근권한을변경 chmod 755 test.out - st_mode 의하위 9 비트를 111 101 101 로변경 chmod -R 644 testdir1 - testdir1 을포함한모든하위파일 / 디렉토리를 644 로변경 10
파일종류검색 [1] 상수를이용한파일종류검색 파일의종류검색관련상수 st_mode 값과 S_IFMT 을 AND(&) 연산하면파일의종류부분만남음 11
[ 예제 3-3] 상수를이용해파일종류검색하기 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <stdio.h> 04 05 int main(void) { 06 struct stat buf; 07 int kind; 08 09 stat("unix.txt", &buf); 10 11 printf("mode = %o (16진수: %x)\n", (unsigned int)buf.st_mode, (unsigned int)buf.st_mode); 12 13 kind = buf.st_mode & S_IFMT; 14 printf("kind = %x\n", kind); 15 16 switch (kind) { 17 case S_IFIFO: 18 printf("unix.txt : FIFO\n"); 19 break; 20 case S_IFDIR: 21 printf("unix.txt : Directory\n"); 22 break; 12
[ 예제 3-3] 상수를이용해파일종류검색하기 23 case S_IFREG: 24 printf("unix.txt : Regular File\n"); 25 break; 26 } 27 28 return 0; 29 } # ex3_3.out Mode = 100644 (16 진수 : 81a4) Kind = 8000 unix.txt : Regular File 13
파일종류검색 [2] 매크로를이용한파일종류검색 각매크로는 mode 값을 0xF000 과 AND 연산수행 AND 연산의결과를파일의종류별로정해진값과비교 14
[ 예제 3-4] 매크로를이용해파일종류검색하기 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <stdio.h> 04 05 int main(void) { 06 struct stat buf; 07 08 stat("unix.txt", &buf); # ex3_4.out Mode = 100644 (16 진수 : 81a4) unix.txt : Regular File 09 printf("mode = %o (16 진수 : %x)\n",(unsigned int)buf.st_mode, (unsigned int)buf.st_mode); 11 12 if(s_isfifo(buf.st_mode)) printf("unix.txt : FIFO\n"); 13 if(s_isdir(buf.st_mode)) printf("unix.txt : Directory\n"); 14 if(s_isreg(buf.st_mode)) printf("unix.txt : Regular File\n"); 15 16 return 0; 17 } 15
파일접근권한검색 [3] 함수를사용한파일접근권한검색 : access(2) #include <unistd.h> int access(const char *path, int amode); path 에지정된파일이 amode 로지정한권한을가졌는지확인 접근권한이있으면 0 을, 오류가있으면 -1 을리턴 오류메시지 - ENOENT : 파일이없음 - EACCESS : 접근권한이없음 amode - R_OK : 읽기권한확인 - W_OK : 쓰기권한확인 - X_OK : 실행권한확인 - F_OK : 파일이존재하는지확인 19
[ 예제 3-6] access 함수를이용해접근권한검색하기 01 #include <sys/errno.h> 02 #include <unistd.h> 03 #include <stdio.h> 04 05 extern int errno; 06 07 int main(void) { 08 int per; 09 # ls -l unix* -rw-r--r-- 1 root other 24 1월 8일 15:47 unix.txt # ex3_6.out unix.bak: File not exist. unix.txt: Read permission is permitted. 10 if (access("unix.bak", F_OK) == -1 && errno == ENOENT) 11 printf("unix.bak: File not exist.\n"); 12 13 per = access("unix.txt", R_OK); 14 if (per == 0) 15 printf("unix.txt: Read permission is permitted.\n"); 16 else if (per == -1 && errno == EACCES) 17 printf("unix.txt: Read permission is not permitted.\n"); 18 19 return 0; 20 } 20
파일접근권한변경 파일명으로접근권한변경 : chmod(2) #include <sys/types.h> #include <sys/stat.h> int chmod(const char *path, mode_t mode); path 에지정한파일의접근권한을 mode 값으로변경 접근권한추가 - OR 연산자 - chmod(path, S_IRWXU S_IRGRP S_IXGRP S_IROTH); - mode = S_IWGRP; 접근권한제거 - NOT 연산후 AND 연산자 - mode &= ~(S_IROTH); 파일기술자로접근권한변경 : fchmod(2) #include <sys/types.h> #include <sys/stat.h> int fchmod(int fd, mode_t mode); 21
파일접근권한변경 POSIX 에서정의한접근권한관련상수 시프트연산없이직접 AND 연산이가능한상수정의 22
[ 예제 3-7] chmod 함수사용하기 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <stdio.h> 04 05 int main(void) { 06 struct stat buf; 07 # ls -l unix.txt -rw-r--r-- 1 root other 24 1월 8일 15:47 unix.txt # ex3_7.out 1.Mode = 100754 2.Mode = 100770 # ls -l unix.txt -rwxrwx--- 1 root other 24 1월 8일 15:47 unix.txt 08 chmod("unix.txt", S_IRWXU S_IRGRP S_IXGRP S_IROTH); 09 stat("unix.txt", &buf); 10 printf("1.mode = %o\n", (unsigned int)buf.st_mode); 11 12 chmod("unix.txt", 0770); 0770? 13 stat("unix.txt", &buf); 14 printf("2.mode = %o\n", (unsigned int)buf.st_mode); 15 16 return 0; 17 } 23
링크파일생성 [1] 링크 이미있는파일이나디렉토리에접근할수있는새로운이름 같은파일 / 디렉토리지만여러이름으로접근할수있게한다 하드링크 : 기존파일과동일한 inode 사용, inode 에저장된링크개수증가 - ln original.txt link.txt 심볼릭링크 : 기존파일에접근하는다른파일생성 ( 다른 inode 사용 ) - ln -s original.txt link.txt 하드링크생성 : link(2) #include <unistd.h> int link(const char *existing, const char *new); 두경로는같은파일시스템에존재해야함 24
[ 예제 3-8] link 함수사용하기 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <unistd.h> 04 #include <stdio.h> 05 06 int main(void) { 07 struct stat buf; 08 09 stat("unix.txt", &buf); # ls -l unix* -rwxrwx--- 1 root other 24 1월 8일 15:47 unix.txt # ex3_8.out Before Link Count = 1 After Link Count = 2 # ls -l unix* -rwxrwx--- 2 root other 24 1월 8일 15:47 unix.ln -rwxrwx--- 2 root other 24 1월 8일 15:47 unix.txt 10 printf("before Link Count = %d\n", (int)buf.st_nlink); 11 12 link("unix.txt", "unix.ln"); 13 14 stat("unix.txt", &buf); 15 printf("after Link Count = %d\n", (int)buf.st_nlink); 16 17 return 0; 18 } 25
링크파일생성 [2] 심볼릭링크생성 : symlink(2) #include <unistd.h> int symlink(const char *name1, const char *name2); 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <unistd.h> 04 05 int main(void) { 06 symlink("unix.txt", "unix.sym"); 07 08 return 0; 09 } # ls -l unix* -rwxrwx--- 2 root other 24 1월 8일 15:47 unix.ln -rwxrwx--- 2 root other 24 1월 8일 15:47 unix.txt # ex3_9.out # ls -l unix* -rwxrwx--- 2 root other 24 1월 8일 15:47 unix.ln lrwxrwxrwx 1 root other 8 1월 11일 18:48 unix.sym -> unix.txt -rwxrwx--- 2 root other 24 1월 8일 15:47 unix.txt 26
심볼릭링크정보검색 심볼릭링크정보검색 : lstat(2) #include <sys/types.h> #include <sys/stat.h> int lstat(const char *path, struct stat *buf); lstat : 심볼릭링크자체의파일정보검색 심볼릭링크를 stat 함수로검색하면원본파일에대한정보를검색 심볼릭링크의내용읽기 : readlink(2) #include <unistd.h> ssize_t readlink(const char *restrict path, char size_t bufsiz); *restrict buf, 심볼릭링크의데이터블록에저장된내용읽기 원본파일의경로읽기 : realpath(3) #include <stdlib.h> char *realpath(const char *restrict file_name, char *restrict resolved_name); 심볼릭링크가가리키는원본파일의실제경로명출력 27
디렉토리관련함수 [1] 디렉토리생성 : mkdir(2) #include <sys/types.h> #include <sys/stat.h> int mkdir(const char *path, mode_t mode); path 에지정한디렉토리를 mode 권한에따라생성 디렉토리삭제 : rmdir(2) #include <unistd.h> int rmdir(const char *path); 디렉토리명변경 : rename(2) #include <stdio.h> int rename(const char *old, const char *new); 33
[ 예제 3-13] 디렉토리생성 / 삭제 / 이름변경하기 01 #include <sys/stat.h> 02 #include <unistd.h> 03 #include <stdlib.h> 04 #include <stdio.h> 05 06 int main(void) { 07 if (mkdir("han", 0755) == -1) { 08 perror("han"); 09 exit(1); 10 } 11 12 if (mkdir("bit", 0755) == -1) { 13 perror("bit"); 14 exit(1); 15 } 16 17 if (rename("han", "hanbit") == -1) { 18 perror("hanbit"); 19 exit(1); 20 } 21 han -> hanbit 로변경 34
[ 예제 3-13] 디렉토리생성 / 삭제 / 이름변경하기 22 if (rmdir("bit") == -1) { 23 perror("bit"); 24 exit(1); 25 } 26 27 return 0; 28 } bit 는생성했다삭제 # ex3_13.out # ls -l drwxr-xr-x 2 root other 512 1월 12일 18:06 hanbit 35
디렉토리관련함수 [2] 현재작업디렉토리위치 : getcwd(3) #include <unistd.h> char *getcwd(char *buf, size_t size); 현재작업디렉토리위치를알려주는명령은 pwd, 함수는 getcwd 디렉토리이동 : chdir(2) #include <unistd.h> int chdir(const char *path); 36
[ 예제 3-14] 작업디렉토리위치검색 / 디렉토리이동하기 01 #include <unistd.h> 02 #include <stdio.h> 03 04 int main(void) { 05 char *cwd; 06 char wd[bufsiz]; 07 08 cwd = getcwd(null, BUFSIZ); 09 printf("1.current Directory : %s\n", cwd); 10 11 chdir("hanbit"); 12 13 getcwd(wd, BUFSIZ); 14 printf("2.current Directory : %s\n", wd); 15 16 return 0; 17 } # ex3_14.out 1.Current Directory : /export/home/jw/syspro/ch3 2.Current Directory : /export/home/jw/syspro/ch3/hanbit 37
디렉토리정보검색 [1] 디렉토리열기 : opendir(3) #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *dirname); typedef struct dirent { ino_t d_ino; off_t d_off; unsigned short d_reclen; char d_name[name_max+1]; } dirent_t; 성공하면열린디렉토리를가리키는 DIR 포인터를리턴 디렉토리닫기 : closedir(3) #include <sys/types.h> #include <dirent.h> int closedir(dir *dirp); 디렉토리정보읽기 : readdir(3) #include <sys/types.h> #include <dirent.h> struct dirent *readdir(dir *dirp); 디렉토리의내용을한번에하나씩읽어옴 38
[ 예제 3-15] 디렉토리열고정보읽기 01 #include <dirent.h> 02 #include <stdlib.h> # ex3_15.out 03 #include <stdio.h> Name :. Inode : 208 04 Name :.. Inode : 189 05 int main(void) { 06 DIR *dp; 07 struct dirent *dent; 08 09 if ((dp = opendir("hanbit")) == NULL) { 10 perror("opendir: hanbit"); 11 exit(1); 12 } 13 14 while ((dent = readdir(dp))) { 15 printf("name : %s ", dent->d_name); 16 printf("inode : %d\n", (int)dent->d_ino); 17 } 18 19 closedir(dp); 20 21 return 0; 22 } 39
[ 예제 3-16] 디렉토리항목의상세정보검색하기 01 #include <sys/types.h> 02 #include <sys/stat.h> 03 #include <dirent.h> 04 #include <stdlib.h> 05 #include <stdio.h> 06 07 int main(void) { 08 DIR *dp; 09 struct dirent *dent; 10 struct stat sbuf; 11 char path[bufsiz]; 12 13 if ((dp = opendir("hanbit")) == NULL) { 14 perror("opendir: hanbit"); 15 exit(1); 16 } 18 while ((dent = readdir(dp))) { 19 if (dent->d_name[0] == '.') continue; 20 else break; 21 } 22 40
[ 예제 3-16] 디렉토리항목의상세정보검색하기 23 sprintf(path, "hanbit/%s", dent->d_name); 24 stat(path, &sbuf); 25 26 printf("name : %s\n", dent->d_name); 27 printf("inode(dirent) : %d\n", (int)dent->d_ino); 28 printf("inode(stat) : %d\n", (int)sbuf.st_ino); 29 printf("mode : %o\n", (unsigned int)sbuf.st_mode); 30 printf("uid : %d\n", (int)sbuf.st_uid); 31 32 closedir(dp); 33 34 return 0; 35 } 디렉토리의항목을읽고다시 stat 함수로상세정보검색 # ls -ai hanbit 208. 189.. 213 han.c # ex3_16.out Name : han.c Inode(dirent) : 213 Inode(stat) : 213 Mode : 100644 Uid : 0 41
디렉토리정보검색 [2] 디렉토리오프셋 : telldir(3), seekdir(3), rewinddir(3) #include <dirent.h> long telldir(dir *dirp); void seekdir(dir *dirp, long loc); void rewinddir(dir *dirp); telldir : 디렉토리오프셋의현재위치를알려줌 seekdir : 디렉토리오프셋을 loc 에지정한위치로이동 rewinddir : 디렉토리오프셋을디렉토의시작인 0 으로이동 42
Exercise Ex. 특정디렉토리내의모든파일이름과 inode 번호를출력하는프로그램을작성./a.out /tmp/dirtest 25067538. 25067521.. 25067540 a.out 25067542 debug 25067543 hello 25067539 hello.c 25067541 perr.c 25067546 winscp437.zip 45
Exercise - Extra Ex. 특정디렉토리내의모든파일이름과 inode 번호를출력하는프로그램을작성 하위에디렉토리가있을경우 recursive 로출력./a.out /tmp/dirtest 25067538. 25067521.. 25067540 a.out 25067542 debug 25067543 dir1 25067539 dir1/hello.c 25067541 dir1/perr.c 25067546 winscp437.zip 46