전공/시스템 프로그래밍(운영체제)

5. 추가적인 System Call

문정훈 2021. 10. 17. 01:28

1-1. System call: lseek()

#include <sys/types.h>
#include <unistd.h>

off_t lseek(int fd, off_t pos, int origin);

파일 디스크립터를 처음 open하면 offset은 당연히 0이다. (참고로 offet은 메타 데이터가 아니다. !!)

그리고 파일을 읽을 때 마다 offset이 뒤로 이동한다. 

이 offset을 이동 시키는 시스템 콜이다. 

첫 번째 매개변수인 파일 디스크립터의 파일의 offset의 원래 위치인 origin 값에서 pos만큼 뒤로 이동하라는 의미가 된다. 

이때 origin이 아래 2가지 상수 값을 가질 수 있다. 

  1. SEEK_CUR : 현재 offset위치를 반환
  2. SEEK_END : 현재 파일의 offset을 걍 맨 마지막 끝으로 이동하라는 것이다.

또한 offset의 값을 리턴하는 System Call은 없으므로 lseek(fd, 0, SEEK_CUR); 로 현재 offset의 위치를 알 수 있다. 

 

1-2. lseek 에러 설명

 

EBADF

경우1) 
파일의 경로가 잘못되어 파일 디스크립터가 없는경우 발생한다.  다른 경우로
파일 디스크립터가 메인 메모리에 있는 file table에 존재하지 않는데 read를 호출하는 경우이다. 

경우2)
파일에 대한 file descriptor를 반환받는 것 까지는 성공하였으나 이후 I/O 함수를 호출하는 과정에서 동시에 접속한 다른 프로세스에 의해서 close되는 경우 메인 메모리에서 file descriptor가 사라져서 발생하는 오류이다. 

정리=>
파일 디스크립터가 메인 메모리(file table)에 존재하지 않아 발생하는 오류가 된다. 
EINVAL

origin 매개변수가 SEEK_SET, SEEK_CUR, SEEK_END 중 의 값이 아닌 경우 또는 
파일 offset이 음수인 경우이다. 
EOVERFLOW

offset 값이 너무 크거나 음수인 경우 에러를 발생한다. 

 

2-1. System call: pread()

#define _XOPEN_SOURCE 500
#include <unistd.h>

ssize_t pread(int fd, void *buf, size_t count, off_t offset);

fd 가 가리키는 파일에서 offset부터 뒤로 count (byte) 만큼 읽어서 buf에 저장한다. 

이때 offset은 변경되지 않는다.

 

 

2-2. System call: pwrite()

#define _XOPEN_SOURCE 500
#include <unistd.h>

ssize_t pwrite(int fd, void *buf, size_t count, off_t offset);

fd가 가리크는 곳에서 offset에서 시작해 buf의 내용을 count 만큼쓰는 것이다. 

이때 offset은 변경되지 않는다.

 

 

3-2. pread()/pwrite() and read()/write() 의 차이점

pread와 pwrite는 현재 파일 디스크립터에서 pos 위치 만큼 이동 시킨뒤 작업을 하는데 이때 실제 offset의 값은 바뀌지 이 시스템 콜을 사용하기 전의 값 그대로이다. 즉 offset이 이 시스템 콜에서는 변경되지 않고 매개변수로 주어진 정보를 가지고 작업만 한다. 


 

4-1. System call: ftruncate()

#include <unistd.h>
#include <sys/types.h>

int ftruncate (int fd, off_t len);

위 시스템 콜은 fd 가 가리키는 파일을 파일의 시작점부터 len 길이 만큼 잘라라 라는 의미이다. 

#include <unistd.h>
#include <sys/types.h>

int ftruncate (const char *path, off_t len);

path 경로에 있는 파일의 내용을 시작점 부터 len 만큼 잘라라는 의미인데 시작부터 len 까지 잘라 그것을 기존의 파일의 내용에서 대체한다. 

이 시스템 콜을 사용하기 위해선 open 시 쓰기 모드로 반드시 열어야한다. 

 

만약 len이 파일의 크기보다 크면 기존의 파일의 크기를 len으로 맞추고 나머지 공간으 0x00으로 채운다. 

 

 

 

'전공 > 시스템 프로그래밍(운영체제)' 카테고리의 다른 글

7. Buffered IO  (0) 2021.10.17
6. Blocking, non-Blocking  (0) 2021.10.17
4. 시스템 콜: buffer 정리  (0) 2021.10.16
3. System Call: read, write  (0) 2021.10.16
2. System Call: open  (0) 2021.10.12