习题3.2的要求是不使用fcntl()而编写一个同dup2()功能相同的函数。直觉上是不断使用dup()直到返回指定的文件描述符。
#include <stdio.h>
#include <stdlib.h>
#define OPEN_MAX 63

int my_dup2(int filedes,int filedes2);

int
main(int argc, char* argv[])
{
  int fd,fd2;
  char buf[] = "It work!\n";

if(argc != 3)
    err_quit("Usage: %s <filedes#> <filedes2#>",argv[0]);
 
  fd = atoi(argv[1]);
  fd2 = atoi(argv[2]);
  my_dup2(fd, fd2);
  printf("fd#%d -> fd#%d\n", fd2, fd);
  if( write(fd2, buf, 9) != 9)
    err_sys("write error");

exit(0);
}

int
my_dup2(int filedes,int filedes2)
{
  int fd_rec[OPEN_MAX];
  int fd,i,n;
 
  if( filedes == filedes2)  //模拟dup2的行为,当filedes2等于filedes时,直接返回filedes即可
    return filedes;

for(n=0 ; (fd=dup(filedes)) < filedes2; n++){  //由于dup总返回当前可用文件描述符的最小值,因此要不断尝试
    fd_rec[n] = fd;  //保存尝试的文件描述符,以便后面关闭
  }
  if( fd != filedes2)  //退出循环的条件也可能由于filedes2已被占用,这时dup2先将原先占有filedes2的文件关掉,此时dup肯定是filedes2
  {
    close(filedes2);
    fd = dup(filedes);
  }
  //关闭打开的非目标文件描述符
  for(i=0; i<n; i++)
    close(fd_rec[i]);
 
  return fd;
}

 
linux bash shell中常常会使用到命令的输入输出重定向符号。例如,《APUE》中程序3-4的使用

       $  a.out  <  /dev/tty     //将程序输入重定向为/dev/tty
       $  a.out  >  tmp.foo      //将程序输出重定向至文件temp.foo
       $  a.out  2>>  temp.foo     //在文件描述符2上打开文件temp.foo以供添写,通常程序出错时会向fd#2上写入相关错误信息
       $  a.out  5<>temp.foo     //在fd#5上打开文件temp.foo以供读、写
文件描述符通常有几个值是被系统保留使用的,默认地,0-标准输入,1-标准输出,2-错误输出。
  • 在没有这些重定向符号时,shell会在运行命令程序前的准备阶段,初始化fd#0、fd#1、fd#3的指向。
  • 使用重定向符时,指定文件描述符上打开文件的工作也是在shell运行命令程序前准备阶段完成的。

对于my_dup2的测试,

    $  my_dup2   2   17

将在屏幕上输出"It works!";

    $  my_dup2   7 17  7<>/dev/fd/1

也将输出"It works!";

    $    my_dup2   2   17  17>tmp.foo

屏幕输出"It words!",但tmp.foo中没有任何记录,这个例子模拟17已被占有的情形。

APUE习题3.2用dup实现dup2以及shell中重定向符号的使用的更多相关文章

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

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

  2. linux之dup和dup2函数解析

    1. 文件描述符在内核中数据结构在具体说dup/dup2之前,我认为有必要先了解一下文件描述符在内核中的形态.一个进程在此存在期间,会有一些文件被打开,从而会返回一些文件描述符,从shell中运行一个 ...

  3. Linux进程间通信(三):匿名管道 popen()、pclose()、pipe()、close()、dup()、dup2()

    在前面,介绍了一种进程间的通信方式:使用信号,我们创建通知事件,并通过它引起响应,但传递的信息只是一个信号值.这里将介绍另一种进程间通信的方式——匿名管道,通过它进程间可以交换更多有用的数据. 一.什 ...

  4. dup和dup2用法小结

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

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

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

  6. dup和dup2函数

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

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

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

  8. dup和dup2详解

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

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

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

随机推荐

  1. rpo攻击

    0 什么是RPO攻击? RPO(Relative Path Overwrite)相对路径覆盖,是一种新型攻击技术,最早由Gareth Heyes在其发表的文章中提出.主要是利用浏览器的一些特性和部分服 ...

  2. 20170805_Elasticsearch_简介和安装

    官网地址: https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started.html Elk 是一个可高 ...

  3. SPARK安装三:SPARK集群部署

    使用2.3.0版本,因为公司生产环境是这个版本 一.下载安装 cd /opt wget https://archive.apache.org/dist/spark/spark-2.3.0/spark- ...

  4. Java集合:LinkedList源码解析

    Java集合---LinkedList源码解析   一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据re ...

  5. instr()函数--支持模糊查询

    1)instr()函数的格式  (俗称:字符查找函数) 格式一:instr( string1, string2 )    /   instr(源字符串, 目标字符串) 格式二:instr( strin ...

  6. bgfx入门练习1——切换图形API驱动模式DX与OpenGL

    翻了下上次编译bgfx是去年2月份的事了,最近正好想试试DX,OpenGL双驱动,看Urho3D和Klayge光封装就头痛,人又懒,写OpenGL时也基本glfw,于是想到bgfx,不如再试试. 发现 ...

  7. MySQL 三 二进制安装

    二进制格式安装   何谓二进制格式安装?   二进制格式安装,编译好的打包在tar文件里,安装时需要下载后解包至编译时指定的位置,然后进行相关配置,完成安装   版本信息:CentOS 7.4 安装m ...

  8. linux 修改用户密码的几种方法

    1.passwd 命令,手动修改: [root@localhost testuser]# passwd testuser Changing password for user testuser. Ne ...

  9. bash编程-执行流程

    1.顺序执行 shell脚本按从上到下的顺序依次执行,除非使用了选择.循环等执行流程. 2.选择执行 2.1 if # 格式一 if 条件; then # 语句 fi # 格式二 if 条件; the ...

  10. 谈谈最近的想法和 Thoughtworks 的 Offer

    最近笔者一直没有记录博客,原因是因为卷入了面试,离职,谈判,思考等一系列事件中.不过可以先说明一下的是, 笔者最后还是拒绝了 Thoughtworks 的 Offer,继续留在目前的公司. 去年毕业后 ...