Linux/UNIX Programming 문양세강원대학교 IT대학컴퓨터과학전공
강의목표및내용 강의목표 파일의특성을이해한다. 파일을열고닫는다. 파일로부터데이터를읽고쓴다. 기타파일제어함수를익힌다. 강의내용 파일구조 (UNIX 파일은어떤구조일까?) 파일관련시스템호출 시스템호출의효율과구조 Page 2
What is a File? A file is a contiguous sequence of bytes. (UNIX 에서파일은연속적인바이트시퀀스로볼수있다.) No format imposed by the operating system. (UNIX 운영체제는파일에특별한 Format 을부여치않는다.) Each byte is individually addressable in a disk file. ( 파일의각바이트는고유의주소를가지고 ( 매길수 ) 있다.) Page 3
File Descriptor (1/2) open() returns an fd, an integer value. Used in subsequent I/O operations on that file. (Open 된파일의 fd 는이후 File I/O 연산에사용된다.) close(fd) closes that file described by fd. All of a process's open files are automatically closed when it terminates. ( 프로세스가종료되면, 해당프로세스가 Open 한파일은자동적으로 Close 된다.) Page 4
File Descriptor (2/2) file descriptor: 0 ~ N (N = 19? or more) // unistd.h Value Meaning 0 standard input 1 standard output 2 standard error 3.. 19 fds for users Page 5
파일을위한 Kernel 자료구조 skip open file table v-node table fd status flags v-node information current file offset v-node ptr i-node file descriptors information fd 0: fd flags ptr current file size fd 1: fd 2: fd 3:.... v-node fd status flags information current file offset i-node v-node ptr information process table entry The meaning of each field will be explained in next slides. current file size Page 6
Process Table Entry skip 프로세스테이블 (Process Table) 커널 (kernel) 자료구조 프로세스목록 프로세스 프로세스테이블항목 프로세스테이블항목 (Process Table Entry) 파일구분자 (file descriptor) 의배열을포함 Page 7
Open File Table skip 파일테이블 (File Table) 커널자료구조 열려진모든파일목록 열려진파일 파일테이블의항목 파일테이블항목 (File Table Entry) 파일상태플래그 (read, write, append, sync, nonblocking, ) open() 시주는정보 파일의현재위치 (current file offset) v-node에대한포인터 Page 8
v-node skip v-node 의내부 파일의유형 ( 일반, 디렉토리, 특수파일, ) 함수들에대한포인터배열 : 이파일을다루는데사용되는함수들 i-node 하드디스크에저장되어있는자료구조 파일에대한 ( 실질적인 ) 정보를가지고있음 소유자, 크기 파일이위치한장치 ( 실제가장중요한정보에해당함 ) 파일내용디스크블럭에대한포인터 ( 실제가장중요한정보에해당함 ) Page 9
파일관련 System Calls open() 열기 creat() - 파일생성 close() read() 닫기 읽기 write() 쓰기 lseek() - 이동 Page 10
open() 파일열기 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open (const char *pathname, int oflag, [ mode_t mode ]); 파일을연다. 파일이없으면경우에따라새로만들어질수도있다. pathname mode : 파일의이름 : 파일의 access permission 값으로, 생략가능새로운파일을만드는경우에만사용됨 (creat() 함수설명참조 ) 리턴값 : 파일식별자 (file descriptor), 실패하면 -1 Page 11
open() 의파라미터 (1/2) 두번째파라미터 oflag 는다음상수들의 (logical) OR 이다. 예 int fd; fd = open("afile", O_RDWR O_CREAT, 0644); 열기모드에대해서, 반드시하나를지정해주어야한다. O_RDONLY : 읽기모드, write 함수를사용할수없음 O_WRONLY : 쓰기모드, read 함수를사용할수없음 O_RDWR : 읽고쓰기모드, read 및 write 사용가능 Page 12
open() 의파라미터 (2/2) 선택적지정가능플래그 O_APPEND : 모든 write 된데이터는파일의끝에추가된다. O_CREAT : 파일이없을경우파일을생성한다 ( 이경우, 세번째인자mode가사용 ). O_EXCL : 그이름의파일이이미있고 O_CREAT를지정한경우에러를발생시킨다. O_TRUNC : 파일이있는경우에기존내용을지우고, 파일크기를 0으로만든다. O_SYNC : 각 write 함수호출은디스크에물리적으로쓰여진후리턴한다 Page 13
예제 : open.c Page 14
creat() 파일생성 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int creat ( const char *pathname, mode_t mode ); 새로운파일을생성한다. pathname mode : 파일의이름 : 파일의 access permission 값 리턴값 : 파일식별자 (file descriptor), 실패하면 -1 Page 15
creat() 의파라미터 다음두함수의호출은동일한기능을수행함 fd = creat ( pathname, mode ); fd = open ( pathname, O_WRONLY O_CREAT O_TRUNC, mode); 두번째파라미터인 mode 는 permission mode 를나타냄 0644 -rw-r--r-- 0755 -rwxr-xr-x 0444 -r--r--r-- Page 16
close() 파일닫기 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int close ( int filedesc ); 작업이끝난후파일을닫는다. 파일을닫지않더라도프로세스가종료하면, 모든열려진파일들은자동적으로닫힌다. filedesc : 닫고자하는파일의파일식별자 (File Descriptor) 리턴값 : 파일식별자 (file descriptor), 실패하면 -1 Page 17
read() 파일읽기 (1/2) #include <unistd.h> ssize_t read ( int filedes, void *buf, size_t nbytes ); 파일에서데이터를읽는다. buf: 읽은데이터를저장할메모리 ( 버퍼 ) nbytes: 읽을데이터의바이트수 리턴값 성공하면읽은바이트수 (nbytes 와다를수 ( 작을수 ) 있음 ) 파일의끝을만나면 0 실패하면 -1 Page 18
read() 파일읽기 (2/2) 읽을데이터가충분하면한번에 nbytes 만큼읽는다. 읽을데이터가 nbytes 보다적은경우더적게읽기도한다. 파일의끝에다다른경우 네트웍입출력을수행하는경우 참고 size_t : unsigned integer ssize_t : signed integer Page 19
예제 : count.c ( 문자수세는프로그램 ) (1/2) Page 20
예제 : count.c ( 문자수세는프로그램 ) (2/2) Page 21
write() 파일쓰기 #include <unistd.h> ssize_t write (int filedes, const void *buf, size_t nbytes); 파일에데이터를쓴다. buf: 쓸데이터를저장한메모리 ( 버퍼 ) nbytes: 쓸데이터의바이트수 리턴값 성공하면, 파일에쓰여진데이터의바이트수 (nbytes 보다작을수있음 ) 실패하면 -1 Page 22
lseek() 오프셋 ( 커서 ) 이동 (1/2) #include <sys/types.h> #include <unistd.h> off_t lseek (int filedes, off_t offset, int whence ); 파일의현재위치 (current file offset) 를이동한다. 파라미터설명 whence: ( 이동을시작할 ) 위치의기준점 SEEK_SET : 파일의시작점을기준으로이동 SEEK_CUR : 현재위치를기준으로이동 SEEK_END : 파일의끝을기준으로이동 offset: 기준점에서의상대적인거리 (byte 단위 ) SEEK_CUR, SEEK_END 와같이쓰일때는음수도가능 리턴값 : 성공하면이동한현재위치를리턴, 실패하면 -1 Page 23
lseek() 오프셋 ( 커서 ) 이동 (2/2) 파일의현재위치 ( 오프셋 ) 를임의의위치로이동한다 파일의현재위치 (current file offset) 파일에대한읽기 / 쓰기는파일의현재위치에서실행된다. 파일을처음열면현재위치는 0, 즉파일의시작이다. 읽기 / 쓰기후파일의현재위치는읽기 / 쓰기한 byte 수만큼저절로뒤로이동된다. lseek() 를사용하여임의의위치로파일의현재위치를이동할수있다 Page 24
예제 : lseek1.c (1/3) Page 25
예제 : lseek1.c (2/3) lseek1.c 의출력파일 file.hole 의내용 0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j 10 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 20 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 30 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 40 A B C D E F G H I J UNIX 명령어인 od (octal dump) 를사용하여확인할수있음 Page 26
예제 : lseek1.c (3/3) Page 27
fcntl() 파일제어 #include <sys/types.h> #include <fcntl.h> #include <unistd.h> int fcntl (int filedes, int cmd, /* int arg */ ); 역할 : 파일의속성을알아내거나변경한다. cmd: F_GETFL, F_SETFL, F_GETFD, F_SETFD, F_DUPFD, 리턴값 성공인경우 : 파라미터인 cmd 에따라다름 실패인경우 : -1 Page 28
fcntl() 의주요사용법 F_GETFL : file table 의 file status flags 를리턴 F_SETFL : file status flags 를설정 File status flag O_RDONLY O_WRONLY O_RDWR O_APPEND O_NONBLOCK O_SYNC O_ASYNC Description open for reading only open for writing only open for reading and writing append on each write nonblocking mode wait for writes to complete asynchoronouse I/O Page 29
예제 : fileflags.c (1/2) Page 30
예제 : fileflags.c (2/2) Page 31
Asynchronous Write UNIX 에서의 Write 는 Asynchronous Write 이다. 데이터가디스크에쓰여지길기다리지않고, 쓰여질데이터를큐 (queue) 에등록하고바로리턴한다. 큐에등록된데이터는나중에 (Scheduling 에의해한꺼번에 ) 디스크에쓰여진다 Synchronous Write Write 호출은데이터가실제로디스크에쓰여진후리턴한다. Asynchronous Write 에비해서 Clock Time 이증가한다. File Table 의 File Status Flags 에서 O_SYNC 플래그를설정한다. Page 32
예제 : write2.c (1/3) Page 33
예제 : write2.c (2/3) Page 34
예제 : write2.c (3/3) Page 35
실험결과 BUFFSIZE User CPU System CPU Clock time (seconds) (seconds) (seconds) #loops asynchrohous 8,192 0.0 1.1 3.6 12,800 synchrohous 8,192 0.0 3.4 180.3 12,800 상기결과에서볼수있듯이 Synchronous Write 가훨씬더느림 DBMS(Database Management System) 처럼실제로데이터가디스크에기 록되었는지여부가중요한경우에사용됨 Page 36
에러처리 파라미터 errno 값에해당하는에러메시지를리턴한다. #include <stdio.h> void perror(const char *msg); 표준에러에다음과같은순서로메시지를출력한다. msg 출력 문자열 ": " 출력 시스템전역변수 (system global l variable) errno 값에해당하는에러메시지출력 Page 37
write_num.c / read_num.c (1/3) Page 38
write_num.c / read_num.c (2/3) Page 39
write_num.c / read_num.c (3/3) Page 40
Homework #5 Page 41