dup
1
2
3
#include <unistd.h>
int dup(int fildes);
함수의 매개변수(fileds
)로 전달하는 파일 디스크립터를 현재 할당할 수 있는 가장 작은 파일 디스크립터에 복사하여 반환한다.
반환값
- 성공 : 복사된 파일 디스크립터 번호
- 실패 : -1
- 발생한 오류에 따라
errno
가 설정됨
- 발생한 오류에 따라
예시
hello.txt
파일에 다음과 같이 저장되어있다고 해보자.
1
hello wolrd
hello.txt
의 파일 디스크립터를 복사하여 hello.txt
파일의 내용에서 소문자 hello
를 대문자 HELLO
로 변경하는 예시이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd;
int dup_fd;
char *file;
file = "hello.txt";
fd = open(file, O_RDWR);
dup_fd = dup(fd);
printf("fd: %d, dup_fd: %d\n", fd, dup_fd);
write(dup_fd, "HELLO", 5);
close(fd);
close(dup_fd);
return (0);
}
실행 후 출력 결과는 다음과 같다.
1
fd: 3, dup_fd: 4
dup
함수는 현재 사용할 수 있는 파일 디스크립터 중에서 가장 낮은 번호에 원본 파일 디스크립터를 복사한다.
실행 후 hello.txt
파일에는 다음과 같이 변경된다.
1
HELLO world
dup_fd
에 write
함수를 실행했는데, fd
에 해당하는 파일 내용이 변경되는 이유는 두 파일 디스크립터가 같은 파일을 가리키고 있기 때문이다.
이를 이해하기 위해서는 파일 디스크립터에 대한 이해가 필요하다.
파일 디스크립터 이해하기
출처: wikipedia
위의 그림은 파일 디스크립터가 작동하는 방식을 표현한 그림이다.
파일 디스크립터는 인덱스로만 존재하며, 파일 테이블에 존재하는 파일을 포인터로 가리킨다. 파일 테이블이란 모든 프로세스에서 열린 파일들에 대해 시스템 전체가 사용할 수 있는 테이블이다. 파일 테이블에는 특정 파일을 어떤 모드로 열었는지 기록한다. 즉, 읽기 전용, 쓰기 전용, 읽기 및 쓰기 등과 같은 정보를 기록하는 것이다. 그리고 파일 테이블은 실제 데이터가 저장되어 있는 Inode 테이블을 포인터로 가리킨다.
위의 그림에서 알 수 있듯이 다른 파일 디스크립터가 같은 파일 테이블을 가리킬 수도 있다. 파일 디스크립터 0번과 2번이 파일 테이블의 read를 지칭하는 경우인데, 이 경우는 같은 파일을 각각 다른 파일 디스크립터로 open 한 경우이다. 예시 코드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd;
int fd2;
char *file;
file = "hello.txt";
fd = open(file, O_RDONLY);
fd2 = open(file, O_RDONLY);
printf("fd: %d, fd2: %d\n", fd, fd2);
close(fd);
close(fd2);
return (0);
}
실행 결과는 다음과 같다.
1
fd: 3, fd2: 4
또는 다른 파일 테이블이 같은 Inode 테이블을 가리킬 수도 있다. 파일 디스크립터 1번과 4번이 각각 다른 파일 테이블을 가리키고 있지만 같은 Inode 테이블을 지칭하는 경우인데, 이 경우는 같은 파일을 각각 다른 모드로 open한 경우에 해당한다. 예시 코드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd;
int fd2;
char *file;
file = "hello.txt";
fd = open(file, O_RDONLY);
fd2 = open(file, O_RDWR);
printf("fd: %d, fd2: %d\n", fd, fd2);
close(fd);
close(fd2);
return (0);
}
dup 함수에 적용하기
dup
함수를 사용하기 전에는 fd
변수에 hello.txt
파일을 가리키는 포인터의 파일 디스크립터 3번이 저장되어 있었다.
이때, dup_fd
변수에 dup(fd)
를 실행하면 사용 가능한 가장 낮은 디스크립터 번호인 4번에 hello.txt
를 가리키는 포인터를 저장하는 것이다. fd
변수는 open
할 때 읽기 및 쓰기 모드를 사용했는데, dup
함수는 파일 테이블 포인터도 동일하게 복사하기 때문에 동일한 파일을 가리킬 수 있게 되는 것이다.