zoukankan      html  css  js  c++  java
  • APUE习题3.2用dup实现dup2以及shell中重定向符号的使用

    习题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! ";

      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 ", 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已被占有的情形。

  • 相关阅读:
    dynamics crm 2011升级过程中发现的一些问题
    报价单上的“创建订单”按钮Disabled
    C/C++ Qt TableDelegate 自定义代理组件
    C/C++ Qt TabWidget 实现多窗体创建
    C/C++ Qt MdiArea 多窗体组件应用
    C/C++ Qt Tree与Tab组件实现分页菜单
    C/C++ Qt ListWidget 增加右键菜单
    C/C++ Qt StatusBar 底部状态栏应用
    C/C++ Qt TableWidget 表格组件应用
    VS2012 + Qt 4.8.3 + OpenSSL
  • 原文地址:https://www.cnblogs.com/instona/p/4280545.html
Copyright © 2011-2022 走看看