프로그래밍 기술/리눅스(Unix) 시스템 프로그래밍

[리눅스/유닉스 시스템 프로그래밍] lseek

언제나휴일 2016. 4. 5. 23:04
반응형

3.4 lseek

 파일 입출력 작업을 할 때 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 dummy file.");

        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;

}

 이를 테스트 할 때는 root 계정으로 실행하세요.

$ ./ex_enable_lseek dummy

can lseek dummy file.

$ ./ex_enable_lseek /dev/tty0

can't lseek /dev/tty0 file.

 

 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|O_EXCL,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 코드를 확인할 수 있습니다. 자세한 사항은 man od로 확인하세요.

$ ./ex_hole dummy

$ ls -l dummy

-rw-r--r-- 1 ehpub 21 2015-02-14 11:11 dummy

$ od -c dummy

00000000 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0

00000020 \0 \0 \0 \0 \a

00000025

 

 앞으로 소스 코드를 표현할 때 공통적으로 사용하는 내용은 #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>

 


반응형