📜  dup()和dup2()Linux系统调用(1)

📅  最后修改于: 2023-12-03 15:00:33.332000             🧑  作者: Mango

Linux系统调用: dup()和dup2()

在Linux系统中,dup()和dup2()是非常常用的两个系统调用。它们主要用于复制文件描述符,从而使得文件描述符的引用计数增加,从而允许多个文件描述符引用同一个打开的文件。

dup()

dup()系统调用的原型为:

#include <unistd.h>

int dup(int oldfd);

该函数的功能为创建一个新的文件描述符,使得该文件描述符和oldfd所指向的文件描述符指向同一个打开的文件。函数返回值为新的文件描述符。

使用dup()系统调用可以充分利用文件描述符,使得多次操作同一个文件时,无需反复打开和关闭该文件。另外,我们常常会在调用系统函数前将它们进行dup(),这样做的好处是可以在需要时关闭文件,而不会影响到之前打开的文件描述符。

示例:

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

int main()
{
   int fd, newfd;

   fd = open("file.txt", O_RDONLY);
   if(fd == -1)
   {
       printf("Failed to open file\n");
       return -1;
   }
   
   newfd = dup(fd);
   if (newfd == -1)
   {
       printf("Failed to duplicate file descriptor\n");
       close(fd);
       return -2;
   }

   close(fd);
   printf("File descriptor has been closed\n");

   char buffer[1024];
   int count = read(newfd, buffer, sizeof(buffer));
   if(count > 0)
   {
       printf("%s", buffer);
   }
   else
   {
       printf("Error reading from file\n");
   }
   
   close(newfd);
   printf("File descriptor has been closed\n");

   return 0;
}

在上述示例中,我们首先调用了open()函数打开一个文件,并得到了文件描述符fd。然后使用dup()方法复制该文件描述符,得到另一个描述符newfd。在接下来的代码中,我们先关闭了原始文件描述符fd,然后读取了newfd所指向的文件。

dup2()

dup2()的函数原型为:

#include <unistd.h>

int dup2(int oldfd, int newfd);

该函数和dup()类似,也可以用于复制文件描述符。但不同的是,dup2()可以使新的文件描述符成为指定的描述符的副本,同时可以释放原描述符。如果newfd已经打开,dup2()会首先关闭它。

使用dup2()系统调用的好处在于,可以更容易地控制文件描述符的编号,这对于我们使用到了类似标准输入、标准输出等特殊文件描述符的程序来说就尤为重要。

示例:

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

int main()
{
   int fd1, fd2;
   char buffer[1024];

   fd1 = open("file.txt", O_RDONLY);
   if(fd1 == -1)
   {
       printf("Failed to open file\n");
       return -1;
   }
   
   fd2 = dup2(fd1, 100);
   if(fd2 == -1)
   {
       printf("Failed to duplicate file descriptor\n");
       close(fd1);
       return -2;
   }

   printf("fd1=%d fd2=%d\n", fd1, fd2);

   close(fd1);

   int count = read(fd2, buffer, sizeof(buffer));
   if(count > 0)
   {
       printf("%s", buffer);
   }
   else
   {
       printf("Error reading from file\n");
   }
   
   close(fd2);

   return 0;
}

在上述示例中,我们首先调用了open()函数打开一个文件,并得到了文件描述符fd1。然后使用dup2()方法复制该文件描述符,并将其复制得到的描述符设为100,得到另一个描述符fd2。我们在接下来的代码中关闭了原始文件描述符fd1,然后读取了newfd所指向的文件。该示例中还打印出了fd1和fd2的值,以表明dup2()已经将fd2赋为100。

总而言之,dup()和dup2()系统调用非常有用,在处理文件和套接字等任务时经常用到。掌握它们的使用方法,可以提高我们的代码质量和开发效率。