리눅스 시스템에서는 열려진 파일의 디스크립터를 복제하는 dup와 dup2 함수를 제공합니다.
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
반환 값: 새로운 파일 디스크립터, 실패 시 -1
예를 들어 hello 파일에 abcdefghijklmnopqrstuvwxyz라는 내용이 있다고 가정합시다. 이 파일을 열어서 fd1에 파일 디스크립터를 기억합니다. dup 함수를 이용하여 fd1을 복제한 파일 디스크립터를 fd2에 기억합니다. fd1으로 10바이트를 읽으면 abcdefghij까지 읽어옵니다. 이 때 fd2로 10바이트를 읽어오면 두 개의 파일 디스크립터는 같은 파일 테이블의 엔트리를 참조하므로 읽어 온 다음 위치에 있는 klmnopqrst를 읽어옵니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// ex_dup.c #include "eh.h" int main(int argc,char **argv) { int fd1 = 0, fd2=0; char buf[10+1]=""; if(argc != 2) { fprintf(stderr,"usage: %s <file name>\n",argv[0]); return 1; } fd1= open(argv[1],O_RDONLY); if(fd1 == -1) { fprintf(stderr,"failed open %s\n",argv[1]); return 1; } fd2= dup(fd1); if(fd2 == -1) { perror("failed dup"); return 1; } read(fd1,buf,10); printf("fd1:%s\n",buf); read(fd2,buf,10); printf("fd2:%s\n",buf); close(fd1); close(fd2); return 0; } |
보통 dup2 함수는 정규 파일을 표준 출력으로 사용할 때 때 많이 사용합니다.
예를 들어 dup2(fd, STDOUT_FILENO);를 호출한 후에 printf 함수를 호출하면 fd로 연 파일에 쓰여집니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// ex_dup2.c #include "eh.h" int main(int argc,char **argv) { int fd = 0; if(argc != 2) { fprintf(stderr,"usage: %s [file name]\n",argv[0]); return 1; } fd= open(argv[1],O_WRONLY|O_CREAT|O_TRUNC); if(fd == -1) { perror("failed open "); return 1; } if(dup2(fd,STDOUT_FILENO) == -1) { perror("failed dup2"); return 1; } printf("Hello World\n"); close(fd); return 0; } |