习题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. Step by Step Guide on Yanhua ACDP Clear BMW EGS ISN

    Yanhua Mini ACDP authorize new function on BMW EGS ISN clearing.So here UOBDII want to share this st ...

  2. linux获取当前系统的时间

    #include <time.h> #include <sys/time.h> void sysLocalTime(char *str_info) { time_t times ...

  3. BZOJ2212或洛谷3521 [POI2011]ROT-Tree Rotations

    BZOJ原题链接 洛谷原题链接 线段树合并裸题. 因为交换子树只会对子树内部的逆序对产生影响,所以我们计算交换前的逆序对个数和交换后的个数,取\(\min\)即可. 对每个叶子节点建一棵动态开点线段树 ...

  4. java 给任务传递参数

    之前https://www.cnblogs.com/kexb/p/10228369.html没有参数,这里介绍参数什么传入 package com.hra.riskprice; import com. ...

  5. (PMP)第12章-----项目采购管理

    B D 12.1 规划采购管理 输入 工具与技术 输出 1.项目章程 2.商业文件 (商业文件, 效益管理计划) 3.项目管理计划 (范围,质量,资源管理计划, 范围基准) 4.项目文件 (里程碑清单 ...

  6. v$lockv和$locked_object的区别

    v$lockv和$locked_object的区别 url: http://blog.sina.com.cn/s/blog_62defbef0101pgvo.html 2013-12-24 v1.0 ...

  7. php,单引号与双引号的区别

    代码示例 <?php $s='666'; $s2="999"; $test = 'name{$s} - {$s2}'; $test2 = "name{$s} - { ...

  8. PgAgent安装、配置、运行

    一 安装cmakewget http://www.cmake.org/files/v2.8/cmake-2.8.5.tar.gztar -zxvf cmake-2.8.5.tar.gzcd /root ...

  9. kaldi的TIMIT实例二

    ============================================================================ MonoPhone Training & ...

  10. gitlab 一键 merge request(III)

    已经有两位同学写过类似的 wiki 了,值得一看: gitlab一键提交request merge & assign 为啥我又来凑热闹呢?基于下面两个原由: 我的机子是 Win10,上面脚本的 ...