dup2 and dup修改和恢复进程的标准输入

dup2(oldfd, newfd).
旧的文件描述符,和新的文件描述符指向同一个文件。

int ans = dup(oldfd);
返回值文件描述符和旧的文件描述符指向同一个文件。

通过dup/dup2,可以将多个文件描述符指向同一个文件实体,它们都可以等效得访问同一个文件。

dup2的操作会额外关闭原newfd指向的文件。

dup2中newfd指向的文件除了newfd之外还有其他描述符的时候,文件并不会真的被关闭。
仅有newfd的时候文件描述符才会被真正关闭。

通过描述,我们理论上是可以设计一个替换程序stdin为某文件,用完再恢复原始的stdin.

下面是一个简单的实现,首先将标准输入设置为从某个文件,读取其中的第一行,然后将标准输入又变回原本的标准输入。

#include <stdio.h>
#include <unistd.h>

int main() {
  int fd = open("hello_process.c", 2, 0666);
  int old_stdin_fd = dup(0);
  dup2(fd,0);
  int c;
  while( (c=fgetc(stdin)) != '\n' )  {
    putchar(c);
  }
  putchar(c);

  printf("done resume to stdin \n");
  dup2(old_stdin_fd, fd);
  stdin = fdopen(old_stdin_fd,"r");
  while( (c=getchar())!=EOF  )  {
    putchar(c);
  }
}

尝试过程中有一点小插曲。

即resume之后,使用read(0, &c,1)没问题,但c = getchar()或者c=fgetc(stdin)的时候,会出现貌似原始文件没关闭的情况。依然可读的状态。
原因是C中getchar/fgetc对read操作做了缓存,测试中这个缓存大小为4K,在缓存没读完之前,并不会利用文件描述符去真的读数据。

posted @ 2023-06-20 06:24  zwlwf  阅读(53)  评论(0)    收藏  举报