为什么GNU dd会使用dup2重用文件描述符0和1?

时间:2018-10-07 14:26:43

标签: c system-calls dup gnu-coreutils

在从nu追踪dd时,我发现了一些令我惊讶的东西:

openat(AT_FDCWD, "/dev/zero", O_RDONLY) = 3                                                                                                                   
dup2(3, 0)                              = 0                                                                                                                   
close(3)                                = 0                                                                                                                   
lseek(0, 0, SEEK_CUR)                   = 0                                                                                                                   
openat(AT_FDCWD, "/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
dup2(3, 1)                              = 1
close(3)                                = 0
mmap(NULL, 1060864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x681e58939000
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576) = 1048576
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576) = 1048576
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576) = 1048576
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1048576) = 1048576
close(0)                                = 0
close(1)                                = 0

dd打开应该读取/写入的文件,然后使用dup2将filedescriptor更改为filedescriptor 0(stdin)和1(stdout)。

我抬起code,看看这是通过人工优化还是通过编译器优化完成的,并且确实存在:

static int
ifd_reopen (int desired_fd, char const *file, int flag, mode_t mode)
{
  int ret;

  do
    {
      process_signals ();
      ret = fd_reopen (desired_fd, file, flag, mode);
    }
  while (ret < 0 && errno == EINTR);

  return ret;
}


// ...

  if (input_file == NULL)
    {
      input_file = _("standard input");
      set_fd_flags (STDIN_FILENO, input_flags, input_file);
    }
  else
    {
      if (ifd_reopen (STDIN_FILENO, input_file, O_RDONLY | input_flags, 0) < 0)
        die (EXIT_FAILURE, errno, _("failed to open %s"),
             quoteaf (input_file));
    }

在以下代码中,无论是否告诉dd从stdin或文件中读取,它们都使用STDIN_FILENO(和STDOUT_FILENO)。但是,只要将fd存储在某个变量中并使用它,就可以实现相同的目的。使用2个额外的syscall和一堆代码来保存1个int似乎是不合理的。那么或重用stdin / stdout的fd有什么好处?

0 个答案:

没有答案