본문 바로가기
Linux System/Linux

[func] fcntl

by rewyear 2020. 4. 7.

fcntl은 파일들의 특성 제어를 위해 제공하는 함수이다.

#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);

첫 번째 fd는 open,socket 등의 시스템 호출을 통해서 만들어진 file descriptor이다.

두 번째 cmd를 통해 fd에 대한 특성을 제어할 수 있다.

 

cmd

command description 비고
F_DUPFD fd를 복사하기 위해 사용한다. F_DUPFD 를 사용할경우 arg 와 같은 크기의 파일지정자를 되돌려주거나, 이미 사용되어지고 있다면, arg 보다 큰 할당가능한 파일지정번호중 가장 작은 번호를 되돌려준다.


이 복사된 파일지정번호는 잠금, 파일위치 포인터, 플레그 등을 공유한다. 즉 파일지정자들중 하나에서 파일의 위치가 변경된다면(lseek등을 이용), 다른 파일지정자도 변경된다.
F_GETFD fd에 대한 flag 값을 리턴한다.  
F_SETFD FD_CLOEXEC(close-on-exec) 의 값을 지정된 비트값으로 설정한다.  
F_GETFL fd에 대한 flag 값을 리턴한다.  
F_SETFL arg 에 지정된 값으로 파일지정자 fd 의 플래그를 재 설정한다. O_APPEND, O_NONBLOCK, O_ASYNC 만을 설정할수 있다.
F_GETOWN 비동기 입출력과 관련되어서 사용되며, SIGIO와 SIGURG 신호를 받는 프로세스 아이디를 얻기 위해서 사용된다  
F_SETOWN 비동기 입출력과 관련되어서 사용되며, SIGIO, SIGURG 시그널을 수신하는 프로세스 아이디(혹은 그룹)을 설정하기 위해서 사용된다.  

 

fcntl 예제

1. F_DUPFD

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

int main()
{
    int dupfd;
    int fd;

    fd  = open("test.txt", O_CREAT);

    dupfd = fcntl(fd, F_DUPFD, 10);
    printf("testfd :%d\n", testfd);
    dupfd = fcntl(fd, F_DUPFD, 10);
    printf("testfd :%d\n", testfd);

    getchar();
}

위의 예제의 경우 test.txt의 fd로 3, dupfd 로 각각 4, 5 가 아닌 10, 11 로 파일지정번호가 지정됨을 알수 있을것이다.

 

2. F_GETFL / F_SETFL

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

int main()
{
    int mode, fd, flag;
    
    memset(buf, 0x00, 255);

    // BLOCKING 모드
    read (STDIN, buf, 255);
    printf("-> %s\n", buf);
    memset(buf, 0x00, 255);
    
    // NONBLOCKING 모드로 변경한다. 
    value = fcntl(STDIN, F_GETFL, 0);
    fcntl(STDIN, F_SETFL, value | O_NONBLOCK);
    
}

 

300x250

'Linux System > Linux' 카테고리의 다른 글

[func] mmap() / munmap() - memory 맵핑  (0) 2021.07.23
[cmd] install 명령어  (0) 2020.08.05
[func] poll  (0) 2020.04.07
Patch file 만들기(git diff 활용)  (0) 2020.03.04
[cmd] md5sum  (0) 2020.03.04