「Linux 系统编程」dup 与 dup2 函数

1 dup 函数

1.1 函数原型

1
2
3
#include <unistd.h>

int dup(int oldfd);
  • oldfd: 需要被复制的现有文件描述符

返回值:

  • 成功时返回新的文件描述符(当前可用的最小文件描述符),新描述符和 oldfd 指向相同文件

  • 失败时返回 -1 并设置 errno


1.2 代码示例

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
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main(){
int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
if(fd == -1){
perror("open error");
return 1;
}

// 复制文件描述符
int new_fd = dup(fd);
if(new_fd == -1){
perror("dup error");
return 1;
}

printf("Original FD: %d, Duplicated FD: %d\n", fd, new_fd);

// 两个文件描述符指向同一个文件,都会写入到 test.txt
write(fd, "Hello from fd\n", 14);
write(new_fd, "Hello from new_fd\n", 18);

close(fd);
close(new_fd);

return 0;
}



2 dup2 函数

2.1 函数原型

1
2
3
#include <unistd.h>

int dup2(int oldfd, int newfd);
  • oldfd: 被复制的现有文件描述符
  • newfd: 复制到的目标文件描述符

返回值:

  • 成功时 返回新的文件描述符(即 newfd),此时 newfd 指向的文件和 oldfd 指向的文件是同一个

  • 失败时返回 -1 并设置 errno


2.2 代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main(){
int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
if(fd == -1){
perror("open error");
return 1;
}

// 将标准输出(fd 为 1)重定向到文件
if(dup2(fd, STDOUT_FILENO) == -1){
perror("dup2 error");
return 1;
}

close(fd); // 现在可以关闭原始文件描述符

// 此时 printf 会输出到文件中
printf("Test of dup2\n");

return 0;
}



3 使用 fcntl 实现 dup 功能

fcntl 函数可以实现 dup 的功能。

1
2
3
4
#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */ );

其中,cmd 参数使用 F_DUPFD 命令,第 3 个参数设置为 一个整数

  • 如果整数对应文件描述符 被占用,返回当前最小可用的文件描述符;
  • 如果整数对应文件描述符 未被占用,返回等于该整数值的文件描述符。
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
36
37
38
39
40
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main(){
int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
if(fd == -1){
perror("open error");
return 1;
}

// 使用 fcntl 复制文件描述符,预计返回 4
int new_fd = fcntl(fd, F_DUPFD, 0);
if(new_fd == -1){
perror("fcntl error");
return 1;
}

// 使用 fcntl 复制文件描述符,预计返回 8
int new_fd2 = fcntl(fd, F_DUPFD, 8);
if(new_fd2 == -1){
perror("fcntl 2 error");
return 1;
}

printf("Original FD: %d\n", fd);
printf("Duplicated FD: %d\n", new_fd);
printf("Duplicated FD2: %d\n", new_fd2);

// 写入测试
write(fd, "Hello from original\n", 20);
write(new_fd, "Hello from duplicate\n", 21);
write(new_fd2, "Hello from duplicate 2\n", 23);

close(fd);
close(new_fd);
close(new_fd2);

return 0;
}


「Linux 系统编程」dup 与 dup2 函数
https://marisamagic.github.io/2025/08/30/20250830/
作者
MarisaMagic
发布于
2025年8月30日
许可协议