dup 与 dup2
来源:互联网 发布:java得到当前项目路径 编辑:程序博客网 时间:2024/06/10 13:30
1. 文件描述符在内核中数据结构
一个进程在此存在期间,会有一些文件被打开,从而会返回一些文件描述符,从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/dup2函数
APUE和man文档都用一句话简明的说出了这两个函数的作用:复制一个现存的文件描述符。
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
从图1来分析这个过程,当调用dup函数时,内核在进程中创建一个新的文件描述符,此
描述符是当前可用文件描述符的最小数值,这个文件描述符指向oldfd所拥有的文件表项。
进程表项
————————————————
fd标志 文件指针
_____________________
fd 0:|________|____________| ______
fd 1:|________|____________|—————-> | |
fd 2:|________|____________| | 文件表 |
fd 3:|________|____________|—————-> | _____ |
| ……. |
|_____________________|
图2:调用dup后的示意图
如图2 所示,假如oldfd的值为1, 当前文件描述符的最小值为3, 那么新描述符3指向
描述符1所拥有的文件表项。
dup2和dup的区别就是可以用newfd参数指定新描述符的数值,如果newfd已经打开,则
先将其关闭。如果newfd等于oldfd,则dup2返回newfd, 而不关闭它。dup2函数返回的新
文件描述符同样与参数oldfd共享同一文件表项。
APUE用另外一个种方法说明了这个问题:
实际上,调用dup(oldfd);
等效与
fcntl(oldfd, F_DUPFD, 0)
而调用dup2(oldfd, newfd);
等效与
close(oldfd);
fcntl(oldfd, F_DUPFD, newfd);
#include <sys/stat.h>#include <string.h>#include <fcntl.h>#include <stdio.h>#include <unistd.h>int main(void){ #define STDOUT 1 //标准输出文件描述符 号 int nul, oldstdout; char msg[] = "This is a test"; //打开一个文件,操作者具有读写权限 如果文件不存在就创建 nul = open("DUMMY.FIL", O_CREAT | O_RDWR, S_IREAD | S_IWRITE); /* create a duplicate handle for standard output */ oldstdout = dup(STDOUT); /* redirect standard output to DUMMY.FIL by duplicating the file handle onto the file handle for standard output. */ dup2(nul, STDOUT); /* close the handle for DUMMY.FIL */ close(nul); /* will be redirected into DUMMY.FIL */ write(STDOUT, msg, strlen(msg)); /* restore original standard output handle */ dup2(oldstdout, STDOUT); /* close duplicate handle for STDOUT */ close(oldstdout); return 0;}
- dup与dup2
- dup与dup2
- dup与dup2用法
- dup与dup2函数
- dup 与 dup2
- dup 与 dup2
- dup与dup2函数
- dup()与dup2()
- linux dup与dup2
- dup与dup2
- dup与dup2() [转]
- dup与dup2函数
- dup 与 dup2
- dup与dup2
- dup 与 dup2
- dup与dup2
- 函数 dup 与 dup2
- dup 与 dup2 的作用
- Android程序调试工具TraceView和dmtracedump
- 港澳通行证
- ubuntu 11.10 安装JDK6
- 有关循环队列
- Linux 性能监测:CPU
- dup 与 dup2
- 双向队列
- javascript添加Activex控件可能会遇到的问题
- AJAX跨域调用WebService解决方案
- 渲染到纹理(Render To Texture, RTT)详解
- Ogre的SdkTray系统梗概
- 学习使用GTK+
- QT编程基础篇QT入门之深入了解信号与槽
- Debug Assertion Failed! File:f:\dd\vctools\crt_bld\_self_x86\crt\src\flength.c解决方式