dup和dup2函数
2009-07-09 18:26
288 查看
1. 文件描述符在内核中数据结构
在具体说dup
/dup
2之前, 我认为有必要先了解一下文件描述符在内核中的形态。
一个进程在此存在期间,会有一些文件被打开,从而会返回一些文件描述符,从shell
中运行一个进程,默认会有3个文件描述符存在(0、1、2), 0与进程的标准输入相关联,
1与进程的标准输出相关联,2与进程的标准错误输出相关联,一个进程当前有哪些打开
的文件描述符可以通过/proc/进程ID/fd目录查看。 下图可以清楚的说明问题:
进程表项
————————————————
fd标志 文件指针
_____________________
fd 0:|________|____________|------------> 文件表
fd 1:|________|____________|
fd 2:|________|____________|
fd 3:|________|____________|
| ....... |
|_____________________|
图1
文件表中包含:文件状态标志、当前文件偏移量、v节点指针,这些不是本文讨论的
重点,我们只需要知道每个打开的文件描述符(fd标志)在进程表中都有自己的文件表
项,由文件指针指向。
2. dup
/dup
2函数
APUE和man文档都用一句话简明的说出了这两个函数的
作用
:复制一个现存的文件描述符。
#include <unistd.h>
int dup
(int oldfd);
int dup
2(int oldfd, int newfd);
从图1来分析这个过程,当调用dup
函数时,内核在进程中创建一个新的文件描述符,此
描述符是当前可用文件描述符的最小数值,这个文件描述符指向oldfd所拥有的文件表项。
进程表项
————————————————
fd标志 文件指针
_____________________
fd 0:|________|____________| ______
fd 1:|________|____________|----------------> | |
fd 2:|________|____________| |文件表|
fd 3:|________|____________|----------------> |______|
| ....... |
|_____________________|
图2:调用dup
后的示意图
如图2 所示,假如oldfd的值为1, 当前文件描述符的最小值为3, 那么新描述符3指向
描述符1所拥有的文件表项。
dup
2和dup
的区别就是可以用newfd参数指定新描述符的数值,如果newfd已经打开,则
先将其关闭。如果newfd等于oldfd,则dup
2返回newfd, 而不关闭它。dup
2函数返回的新
文件描述符同样与参数oldfd共享同一文件表项。
APUE用另外一个种方法说明了这个问题:
实际上,调用dup
(oldfd);
等效与
fcntl(oldfd, F_DUPFD, 0)
而调用dup
2(oldfd, newfd);
等效与
close(oldfd);
fcntl(oldfd, F_DUPFD, newfd);
printf -> stdout -> STDOUT_FILENO(1) -> 终端(tty)
重拾终端输出方法
ttyfd = open("/dev/tty", O_RDWR);
dup
2(ttyfd, STDOUT_FILENO);
close(ttyfd);
在具体说dup
/dup
2之前, 我认为有必要先了解一下文件描述符在内核中的形态。
一个进程在此存在期间,会有一些文件被打开,从而会返回一些文件描述符,从shell
中运行一个进程,默认会有3个文件描述符存在(0、1、2), 0与进程的标准输入相关联,
1与进程的标准输出相关联,2与进程的标准错误输出相关联,一个进程当前有哪些打开
的文件描述符可以通过/proc/进程ID/fd目录查看。 下图可以清楚的说明问题:
进程表项
————————————————
fd标志 文件指针
_____________________
fd 0:|________|____________|------------> 文件表
fd 1:|________|____________|
fd 2:|________|____________|
fd 3:|________|____________|
| ....... |
|_____________________|
图1
文件表中包含:文件状态标志、当前文件偏移量、v节点指针,这些不是本文讨论的
重点,我们只需要知道每个打开的文件描述符(fd标志)在进程表中都有自己的文件表
项,由文件指针指向。
2. dup
/dup
2函数
APUE和man文档都用一句话简明的说出了这两个函数的
作用
:复制一个现存的文件描述符。
#include <unistd.h>
int dup
(int oldfd);
int dup
2(int oldfd, int newfd);
从图1来分析这个过程,当调用dup
函数时,内核在进程中创建一个新的文件描述符,此
描述符是当前可用文件描述符的最小数值,这个文件描述符指向oldfd所拥有的文件表项。
进程表项
————————————————
fd标志 文件指针
_____________________
fd 0:|________|____________| ______
fd 1:|________|____________|----------------> | |
fd 2:|________|____________| |文件表|
fd 3:|________|____________|----------------> |______|
| ....... |
|_____________________|
图2:调用dup
后的示意图
如图2 所示,假如oldfd的值为1, 当前文件描述符的最小值为3, 那么新描述符3指向
描述符1所拥有的文件表项。
dup
2和dup
的区别就是可以用newfd参数指定新描述符的数值,如果newfd已经打开,则
先将其关闭。如果newfd等于oldfd,则dup
2返回newfd, 而不关闭它。dup
2函数返回的新
文件描述符同样与参数oldfd共享同一文件表项。
APUE用另外一个种方法说明了这个问题:
实际上,调用dup
(oldfd);
等效与
fcntl(oldfd, F_DUPFD, 0)
而调用dup
2(oldfd, newfd);
等效与
close(oldfd);
fcntl(oldfd, F_DUPFD, newfd);
printf -> stdout -> STDOUT_FILENO(1) -> 终端(tty)
重拾终端输出方法
ttyfd = open("/dev/tty", O_RDWR);
dup
2(ttyfd, STDOUT_FILENO);
close(ttyfd);
相关文章推荐
- dup和dup2函数
- dup,dup2函数
- Unix 网络编程 dup和dup2函数
- 文件系统的dup和dup2函数
- dup和dup2函数
- linux下dup/dup2函数的用法1
- dup、dup2函数
- C语言dup和dup2函数
- dup与dup2函数
- 形象的理解dup和dup2函数
- linux下dup/dup2函数的用法
- 进程间通信管道进阶篇:linux下dup/dup2函数的用法
- dup和dup2函数
- Linux内核中的FILE文件数据结构和dup,dup2函数
- dup和dup2函数
- 3.12 文件I/O_dup和dup2函数
- Linux下的管道编程技术-dup函数和dup2函数
- dup和dup2函数
- dup,dup2函数的用法
- 文件I/O——dup和dup2函数