您的位置:首页 > 运维架构 > Linux

Linux 中 dup 和 dup2 函数剖析

2013-03-29 09:47 363 查看
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 main(void)

{

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,是真的关闭了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux