dupdup2都可用来复制一个现存的文件描述符,使两个文件描述符指向同一个file结构体。如果两个文件描述符指向同一个file结构体,File Status Flag和读写位置只保存一份在file结构体中,并且file结构体的引用计数是2。如果两次open同一文件得到两个文件描述符,则每个描述符对应一个不同的file结构体,可以有不同的File Status Flag和读写位置。请注意区分这两种情况。    

  1. #include <unistd.h> 
  2. int dup(int oldfd); 
  3. int dup2(int oldfd, int newfd); 

如果调用成功,这两个函数都返回新分配或指定的文件描述符,如果出错则返回-1dup返回的新文件描述符一定该进程未使用的最小文件描述符,这一点和open类似。dup2可以用newfd参数指定新描述符的数值。如果newfd当前已经打开,则先将其关闭再做dup2操作,如果oldfd等于newfd,则dup2直接返回newfd而不用先关闭newfd再复制。

下面这个例子演示了dupdup2函数的用法,请结合后面的连环画理解程序的执行过程。


  1. #include <unistd.h> 
  2. #include <sys/stat.h> 
  3. #include <fcntl.h> 
  4. #include <stdio.h> 
  5. #include <stdlib.h> 
  6. #include <string.h>  
  7. int main(void
  8. int fd, save_fd; 
  9. char msg[] = "This is a test\n"
  10. fd = open("somefile", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); 
  11. if(fd<0) { 
  12. perror("open");exit(1); 
  13. save_fd = dup(STDOUT_FILENO); 
  14. dup2(fd, STDOUT_FILENO);close(fd); 
  15. write(STDOUT_FILENO, msg, strlen(msg)); 
  16. dup2(save_fd, STDOUT_FILENO); 
  17. write(STDOUT_FILENO, msg, strlen(msg)); 
  18. close(save_fd); 
  19. return 0; 

 

dup和dup2详解_dup2

重点解释两个地方:

3幅图,要执行dup2(fd, 1);,文件描述符1原本指向tty,现在要指向新的文件somefile,就把原来的关闭了,但是tty这个文件原本有两个引用计数,还有文件描述符save_fd也指向它,所以只是将引用计数减1,并不真的关闭文件。

5幅图,要执行dup2(save_fd, 1);,文件描述符1原本指向somefile,现在要指向新的文件tty,就把原来的关闭了,somefile原本只有一个引用计数,所以这次减到0,是真的关闭了。