转:http://www.cnblogs.com/sdphome/archive/2011/04/30/2033381.html
dup
和dup2
都可用来复制一个现存的文件描写叙述符,使两个文件描写叙述符指向同一个file
结构体。假设两个文件描写叙述符指向同一个file
结构体,File
Status Flag和读写位置仅仅保存一份在file
结构体中,而且file
结构体的引用计数是2。假设两次open
同一文件得到两个文件描写叙述符。则每一个描写叙述符相应一个不同的file
结构体,能够有不同的File
Status Flag和读写位置。
请注意区分这两种情况。
#include <unistd.h> int dup(int oldfd);
int dup2(int oldfd, int newfd);
假设调用成功,这两个函数都返回新分配或指定的文件描写叙述符,假设出错则返回-1。dup
返回的新文件描写叙述符一定该进程未使用的最小文件描写叙述符,这一点和open
相似。dup2
能够用newfd
參数指定新描写叙述符的数值。假设newfd
当前已经打开,则先将其关闭再做dup2
操作。假设oldfd
等于newfd
,则dup2
直接返回newfd
而不用先关闭newfd
再复制。
以下这个样例演示了dup
和dup2
函数的使用方法,请结合后面的连环画理解程序的运行过程。
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
{
int fd, save_fd;
char msg[] = "This is a test\n";
fd = open("somefile", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
if(fd<0) {
perror("open");
exit(1);
}
save_fd = dup(STDOUT_FILENO);
dup2(fd, STDOUT_FILENO);
close(fd);
write(STDOUT_FILENO, msg, strlen(msg));
dup2(save_fd, STDOUT_FILENO);
write(STDOUT_FILENO, msg, strlen(msg));
close(save_fd);
return 0;
}
重点解释两个地方:
第3幅图,要运行
dup2(fd, 1);
,文件描写叙述符1原本指向tty
。如今要指向新的文件somefile
,就把原来的关闭了,可是tty
这个文件原本有两个引用计数,还有文件描写叙述符save_fd
也指向它,所以仅仅是将引用计数减1。并不真的关闭文件。第5幅图。要运行
dup2(save_fd, 1);
,文件描写叙述符1原本指向somefile
,如今要指向新的文件tty
,就把原来的关闭了。somefile
原本仅仅有一个引用计数,所以这次减到0,是真的关闭了。
样例1:
以下是一个例子程序:
样例2: