dup/dup2函数用法

系统调用dup和dup2能够复制文件描述符。dup返回新的文件描述符(没有用的文件描述符最小的编号)。dup2可以让用户指定返回的文件描述符的值,它通常用来重新打开或者重定向一个文件描述符。函数原型如下:

1
2
3
#include <unsitd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);

dup和dup2都是返回新的文件描述符,如果出错,返回-1.在dup2中,如果newfd文件已经打开,关闭打开的文件,重定向oldfd所指的文件。新老描述符共享文件的偏移量(位置)、标志和锁,但是不共享close-on-exec标志。


每个进程在进程表中都有一个记录项,每个记录项中有一张打开文件描述符表,可将视为一个矢量,每个描述符占用一项。与每个文件描述符项关联的是:

  • 文件描述符标志
  • 指向一个文件表项的指针

内核为所有打开文件维持一张文件表。每个文件表包含:

  • 文件状态标志(读、写、增写、同步、非阻塞等)
  • 当前文件位移量
  • 指向该文件v节点表项的指针

下面是一段比较简单的程序:创建文件,并将标准输出重定向到文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char *argv[])
{

int fd;
//(1)打开文件
fd = open("my.file", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (fd == -1)
{
perror("\nERROR:fail to create my.file.");
return -1;
}
//(2)文件重定向
if (dup2(fd, STDOUT_FILENO) == -1)
{
perror("\nERROR: fail to redirect std output.");
return -1;
}
//(3)删除oldfd
if (close(fd) == -1)
{
perror("\nERROR: fail to close my.file.");
return -1;
}
//(4)标准输出
if (write(STDOUT_FILENO, "HELLO", 5) == -1)
{
perror("\nERROR: fail to write to file.");
return -1;
}
return 0;
}

  1. open函数打开文件,文件不存在时,根据给定的参数进行文件创建,创建以后再打开。并在系统文件表内创建一个条目。
    这里写图片描述
  2. dup2函数将标准输出定向到刚打开的fd中。
    这里写图片描述
  3. close()后,删除掉fd。
    这里写图片描述
    经过以上三步后,进行标准输出时,会被输出到myfile文件中。