
2장부터 4장까지는 파일에 대해 다루는데, 2장에서는 파일 입출력의 기본을 알아보고 파일을 다루는 가장 기본적이고 간단한 방법인 시스템 콜(syscall)에 대해 이야기한다.
OS = Kernel+ Shell
- 커널은 운영체제의 핵심으로 운영체제가 수행하는 모든 것이 저장됨.
- 쉘은 리눅스 환경에서 일반적으로 쓰는 명령어들을 읽어들여 해석하고 결과를 출력해주는 역할을 함.
사용자 영역과 커널 영역이 나뉘어져 있고 각 영역엔 버퍼가 있음.
- syscall을 통해 파일 입출력을 하게 되면 커널을 통해 입출력을 수행함.
- 예를 들어 open() 이라는 시스템콜을 호출하면, kernel 모드에 들어가서 시스템 콜에 대한 명령어를 수행함.



파일을 읽고 쓰기 전에 open()이나 creat() 시스템 콜을 사용해서 파일을 열어야 한다.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open (const char *name, int flags);
int open(const char *name, int flags, mode_t mode);
name인 파일을 파일 디스크립터에 맵핑하고, 성공하면 이 파일 디스크립터를 반환함.flagsflags 매개 변수에 비트 OR연산으로 값을 더 추가해서 열기 동작 변경 가능mode#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat (const char *name, mode_t mode);
가장 대표적인 읽기 메커니즘은 POSIX.1에 정의된 read() 시스템 콜을 사용하는 것.
#include <unistd.h>
ssize_t read (int fd, void *buf, size_t len);
len 바이트만큼 buf로 읽어 들임.buf에 쓴 바이트 숫자를 반환. 실패시 -1 반환.len 바이트만큼 읽지만, 읽을 데이터가 len 바이트 보다 더 적을 경우 더 적게 읽기도 함.파일에 데이터를 기록하기 위해 사용하는 가장 기본적이며 일반적인 시스템 콜은 write()임.
#include <unistd.h>
ssize_t write (int fd, const void *buf, size_t count);
count 바이트 만큼 파일 디스크립터 fd가 참조하는 파일의 현재 파일 위치에 시작지점이 buf인 내용을 기록.파일 디스크립터로 읽고 쓰는 작업을 마치고 나면 close() 시스템 콜을 이용해서 파일 맵핑을 끊어야 함.
#include <unistd.h>
int close (int fd);
fd에 연관된 파일과의 맵핑을 해제하며 프로세스에서 파일을 떼어냄.코드를 입력하세요
파일 디스크립터에 연결된 파일의 오프셋을 특정 값으로 지정함.
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t pos, int origin);
origin 인자fd의 파일 오프셋을 현재 오프셋에서 pos를 더한 값으로 설정.fd의 파일 오프셋을 현재 파일 크기에서 pos를 더한 값으로 설정.fd의 파일 오프셋을 pos 값으로 설정.애플리케이션에서 직접 데이터가 디스크에 기록되는 시점을 제어하고 싶을 때가 있음. 이런 때를 위해 리눅스 커널에서는 성능을 희생하는 대신 입출력을 동기화하는 옵션 제공.
#include <unistd.h>
int fsync (int fd);
fd에 맵핑된 파일의 모든 변경점을 디스크에 기록.fd는 반드시 쓰기 모드로 열려야 함.애플리케이션이 여러 개의 파일 디스크립터를 동시에 블록하고 그중 하나라도 블록되지 않고 읽고 쓸 준비가 되면 알려주는 기능. 어떤 파일 디스크립터에 이벤트가 발생했는 지 주기적으로 확인.
#include <sys/select.h>
int select (int n, fd_set *readfds, fd_set *writefds, fd_set, *exceptfds, struct timeval *timeout);
FD_CLR (int fd, fd_set *set);
FD_ISSET (int fd, fd_set *set);
FD_SET (int fd, fd_set *set);
FD_ZERO (fd_set *set);
readfds: 데이터 읽기가 가능한지(블록되지 않고 read() 작업이 가능한지) 파악writefds: 블록되지 않고 write() 작업이 가능한지 감시exceptfds: 예외가 발생했거나 대역을 넘어서는 데이터가 존재하는지 감시#include <poll.h>
int poll (struct pollfd *fds, nfds_t nfds, int timeout);
fds가 가리키는 단일 pollfd 구조체 배열을 nfds 개수만큼 사용.#include <poll.h>
struct pollfd{
int fd; //파일 디스크립터
short events; //감시할 이벤트
short revents; //발생한 이벤트