리눅스 시스템에서는 열려진 파일의 속성을 가져오거나 설정할 때 fcntl 함수를 사용합니다.
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, … /* int arg */);
반환 값: cmd에 따라 다름, 실패 시 -1
cmd
F_DUPFD : 파일 디스크립터를 복제함
F_GETFD, F_SETFD : 파일 디스크립터 flags를 가져오거나 설정
F_GETFL, FSETFL : 파일의 status flags를 가져오가나 설정
F_GETOWN, F_SETOWN :
SIGIO와 SIGUSR 시그널을 수신하는 프로세스 ID 혹은 프로세스 그룹 ID를 가져오거나 설정
F_GETLK, F_SETLK, F_SETLKW : 레코드 lock을 가져오거나 설정
fcntl 함수는 cmd 인자에 따라 파일의 속성을 가져오거나 설정할 수 있습니다. 앞으로 함수 이름이 cntl로 끝나는 것을 살펴보시면 여러 가지 기능을 cmd 인자에 따라 수행하는 함수라는 것을 알 수 있습니다.
다음은 fcntl 함수에 F_DUPFD 인자를 전달하여 파일 디스크립터를 복제하는 예제입니다.
//ex_fcntl_dupfd.c #include "eh.h" int main() { int fd1 = 0, fd2 = 0; fd1 = open(“demo”, O_WRONLY|O_CREAT|O_TRUNC); fd2 = fcntl(fd1, F_DUPFD, 30); char data = ‘a’; write(fd1, &data, 1); data = ‘b’; write(fd2,&data,1);wpwneh close(fd1); close(fd2); fd1 = open(“demo”,O_RDONLY); while(read(fd1, &data, 1)>0) { putchar(data); } close(fd1); printf(“\n end of file.\n”); return 0; }
실질적으로 수행하는 작업은 dup2 함수와 비슷합니다. 차이점은 dup2 함수는 재지정하는 파일 디스크립터가 사용 중이어도 지정한 값으로 재지정하지만 fcntl 함수를 이용하면 이미 사용 중일 때에는 이후의 파일 디스크립터 중에 사용 중이지 않은 값을 사용합니다.
다음은 dup2 함수와 fcntl 함수를 이용하였을 때의 차이를 보여주는 예제 코드입니다.
//ex_fcntl_VS_dup2.c #include "eh.h" int main() { int fd1 = 0, fd2 = 0, fd3=0; fd1 = open(“demo”, O_WRONLY|O_CREAT|O_TRUNC); printf(“=== TEST fcntl( , F_DUPFD, ) ===\n”); fd2 = fcntl(fd1, F_DUPFD, 30); printf(“fd2: %d\n”, fd2); fd3 = fcntl(fd1, F_DUPFD, 30); printf(“fd3: %d\n”, fd3); close(fd2); close(fd3); printf(“=== TEST dup2( , ) ===\n”); fd2 = dup2(fd1, 30); printf(“fd2: %d\n”, fd2); fd3 = dup2(fd1, 30); printf(“fd3: %d\n”, fd3); close(fd2); close(fd3); close(fd1); return 0; }