会计考友 发表于 2012-8-4 12:07:07

Linux认证辅导:形象的理解dup和dup2函数(2)

Linux认证辅导:形象的理解dup和dup2函数(2)
一、单个进程内的dup和dup2
  假设进程A拥有一个已打开的文件描述符fd3,它的状态如下:
  进程A的文件描述符表(before dup2)
  ------------
  fd0 0 | p0
  ------------
  fd1 1 | p1 -------------》 文件表1 ---------》 vnode1
  ------------
  fd2 2 | p2
  ------------
  fd3 3 | p3 -------------》 文件表2 ---------》 vnode2
  ------------
  。。. 。。.
  。。. 。。.
  ------------
  经下面调用:
  n_fd = dup2(fd3, STDOUT_FILENO);后进程状态如下:
  进程A的文件描述符表(after dup2)
  ------------
  fd0 0 | p0
  ------------
  n_fd 1 | p1 ------------
  ------------ \
  fd2 2 | p2 \
  ------------ _\|
  fd3 3 | p3 -------------》 文件表2 ---------》 vnode2
  ------------
  。。. 。。.
  。。. 。。.
  ------------
  解释如下:
  n_fd = dup2(fd3, STDOUT_FILENO)表示n_fd与fd3共享一个文件表项(它们的文件表指针指向同一个文件表项),n_fd在文件描述符表中的位置为 STDOUT_FILENO的位置,而原先的STDOUT_FILENO所指向的文件表项被关闭,我觉得上图应该很清晰的反映出这点。按照上面的解释我们就可以解释CU中提出的一些问题:
  (1) “dup2的第一个参数是不是必须为已打开的合法filedes?” -- 答案:必须。
  (2) “dup2的第二个参数可以是任意合法范围的filedes值么?” -- 答案:可以,在Unix其取值区间为[0,255]。
另外感觉理解dup2的一个好方法就是把fd看成一个结构体类型,就如上面图形中画的那样,我们不妨把之定义为:
  struct fd_t {
  int index;
  filelistitem *ptr;
  };
  然后dup2匹配index,修改ptr,完成dup2操作。
  在学习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”。
页: [1]
查看完整版本: Linux认证辅导:形象的理解dup和dup2函数(2)