# 写在前面
本文主要介绍 `Linux`系统编程中用于文件描述符复制的两个函数`dup()`,`dup2()`
# 函数功能
文件描述符不用再过多赘述,它是`Linux`系统编程中用来描述一个文件的东西,而`dup()` 和 `dup2()` 是两个非常有用的系统调用,都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。
# dup
作用:复制一个新的文件描述符
函数原型:int dup(int oldfd);
头文件:
- #include <unistd.h>
参数:
- 旧的文件描述符
返回值
- 成功:返回新的文件描述符,是调用进程文件描述符表中**最小可用的文件描述符**,最终 oldfd 和新的文件描述符都指向同一个文件。
- 失败:返回 -1, 并设置 `errno`
## 举例
使用`dup()`函数复制一个文件描述符,同时对一个文件进行写操作
```c
#include<stdio.h>
#include <unistd.h>
#include <error.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int fd1;
fd1 = open("test.txt",O_RDWR|O_CREAT|O_TRUNC,0644);//打开一个文件
if(fd1 == -1){
perror("open error");
exit(1);
}
char *str1 = "hello fd1\n";
write(fd1, str1, strlen(str1));//通过文件描述符fd1向文件中写
char *str2 = "hello fd2\n";
int fd2 = dup(fd1);
write(fd2, str2, strlen(str2));//通过文件描述符fd2向文件中写
close(fd1);//关闭文件描述符
close(fd2);
return 0;
}
```
程序执行结果,两个字符串都在`test.txt`内,`dup()` **复制的新文件描述符是系统自动分配的最小可用的文件描述符**

# dup2
作用:通过 `oldfd` 复制出一个新的文件描述符 `newfd`,如果成功,`newfd` 和函数返回值是同一个返回值,最终 `oldfd` 和新的文件描述符 `newfd` 都指向同一个文件。
函数原型:int dup2(int oldfd, int newfd);
头文件:
- #include <unistd.h>
参数:
- oldfd:旧的文件描述符
- newfd:新的文件描述符
返回值:
- 成功:返回新的文件描述符
- 失败:返回-1, 设置`errno`
## 案例
将上述案例通过`dup2()`实现
```
#include<stdio.h>
#include <unistd.h>
#include <error.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
int fd1;
fd1 = open("test.txt",O_RDWR|O_CREAT|O_TRUNC,0644);
if(fd1 == -1){
perror("open error");
exit(1);
}
printf("fd1========%d\n", fd1);
//先通过fd1复制出fd2,fd1,fd2都指向"test.txt"
//将fd2设置为标准输出(显示在屏幕上)
int fd2 = dup2(fd1, STDOUT_FILENO);
//下面这句话不会出现在屏幕上,而是在"test.txt"中,
// printf()是标准库函数,最终还是会调用系统调用函数write()
// 相当于这样,write(test,),往 test 文件描述符写内容,
// 默认的情况下, test 文件描述符指向标准输出设备(如,显示屏)
// 所以, printf()的内容先显示到屏幕上
// 但是现在 test 文件描述符指向文件 "test.txt"
// 所以,printf()的内容会写入文件 "test.txt"
printf("fd2========%d\n", fd2);
close(fd1);
close(fd2);
return 0;
}
```
程序执行结果如下

一个出现在文件中, 一个出现在`test.txt`中
# 区别
`dup2`与`dup`区别是`dup2`可以用参数`newfd`指定新文件描述符的数值。若参数`newfd`已经被程序使用,则系统就会将`newfd`所指的文件关闭,若`newfd`等于`oldfd`,则返回`newfd`,而不关闭n`ewfd`所指的文件。`dup2`所复制的文件描述符与原来的文件描述符共享各种文件状态。共享所有的锁定,读写位置和各项权限或`flags`等.
文件描述符复制dup,dup2函数