본 자료는 상명대학교 신동하 교수님의 수업을 정리한 것임을 밝힙니다.
File input/output System Calls
flags란?
<fcntl.h>
에 정의돼있다.
flags는 파일을 어떤 용도로 open할 지를 지정한다.
O_RDONLY | read only |
O_WRONLY | write only |
O_RDWR | read, write |
O_APPEND | append |
O_CREAT | 새 파일 생성, 추가 인수 필요 |
O_EXCL | O_CREAT와 같이 사용 되면 존재하는 파일을 또 생성할 때 error가 생성
(같이 사용된다는 것은 bitwise or 하는 것 “|” ) |
O_TRUNC | 파일 크기가 0이 됨 |
O_SYNC | write시 physical I/O가 완료될 때까지 wait한다. |
mode란?
<sys/stat.h>
에 정의돼있다.
creat할 file의 mode=(user/group/other) 각각의 read/write/execute를 OR한 값을 지정한다.
→ bitwise OR 로 합칠 수 있다.
00400 | octa O, value |
S_IRUSR | user read(00400) |
S_IWUSR | user write (00200) |
S_XUSR | user execute (00100) |
S_IRGRP | group read (00040) |
S_IWGRP | group write (00020) |
S_IXGRP | group execute (00010) |
S_IROTH | other read (00004) |
S_IWOTH | other write (00002) |
S_IXOTH | other execute(00001) |
open
: 주어진 pathname으로 file을 열거나 생성하고 file descriptor를 넘겨준다.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);
=========================================================
return value: 성공 시 새 (file descriptor), 오류 시 (-1)
creat
: 주어진 pathname으로 file을 생성하고 file descriptor를 넘겨준다.
creat와 open 비교
// 아래 두 함수는 기능이 같다.
creat(pathname, mode)
open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode)
함수 creat은 open을 사용하여 프로그래밍이 가능하기 때문에 실제 필요없다.
read
: 주어진 file descriptor에 해당하는 file로 부터 데이터를 읽는다.
#include <unistd.h>
// fd: file descriptor, buf: data를 읽을 mem의 시작
// count: 읽을 char의 갯수
ssize_t read(int fd, void *buf, size_t count);
file로부터 data를 읽는 함수
read가 성공적으로 완료되면 해당 파일의 읽기/쓰기 위치인 file offset이 read한 byte 수 만큼 증가한다.
return value
: 성공 시 read한 byte 수. file의 끝에 도달시, 0 오류시 -1
write
: 주어진 file descriptor에 해당하는 파일에 데이터를 쓴다.
#include <unistd.h>
// buf: write할 data가 저장된 시작 주소
ssize_t write(int fd, const void *buf, size_t count);
write는 주어진 파일에 데이터를 쓰는 함수
write가 성공적으로 완료되면 해당 파일의 읽기/쓰기 위치인 file offset이 write한 byte 수 만큼 증가한다.
return value
: 성공시 write한 byte 수, 오류 시 -1
Example
device I/O도 read, write함수를 사용하여 이용할 수 있다.
// copy.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
// Linux의 ext4 파일 시스템에서 disk의 block size는 4K임
#define BUFFSIZE 4096
// 실제 system call read, write는 unbufered I/O라 버퍼링이 없다.
// 아래 버퍼는 데이터를 저장할 용도로 사용하는 것이다.
char buf[BUFFSIZE];
int main() {
int n;
// STDIN, STDOUT은 프로그램 시작, 종료 시 open, close되므로
// open, close를 할 필요가 없음
while((n = read(STDIN_FILENO, buf, BUFFSIZE) > 0) {
// n만큼 읽었는데 n만큼 출력하지 않으면 오류
if(write(STDOUT_FILENO, buf, n) != n) {
perror("write");
exit(1);
}
// n이 음수를 return하면 오류
if(n < 0) {
perror("read");
exit(1);
}
}
return 0;
}
close
: 주어진 file descriptor에 해당하는 file을 닫는다.
#include <unistd.h>
int close(int fd);
함수 close는 open한 파일을 더 이상 사용하지 않을 경우 부른다.
return value
: 성공 시 0, 오류 시 -1
lseek
: 주어진 file descriptor에 해당하는 file의 입출력 위치를 변경한다. (offset)
whence
offset의 상대적 시작 위치를 지정한다.
SEEK_SET | 파일의 시작 지점에서부터 offset. |
SEEK_CUR | 현재 file offset에서부터 offset |
SEEK_END | 파일의 끝 지점에서부터 offset |
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int file_descriptor, off_t offset, int whence);
lseek은 주어진 file의 입출력 위치인 file offset을 변경하는 함수다.
return value
: 성공시 new file offset, 오류 시 -1
Uploaded by N2T