转:http://www.cnblogs.com/sdphome/archive/2011/04/30/2033381.html

dupdup2都可用来复制一个现存的文件描写叙述符,使两个文件描写叙述符指向同一个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再复制。

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

#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,是真的关闭了。

 

样例1:

在学习dup2时总是碰到“重定向”一词。上图完毕的就是一个“从标准输出到文件的重定向”。经过dup2后进程A的不论什么目标为STDOUT_FILENO的I/O操作如printf等,其数据都将流入fd3所相应的文件里。

以下是一个例子程序

#define TESTSTR "Hello dup2\n"
int main() {
int fd3;
fd3 = open("testdup2.dat",0666)。
if (fd < 0) {
printf("open error\n");
exit(-1);
}
if (dup2(fd3,STDOUT_FILENO) < 0) {
printf("err in dup2\n");
}
printf(TESTSTR);
return 0;
}
其结果就是你在testdup2.dat中看到"Hello dup2"。

 

样例2:

#define TESTSTR "Hello dup2\n"
#define SIZEOFTESTSTR 11
int main() {
int fd3;
int s_fd;
int n_fd;
fd3 = open("testdup2.dat",0666)。
if (fd3 < 0) {
printf("open error\n");
exit(-1)。
}
/* 复制标准输出描写叙述符 */
s_fd = dup(STDOUT_FILENO);
if (s_fd < 0) {
printf("err in dup\n");
}
/* 重定向标准输出到文件 */
n_fd = dup2(fd3,STDOUT_FILENO);
if (n_fd < 0) {
printf("err in dup2\n");
}
write(STDOUT_FILENO,TESTSTR,SIZEOFTESTSTR); /* 写入testdup2.dat中 */
/* 重定向恢复标准输出 */
if (dup2(s_fd,n_fd) < 0) {
printf("err in dup2\n");
}
write(STDOUT_FILENO,TESTSTR,SIZEOFTESTSTR); /* 输出到屏幕上 */
return 0;
}
注意这里我在输出数据的时候我是用了不带缓冲的write库函数。假设使用带缓冲区的printf。则终于结果为屏幕上输出两行"Hello dup2",而文件testdup2.dat中为空。原因就是缓冲区作怪。因为终于的目标是屏幕,所以程序最后将缓冲区的内容都输出到屏幕。

 

dup and dup2的剖析的更多相关文章

  1. dup和dup2用法小结

    今天和同学探讨了一下关于重定向输出到文件的问题,其中需要用到dup和dup2函数,因此来小小的总结一下. 首先来man一下: dup直接返回一个新的描述符和原来的描述符一样代表同一个资源,描述符的值就 ...

  2. Linux内核分析:dup、dup2的实现

    一.首先需要看一下这两个函数的作用: #include <unistd.h> int dup(int oldfd); int dup2(int oldfd, int newfd); 根据m ...

  3. dup和dup2函数

    下面两个函数都可用来复制一个现存的文件描述符: #include<unistd.h> int dup(int filedes); int dup2(int filedes,int file ...

  4. dup和dup2函数以及管道的实现

    疑问:管道应该不是这样实现的,因为这要求修改程序的代码 dup和dup2也是两个非常有用的调用,它们的作用都是用来复制一个文件的描述符.它们经常用来重定向进程的stdin.stdout和stderr. ...

  5. dup和dup2详解

    C语言中dup和dup2函数的不同和使用 发表时间: 2012年11月15日 | 作者: 陈杰斌 | 所属分类: C语言 | 评论: 0 | 浏览: 1024 在unix高级编程中有介绍dup和dup ...

  6. dup和dup2应用实例(dup跟APUE有出入,close+dup=dup2?)

    dup/dup2函数 有时我们希望把标准输入重定向到一个文件,或者把标准输出重定向到一个网络连接. dup()与dup2()能对输入文件描述符进行重定向. 函数原型如下: dup函数创建一个新的文件描 ...

  7. Linux系统编程--文件描述符的复制dup()和dup2()【转】

    本文转载自:http://blog.csdn.net/tennysonsky/article/details/45870459 dup() 和 dup2() 是两个非常有用的系统调用,都是用来复制一个 ...

  8. dup()&dup2()

    [dup()&dup2()] 都是复制文件描述符指针.dup2可以指定复制到哪一个新索引. 参考:http://hi.baidu.com/flikecn/item/e82e14bef06e8a ...

  9. Unix 网络编程 dup和dup2函数

    dup和dup2也是两个很实用的调用,它们的作用都是用来复制一个文件的描写叙述符. 它们经经常使用来重定向进程的stdin.stdout和stderr.这两个函数的原形例如以下: #include & ...

随机推荐

  1. GitHub出现Permissiondenied (publickey).

    cd ~/.ssh ssh -T git@github.com 出现Permission denied(publickey).意思表示缺少公钥. ssh-keygen -t rsa -C " ...

  2. 『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下

    『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 # Author : Hellcat # Time : 2018/2/11 import torch as t import t ...

  3. div节点的操作(添加,删除,替换,克隆)

    <html> <head> <title></title> <style type="text/css"> div{ b ...

  4. 管道与popen函数与重定向

    转自:http://www.tldp.org/LDP/lpg/node12.html Pipes the Easy Way! LIBRARY FUNCTION: popen(); PROTOTYPE: ...

  5. 纯js倒计时效果(交流加群:452892873)(本群每天都更新学习资料)

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  6. 网络协议栈学习(二)创建 socket

    下面通过学习linux 1.2.13源码进一步理解socket通信机制.对该版本源码的学习主要参考<Linux内核网络栈源代码情景分析>(曹桂平 编著). 要理解socket的本质,就要理 ...

  7. 软件工程——Word-Counter

    Python实现Word-Counter 一.前言 Github地址:https://github.com/hzquestion/Word-Counter 二.项目概述 实现一个统计程序,它能正确统计 ...

  8. Python学习(001)--计算机基础

    操作系统发展历史 操作系统并不是与计算机硬件一起诞生的,它是在人们使用计算机的过程中,为了满足两大需求:提高资源利用率.增强计算机系统性能,伴随着计算机技术本身及其应用的日益发展,而逐步地形成和完善起 ...

  9. shell 数学运算总结

    # !/bin/bash ## 整数-算数运算 ### 1. expr r=`expr 4 + 5` ### Tips:1. '4''+''5'三者之间有空白 echo $r; r=`expr 4 \ ...

  10. 【error】Invalid ADAPTORNAME specified. Type 'imaqhwinfo' for a list of available ADAPTORNAMEs.

    前言 使用matlab通过摄像头获取图像进行处理: 问题描述 使用matalb调用摄像头时出现错误: >> imaqhwinfo Warning: No Image Acquisition ...