dup、dup2函数:复制一个文件描述符,使新文件描述符也标识旧文件描述符所标识的文件。
操作新旧文件描述符都是操作同一个文件。
1. dup函数
#include<unistd.h>
int dup(int oldfd);
/*
功能:
通过oldfd复制一个新的文件描述符指向oldfd的文件,
新的文件描述符为调用进程文件描述符表中可用的最小文件描述符。
参数:
oldfd:需要复制的文件描述符
返回值:
成功:新的文件描述符
失败:-1
*/
dup使用示例:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<fcntl.h>
#define SIZE 128
int test() {
int fd = -1;
int newfd = -1;
int ret = -1;
char buf[SIZE];
// 1. 打开文件
fd = open("txt01", O_RDWR | O_CREAT, 0644);
if (-1 == fd) {
perror("open");
return 1;
}
printf("fd=%d\n", fd);
// 2. 复制文件描述符
newfd = dup(fd);
if (-1 == newfd) {
perror("dup");
return 1;
}
printf("newfd = %d\n", newfd);
// 3. 写文件
ret = write(fd, "ABC", 3); //
if (-1 == ret) {
perror("write");
return 1;
}
ret = write(newfd, "123", 3);
if (-1 == ret) {
perror("write");
return 1;
}
// 4. 读文件
lseek(fd, 0, SEEK_SET); // 将文件偏移复位
memset(buf, 0, SIZE);
ret = read(fd, buf, SIZE);
if (-1 == ret) {
perror("read");
return 1;
}
printf("fd内容: %s\n", buf);
// 由于newfd和fd指向同一个文件,因此它们共享文件偏移量
lseek(fd, 0, SEEK_SET); // 将文件偏移复位
memset(buf, 0, SIZE);
ret = read(newfd, buf, SIZE);
if (-1 == ret) {
perror("read");
return 1;
}
printf("newfd内容: %s\n", buf);
// 5. 关闭文件
close(fd);
close(newfd);
return 0;
}
int main(int argc, char const* argv[]) {
test();
return 0;
}
运行结果:
2. dup2函数
#include<unistd.h>
int dup2(int oldfd, int newfd);
/*
功能:
通过oldfd复制一个新的文件描述符newfd指向oldfd的文件。
newfd是人为指定的文件描述符号。
若成功,函数返回值和newfd值一样。
参数:
oldfd:需要复制的文件描述符。
newfd:新的文件描述符。该文件描述符可被人为地指定位一个数字(0-1023),
若该数字是已被使用的文件描述符,则自动关闭该数字与文件的关联,再使用这个文件描述符。
若和oldfd相等,则直接返回oldfd。
返回值:
成功:newfd
失败:-1
*/
dup2的使用和dup类似,只不过dup2可以重用已被使用的文件描述符。