1 / 53

11 장 파일

11 장 파일. 11.1 시스템 호출. 유닉스 / 리눅스 커널 (kernel). 하드웨어를 운영 관리하여 다음과 같은 서비스를 제공 프로세스 관리 (Process management) 파일 관리 (File management) 메모리 관리 (Memory management) 통신 관리 (Communication management) 주변장치 관리 (Device management). 시스템 호출 (system call). 시스템 호출은 유닉스 / 리눅스 커널에 서비스를 요청하기 위한 프로그래밍 인터페이스

Download Presentation

11 장 파일

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 11장 파일

  2. 11.1 시스템 호출

  3. 유닉스/리눅스 커널(kernel) • 하드웨어를 운영 관리하여 다음과 같은 서비스를 제공 • 프로세스 관리(Process management) • 파일 관리(File management) • 메모리 관리(Memory management) • 통신 관리(Communication management) • 주변장치 관리(Device management)

  4. 시스템 호출(system call) • 시스템 호출은 유닉스/리눅스 커널에 서비스를 요청하기 위한 프로그래밍 인터페이스 • 응용 프로그램은 시스템 호출을 통해서 유닉스/리눅스 커널에 서비스를 요청한다 • /usr/include/asm/unistd_32.h 참조

  5. 11.2 파일

  6. 유닉스/리눅스에서 파일 • 연속된 바이트의 나열 • 특별한 다른 포맷을 정하지 않음 • 디스크 파일뿐만 아니라 외부 장치에 대한 인터페이스

  7. 파일 열기: open() • 파일을 사용하기 위해서는 먼저 open() 시스템 호출을 이용하여 파일을 열어야 한다 • 파일 디스크립터는 열린 파일을 나타내는 번호 • oflag, mode : 교재 331~332 쪽, /usr/include/bits/fcntl.h참조

  8. 파일 열기: 예 • fd =open("account",O_RDONLY); • fd =open(argv[1], O_RDWR); • fd = open(argv[1], O_RDWR | O_CREAT, 0600); • fd = open("tmpfile", O_WRONLY|O_CREAT|O_TRUNC, 0600); • fd =open("/sys/log", O_WRONLY|O_APPEND|O_CREAT, 0600); • if ((fd =open("tmpfile", O_WRONLY|O_CREAT|O_EXCL, 0666))==-1)

  9. fopen.c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> int main(int argc, char *argv[]) { int fd; if ((fd = open(argv[1], O_RDWR)) == -1) perror(argv[1]); printf("파일 %s 열기 성공\n", argv[1]); close(fd); exit(0); } • fd 번호를 출력해보세요! • 매개변수없을 경우도 잘 처리하도록 debug 해보세요!

  10. 파일 생성: creat() • creat() 시스템 호출 • path가 나타내는 파일을 생성하고 쓰기 전용으로 연다 • 생성된 파일의 사용권한은 mode로 정한다 • 기존 파일이 있는 경우에는 그 내용을 삭제하고 연다 • 다음 시스템 호출과 동일 open(path, WRONLY | O_CREAT | O_TRUNC, mode);

  11. 파일 닫기: close() • close() 시스템 호출은 fd가 나타내는 파일을 닫는다

  12. 데이터 읽기: read() • read() 시스템 호출 • fd가 나타내는 파일에서 • nbytes 만큼의 데이터를 읽고 • 읽은 데이터는 buf에 저장한다

  13. fsize.c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> //#include <unistd.h> #define BUFSIZE 512 /* 파일 크기를 계산한다 */ int main(int argc, char *argv[]) { char buffer[BUFSIZE]; int fd; ssize_t nread; long total = 0; if ((fd = open(argv[1], O_RDONLY)) == -1) perror(argv[1]); /* 파일의 끝에 도달할 때까지 반복해서 읽으면서 파일 크기 계산 */ while((nread = read(fd, buffer, BUFSIZE)) > 0) total += nread; close(fd); printf ("%s 파일 크기 : %ld 바이트 \n", argv[1], total); exit(0); } $ gcc –o fsizefsize.c $ fsize xx 매개변수없을 경우도 잘 처리하도록 debug 해보세요!

  14. 데이터 쓰기: write() • write() 시스템 호출 • buf에 있는 nbytes 만큼의 데이터를 fd가 나타내는 파일에 쓴다

  15. fcp.c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> /* 파일 복사 프로그램 */ main(int argc, char *argv[]) { int fd1, fd2, n; char buf[BUFSIZ]; if (argc != 3) { fprintf(stderr,"사용법: %s file1 file2\n", argv[0]); exit(1); } if ((fd1 = open(argv[1], O_RDONLY)) == -1) { perror(argv[1]); exit(2); } if ((fd2 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { perror(argv[2]); exit(3); } while ((n = read(fd1, buf, BUFSIZ))> 0) write(fd2, buf, n); // 읽은 내용을 쓴다 exit(0); } BUFSIZ 값 출력해보기 $ grepBUFSIZ /usr/include/*  O_APPEND

  16. (보충) $ man $ man read $ whatis read $ man –f read (Unix) $ man –l read read (1p) - read a line from standard input read (2) - read from a file descriptor read (3p) - read from a file read [builtins] (1) - bash built-in commands, see bash(1) $ man –s 2 read 또는 $ man2 read $ man –M /usr/share/man 2 read (목록의 manpage가 나오지 않을 경우) $ man man 1절 명령어 2절 시스템 호출 3절 라이브러리 함수 4절 특수화일 5절 파일 형식 6절 게임 7절 기타 정보 8절 유지보수 명령어 9절 커널 루틴 1 Executable programs or shell commands 2 System calls (functions provided by the kernel) 3 Library calls (functions within program libraries) 4 Special files (usually found in /dev) 5 File formats and conventions eg /etc/passwd 6 Games 7 Miscellaneous (including macro packages and conven-tions 8 System administration commands (usually only for root) 9 Kernel routines [Non standard]

  17. (보충) set-user-id set-group-id set-sticky-bit • Symbolic File Access Modes $ chmod a=rw xx $ chmod g+x xx $ chmod g-rwx xx $ chmod g=u xx • Octal File Access Modes $ chmod 644 xx $ chmod 751 xx $ chmod 000 xx • 실행파일에 대하여 • 4000 set user ID : $ chmod 4751 xx • $ chmod u+s myfile • 2000 set group ID : $ chmod 2751 xx • $ chmod g+s myfile • 1000 set sticky bit : $ chmod 1751 xx • $ chmod o+t myfile $ find / -perm -4755 -ls > result $ find / -perm -4700 -ls > result • 디렉터리에 대하여 • 1000 set sticky bit : $ chmod 1777 /share • 그 디렉터리 안의 파일제거 또는 이름 변경은 파일 소유자, 디렉터리 소유자, 수퍼유저만 가능 • 디렉터리 소유자 아닌 다른 사용자는 그 안에 자기파일 생성만 가능 • umask (user mask) : file 생성시 허가권 제한 - rws r-x --x - 100 111 101 001 - rwx r-s --x - 010 111 101 001 - rwx r-x --t - 001 111 101 001

  18. (보충) IA-32(Intel Architecture, 32-bit)정수 표현 Q:IA-32(Intel Architecture, 32-bit) 정수형 데이터음수표현 방법은? • signed& unsigned • char(8bit), short(16bit), int(32bit), long(64bit), long long(128bit) • 리틀 엔디안(Little-Endian) 사용 • 고정 소수점 (Fixed-Point) 표현 • 첫 번째 비트는 부호 비트 양수(+)는 0, 음수(-)는 1로 표시 • 나머지는 정수부가 저장되고, 소수점은 맨 오른쪽에 있는 것으로 가정 • 고정 소수점 음수 표현 방법 • 부호와 절대치(signed-magnitude) 양수 표현에 대하여 부호 비트만 1로 변경 • 1의 보수(1’s complement) 양수 표현에 대하여 1의 보수 계산 • 2의 보수(2’s complement) 양수 표현에 대하여 2의 보수 계산(reverse+1) • (예) shortscore = 99; • 99 = 6*16 + 3 = 0x63 • 0000 0000 0110 0011 • (예) shortscore = -99; • -99 = -6*16 - 3 = -0x63 • (부호와절대치) 1000 0000 0110 0011 • (2의 보수) 1111 1111 1001 1101

  19. (보충) 비트단위 정수 출력 bitwise.c $ gcc –o bitwisebitwise.c $ bitwise -99 #include <stdio.h> #include <limits.h> void bit_print(short); main(int arc, char *argv[]) { short i=atoi(argv[1]), mask=1; bit_print(i); printf("\n정수: %d\n", i); } void bit_print(short a) { int i; int n=sizeof(short) * CHAR_BIT; /* /usr/include/limits.h 55행 */ printf("n=%d, sizeof(short)=%d, CHAR_BIT=%d\n", n, sizeof(short), CHAR_BIT); int mask = 1 << (n-1); for (i=1; i<=n; ++i) { putchar(((a & mask) == 0) ? '0' : '1'); a <<= 1; if(i % (CHAR_BIT/2) == 0 && i < n) putchar(' '); } } • short 형을 int 형으로 수정하세요! • 매개변수없을 경우도 잘 처리하도록 debug 하세요!

  20. 11.3 현재 파일 위치

  21. 파일 위치 포인터(file position pointer) • 파일 위치 포인터는 파일 내에 읽거나 쓸 위치인 현재 파일 위치(current file position)를 가리킨다.

  22. 파일 위치 포인터 이동: lseek() • lseek() 시스템 호출 • 임의의 위치로 파일 위치 포인터를 이동시킬 수 있다.

  23. 파일 위치 포인터이동: 예 • 파일 위치 이동 • lseek(fd, 0L, SEEK_SET);파일 시작으로 이동(rewind) • lseek(fd, 100L, SEEK_SET);파일 시작에서 100바이트 위치로 • lseek(fd, 0L, SEEK_END);파일 끝으로 이동(append) • 레코드 단위로 이동 • lseek(fd, n * sizeof(record), SEEK_SET); n+1번째 레코드 시작위치로 • lseek(fd, sizeof(record), SEEK_CUR); 다음 레코드 시작위치로 • lseek(fd, -sizeof(record), SEEK_CUR);전 레코드 시작위치로 • 파일끝 이후로 이동 • lseek(fd, sizeof(record), SEEK_END); 파일끝에서 한 레코드 다음 위치로

  24. 레코드 저장 예 $ vi student.h #define MAX 20 struct student { int id; char name[MAX]; int score; }; • write(fd, &record1, sizeof(record)); • write(fd, &record2, sizeof(record)); • lseek(fd, sizeof(record), SEEK_END); • write(fd, &record3, sizeof(record));

  25. dbcreate.c if ((fd = open(argv[1], O_WRONLY | O_CREAT | O_EXCL, 0640)) == -1) { perror(argv[1]); exit(2); } printf("%7s %6s %4s\n", "학번", "이름", "점수"); while (scanf("%d %s %d", &record.id, record.name, &record.score) == 3) { lseek(fd, (record.id - START_ID) * sizeof(record), SEEK_SET); write(fd, (char *) &record, sizeof(record) ); } close(fd); exit(0); } #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include "student.h" #define START_ID 1201001 /* 학생 정보를 입력받아 데이터베이스 파일에 저장한다 */ int main(int argc, char *argv[]) { int fd; struct student record; if (argc < 2) { fprintf(stderr, "사용법 : %s file\n", argv[0]); exit(1); } $ gcc –o dbcreate.c dbcreate.c $ dbcreate stdb

  26. dbquery.c do { printf("검색할 학생의 학번 입력: "); if (scanf("%d", &id) == 1) { lseek(fd, (id-START_ID)*sizeof(record), SEEK_SET); if ((read(fd, (char *) &record, sizeof(record)) > 0) && (record.id != 0)) printf("이름:%s\t 학번:%d\t 점수:%d\n", record.name, record.id, record.score); else printf("레코드 %d 없음\n", id); } else printf("입력 오류"); printf("계속하겠습니까?(Y/N) "); scanf(" %c", &c); } while (c=='Y'); close(fd); exit(0); } #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include "student.h" #define START_ID 1201001 /* 학번을 입력받아 해당 학생의 레코드를 파일에서 읽어 출력한다 */ int main(int argc, char *argv[]) { int fd, id; char c; struct student record; if (argc < 2) { fprintf(stderr, "사용법 : %s file\n", argv[0]); exit(1); } if ((fd = open(argv[1], O_RDONLY)) == -1) { perror(argv[1]); exit(2); } $ gcc –o dbquery.c dbquery.c $ dbcreate stdb

  27. 레코드 수정과정 (1) 파일로부터 해당 레코드를 읽어서 (2) 이 레코드를 수정한 후에 (3) 수정된 레코드를 다시 파일 내의 원래 위치에 써야 한다

  28. dbupdate.c do { printf("수정할 학생의 학번 입력: "); if (scanf("%d", &id) == 1) { lseek(fd, (long) (id-START_ID)*sizeof(record), SEEK_SET); if ((read(fd, (char *) &record, sizeof(record)) > 0) && (record.id != 0)) { printf("학번:%8d\t 이름:%4s\t 점수:%4d\n", record.id, record.name, record.score); printf("새로운 점수: "); scanf("%d", &record.score); lseek(fd, (long) -sizeof(record), SEEK_CUR); write(fd, (char *) &record, sizeof(record)); } else printf("레코드 %d 없음\n", id); } else printf("입력오류\n"); printf("계속하겠습니까?(Y/N)"); scanf(" %c",&c); } while (c == 'Y'); close(fd); exit(0); } #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include "student.h" #define START_ID 1201001 /* 학번을 입력받아 해당 학생 레코드를 수정한다 */ int main(int argc, char *argv[]) { int fd, id; char c; struct student record; if (argc < 2) { fprintf(stderr, "사용법 : %s file\n", argv[0]); exit(1); } if ((fd = open(argv[1], O_RDWR)) == -1) { perror(argv[1]); exit(2); } $ gcc –o dbupdate.c dbupdate.c $ dbupdate stdb

  29. 11.4 파일 상태 정보

  30. 파일 상태(file status) • 파일 상태 • 파일에 대한 모든 정보 • 블록수, 파일 타입, 접근 권한, 링크수, 파일 소유자의 사용자 ID, • 그룹 ID, 파일 크기, 최종 수정 시간 등 • 예 $ ls -sl hello 2 -rw-r--r-- 1 mysung other 617 11월 26일 15:59 hello.c 블록수 사용권한 링크수 사용자ID 그룹ID 파일크기 최종 수정 시간 파일이름  파일 타입 Linux: $ getconfPAGESIZE 또는 PAGE_SIZE (4096) Solaris: $ pagesize –a (4096, 2097152)

  31. 상태 정보: stat() • 파일 하나당 하나의 i-노드가 있으며 • i-노드 내에 파일에 대한 모든 상태 정보가 저장되어 있다 Q: stat()과 lstat()의 차이점은?  $ man –s 2 stat

  32. stat 구조체 • /usr/include/sys/stat.h 107행  /usr/include/bits/stat.h 39행 참조 struct stat { dev_t st_dev; /* 장치 */ ino_t st_ino; /* inode 번호 */ mode_t st_mode; /* 파일타입과 사용권한 */ nlink_t st_nlink; /* 하드 링크 수 */ uid_t st_uid; /* 소유자의 사용자 ID */ gid_t st_gid; /* 소유자의 그룹 ID */ dev_t st_rdev; /* 장치이면 장치 번호 */ off_t st_size; /* 파일의 바이트 크기 */ unsigned long st_blksize; /* 파일시스템 I/O 최적블록크기 */ unsigned long st_blocks; /* 파일에 할당 된 512-byte 블록 수 */ time_t st_atime; /* 최종 접근 시간 */ time_t st_mtime; /* 최종 수정 시간 */ time_t st_ctime; /* 최종 상태 변경 시간 */ };

  33. 파일 타입과 매크로 함수 • /usr/include/sys/stat.h 127행참조 • /usr/include/bits/stat.h 142행 참조

  34. ftype.c $ gcc –o ftype ftype.c $ ln -s xx yy $ ftype xx yy $ ftype * $ ftype /dev/* | more • st_ino와 st_size 출력해 보세요! • Q: stat()과 lstat()의 차이점은? #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> /* 파일 타입을 검사한다. */ int main(int argc, char *argv[]) { int i; struct stat buf; for (i = 1; i < argc; i++) { printf("%s: ", argv[i]); if (lstat(argv[i], &buf) < 0) { perror("lstat()"); continue; } if (S_ISREG(buf.st_mode)) printf("%s\n", "일반 파일"); if (S_ISDIR(buf.st_mode)) printf("%s\n", "디렉터리"); if (S_ISCHR(buf.st_mode)) printf("%s\n", "문자 장치 파일"); if (S_ISBLK(buf.st_mode)) printf("%s\n", "블록 장치 파일"); if (S_ISFIFO(buf.st_mode)) printf("%s\n", "FIFO 파일"); if (S_ISLNK(buf.st_mode)) printf("%s\n", "심볼릭 링크"); if (S_ISSOCK(buf.st_mode)) printf("%s\n", "소켓"); } exit(0); }

  35. 파일 상태 정보 변경 • chmod() 시스템 호출 • 파일의 상태 정보를 변경

  36. fchmod.c #include <stdio.h> #include <stdlib.h> /* 파일 사용권한을 변경한다 */ main(int argc, char *argv[]) { long int strtol( ); int newmode; newmode = (int) strtol(argv[1],(char **) NULL, 8); if (chmod(argv[2], newmode) == -1) { perror(argv[2]); exit(1); } exit(0); } $ gcc –o fchmod fchmod.c $ fchmod 666 xx $ ls –asl xx $ manatoi int atoi(const char *nptr); = strtol(nptr, (char **)NULL, 10); # include <sys/types.h> /usr/include/stdlib.h 320행 typedef __mode_t mode_t; /usr/include/sys/types.h 71행 # define __STD_TYPE typedef /usr/include/bits/types.h 127행 __STD_TYPE __MODE_T_TYPE __mode_t; /usr/include/bits/types.h 139행 #include <bits/typesizes.h> /usr/include/bits/types.h 131행 #define __MODE_T_TYPE __U32_TYPE /usr/include/bits/typesizes.h 35행 #define __U32_TYPE unsigned int /usr/include/bits/types.h 102행

  37. 11.5 디렉터리

  38. 디렉터리 구현 • 디렉터리 내에는 무엇이 저장되어 있을까? • 디렉터리 엔트리 #include <dirent.h> • /usr/include/dirent.h 30행 • #include <bits/dirent.h> • /usr/include/bits/dirent.h 23행 struct dirent { #ifndef __USE_FILE_OFFSET64 __ino_t d_ino; __off_t d_off; #else __ino64_t d_ino; __off64_t d_off; #endif unsigned short int d_reclen; unsigned char d_type; char d_name[256]; /* We must not include limits.h! */ }; DIR

  39. 디렉터리 리스트 • opendir() • 디렉터리 열기 함수 • DIR 포인터(열린 디렉터리를 가리키는 포인터) 리턴 • readdir() • 디렉터리 읽기 함수 typedef struct __dirstream DIR; /usr/include/dirent.h 128행

  40. list1.c $ gcc –o list1 list1.c $ list1 $ list1 /usr #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <stdio.h> #include <stdlib.h> /* 디렉터리 내의 파일 이름들을 리스트한다 */ int main(int argc, char **argv) { DIR *dp; char *dir; struct dirent *d; struct stat st; char path[BUFSIZ+1]; if (argc == 1) dir = "."; // 현재 디렉터리를 대상으로 else dir = argv[1]; if ((dp = opendir(dir)) == NULL) // 디렉터리 열기 perror(dir); while ((d = readdir(dp)) != NULL) // 각 디렉터리 엔트리에 대해 printf("%s \n", d->d_name); // 파일 이름 프린트 closedir(dp); exit(0); }

  41. 파일 이름/크기 프린트 • 디렉터리 내에 있는 파일 이름과 그 파일의 크기(블록의 수)를 프린트하도록 확장 while ((d = readdir(dp))!= NULL) { //디렉터리 내의 각 파일 sprintf(path, "%s/%s", dir, d->d_name); // 파일경로명 만들기 if (lstat(path, &st) < 0) // 파일 상태 정보 가져오기 perror(path); printf("%5d %s", st->st_blocks, d->name); // 블록 수, 파일 이름 출력 putchar('\n'); }

  42. 디렉터리 리스트: 예 • list2.c • ls –l 명령어처럼 파일의 모든 상태 정보를 프린트 • 프로그램 구성 • main() 메인 프로그램 • printStat() 파일 상태 정보 프린트 • type() 파일 타입 리턴 • perm() 파일 접근권한 리턴 Q: 한 블록의크기는? Linux: $ getconfPAGESIZE 또는 PAGE_SIZE (4096) Solaris: $ pagesize –a (4096, 2097152)

  43. list2.c #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <pwd.h> #include <grp.h> #include <stdio.h> #include <stdlib.h> char type(mode_t); char *perm(mode_t); void printStat(char*, char*, struct stat*); int main(int argc, char **argv) /* 디렉터리 내용을 자세히 리스트한다 */ { DIR *dp; char *dir; struct stat st; struct dirent *d; char path[BUFSIZ+1]; if (argc == 1) dir = "."; else dir = argv[1]; if ((dp = opendir(dir)) == NULL) /* 디렉터리 열기 */ perror(dir); while ((d = readdir(dp)) != NULL) { /* 디렉터리의 각 파일에 대해 */ sprintf(path, "%s/%s", dir, d->d_name); /* 파일경로명 만들기 */ if (lstat(path, &st) < 0) /* 파일 상태 정보 가져오기 */ perror(path); printStat(path, d->d_name, &st); /* 상태 정보 출력 */ putchar('\n'); } closedir(dp); exit(0); } $ gcc –o list2 list2.c $ list2 $ list2 | sort +9 -10 $ ls -asl $ list2 /bin (/bin/su 파일로 확인)

  44. list2.c (계속) • 교재 코드 Debug  채워 넣으세요 • st_ino 출력해 보세요 • Q: 파일시스템 I/O 최적블록크기는? char* perm(mode_t mode) { int i; static char perms[10] = "---------"; for (i=0; i < 3; i++) { if (mode & (S_IREAD >> i*3)) perms[i*3] = 'r'; if (mode & (S_IWRITE >> i*3)) perms[i*3+1] = 'w'; if (mode & (S_IEXEC >> i*3)) perms[i*3+2] = 'x'; } /* setuser ID * * set group ID * * set sticky bit */ return(perms); } /* 파일 상태 정보를 출력 */ void printStat(char *pathname, char *file, struct stat *st) { printf("%5d ", st->st_blocks); printf("%c%s ", type(st->st_mode), perm(st->st_mode)); printf("%3d ", st->st_nlink); printf("%s %s ", getpwuid(st->st_uid)->pw_name, getgrgid(st->st_gid)->gr_name); printf("%9d ", st->st_size); printf("%.12s ", ctime(&st->st_mtime)+4); printf("%s", file); } /* 파일 타입을 리턴 */ char type(mode_t mode) { if (S_ISREG(mode)) return('-'); if (S_ISDIR(mode)) return('d'); if (S_ISCHR(mode)) return('c'); if (S_ISBLK(mode)) return('b'); if (S_ISLNK(mode)) return('l'); if (S_ISFIFO(mode)) return('p'); if (S_ISSOCK(mode)) return('s'); } /usr/include/bits/stat.h 161행 참조 #define __S_ISUID 04000 /* Set user ID on execution. */ #define __S_ISGID 02000 /* Set group ID on execution. */ #define __S_ISVTX 01000 /* Save swapped text after use (sticky). #define __S_IREAD 0400 /* Read by owner. */ #define __S_IWRITE 0200 /* Write by owner. */ #define __S_IEXEC 0100 /* Execute by owner. */

  45. 디렉터리 만들기 • mkdir() 시스템 호출 • path가 나타내는 새로운 디렉터리를 만든다 • "." 와 ".." 파일은 자동적으로 만들어진다

  46. 디렉터리 삭제 • rmdir() 시스템 호출 • path가 나타내는 디렉터리가 비어 있으면 삭제한다

  47. 링크 • 링크는 기존 파일에 대한 또 다른 이름으로 • 하드 링크와 심볼릭(소프트) 링크가 있다

  48. 링크의 구현 • link() 시스템 호출 • 기존 파일 existing에 대한 새로운 이름 new 즉 링크를 만든다

  49. 하드 링크 vs 심볼릭 링크 • 하드 링크(hard link) • 지금까지 살펴본 링크 • 파일 시스템 내의 i-노드를 가리키므로 • 같은 파일 시스템 내에서만 사용될 수 있다 • 심볼릭 링크(symbolic link) • 소프트 링크(soft link) • 실제 파일의 경로명 저장하고 있는 링크 • 파일에 대한 간접적인 포인터 역할을 한다 • 다른 파일 시스템에 있는 파일도 링크할 수 있다

  50. link.c #include <unistd.h> #include <stdlib.h> int main(int argc, char *argv[ ]) { if (link(argv[1], argv[2]) == -1) { exit(1); } exit(0); }

More Related