파일 입출력 작업을 할 때 lseek 함수를 이용하여 원하는 위치로 이동할 수 있습니다. 현재 작업하고 있는 파일의 시작 위치에서 상대적 거리를 파일 offset이라 부르며 lseek 함수를 이용하면 파일의 시작 위치나 현재 위치, 파일의 끝에서 상대적 거리로 이동할 수 있습니다. 하지만 FIFO나 pipe처럼 특수한 파일은 lseek를 허용하지 않습니다.
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
반환 값: 함수를 수행한 이후에 새로운 offset, 실패 시 -1
whence
SEEK_SET: 파일의 시작 위치를 기준
SEEK_CUR: 파일의 현재 작업 위치를 기준
SEEK_END: 파일의 끝을 기준
다음은 lseek 함수의 리턴값을 확인하여 lseek 함수를 사용할 수 있는 파일인지 확인하는 코드입니다.
//ex_ enable_lseek.c #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> int main(int argc,char **argv) { int fd = 0; if(argc != 2) { fprintf(stderr,"usage: %s <filename>\n",argv[0]); return 1; } fd = open(argv[1],O_RDONLY); if(fd == -1) { perror("failed open."); return 1; } if(lseek(fd, 0, SEEK_CUR)==-1) { printf("can't lseek %s file. \n",argv[1]); } else { printf("can lseek %s file. \n",argv[1]); } close(fd); return 0; }
다음은 루트 계정으로 정규 파일과 터미널 장치 파일을 인자로 테스트 화면입니다.
lseek를 이용하여 파일의 끝보다 뒤로 이동한 후에 쓰기 작업을 하면 파일의 크기는 커지면서 빈 공간(hole)이 생깁니다. 내용을 확인하면 빈 공간(hole)은 ‘\0’로 보입니다.
다음은 새로운 파일을 생성한 후 lseek 함수 호출 후에 1바이트 더미 내용을 write하여 Hole을 만드는 예제 코드입니다.
// ex_hole.c #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> int main(int argc,char **argv) { int fd = 0; if(argc != 2) { fprintf(stderr,"usage: %s <filename>\n",argv[0]); return 1; } fd = open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0644); if(fd == -1) { fprintf(stderr,"failed open %s\n",argv[1]); return 1; } if(lseek(fd, 20, SEEK_CUR)==-1) { printf("can't lseek %s file. \n",argv[1]); } else { char dummy='a'; write(fd,&dummy,1); } close(fd); return 0; }
컴파일 한 후에 이를 실험하면 다음처럼 빈 공간이 있는 파일이 생긴 것을 확인할 수 있습니다. 참고로 od 명령은 파일의 내용을 8진수로 dump 하여 보여주며 -c 옵션을 사용하면 ASCII 코드를 확인할 수 있습니다. 그리고 du 명령은 사용 용량을 확인할 수 있어요. 자세한 사항은 man od와 man du로 확인하세요.
앞으로 소스 코드를 표현할 때 공통적으로 사용하는 내용은 #include “eh.h”로 표시할게요. 그리고 새로운 헤더 파일을 포함할 필요가 있으면 무엇을 추가하였는지 알리기로 하겠습니다.
현재 eh.h 파일의 내용은 다음과 같습니다.
// eh.h #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <limits.h> #include <stdlib.h>