Linux系统编程18-dup和dup2.md
dup
在Linux中,dup函数用于复制一个文件描述符。具体而言,dup函数会复制参数fd所指向的文件描述符,并返回一个新的文件描述符,新的文件描述符和原文件描述符指向同一个文件表项,也就是说,它们共享同一文件偏移量和文件状态标志等信息。新的文件描述符和原文件描述符的值可能不同。
#include <unistd.h>
int dup(int oldfd);
作用: 复制一个新的文件描述符,指向同一个文件,
从空闲的文件描述符表中找一个最小的作为新文件描述符
参数:
- oldfd 旧的文件描述符
返回:
新描述符
-1 错误
实例: 复制一个文件描述符,并且为所指向的文件写入数据
dup.c
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char const *argv[])
{
int fd = open("dup.txt", O_RDWR | O_CREAT, 0664);
int fd1 = dup(fd);
if (fd == -1)
{
perror("dup err");
return -1;
}
printf("fd : %d, fd1 : %d\n", fd, fd1);
close(fd);
char *str = "hello world";
int ret = write(fd1, str, strlen(str));
if (ret == -1)
{
perror("write err");
return -1;
}
close(fd1);
return 0;
}
需要注意的是,由于dup函数返回的新文件描述符和原文件描述符共享同一文件表项,因此在使用完这两个文件描述符后,需要分别将它们关闭,否则可能导致文件描述符泄漏。
dup2
#include <unistd.h>
int dup2(int oldfd, int newfd);
作用: 重定向文件描述符
例如 oldfd 指向 a.txt, newfd 指向 b.txt
调用函数成功后, newfd 的 b.txt 做 close, newfd指向了a.txt;
oldfd 必须是一个有效的文件描述符
如果 oldfd 和 newfd 值相同,相当于什么都没有做
返回: 与newfd相同的新文件描述符
其中 oldfd
是需要被复制的文件描述符,newfd
是新的文件描述符,它与 oldfd
共享同一个文件表项。如果 newfd
之前已经打开了,则 dup2
会先关闭 newfd
,再将 oldfd
复制到 newfd
,使得 newfd
与 oldfd
指向同一个文件表项。
实例:
dup2.c
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
//创建dup2.txt
int fd = open("dup2.txt", O_RDWR | O_CREAT, 0664);
if (fd == -1)
{
perror("open err");
return -1;
}
//创建dup3.txt
int fd1 = open("dup3.txt", O_RDWR | O_CREAT, 0664);
if (fd1 == -1)
{
perror("open err");
return -1;
}
printf("fd : %d, fd1 : %d\n", fd, fd1);
// fd1不再指向dup3.txt, 而是指向和fd的同一个文件dup2.txt
int fd2 = dup2(fd, fd1);
if (fd2 == -1)
{
perror("dup2 err");
return -1;
}
//通过fd1 去写数据
char *str = "hello, dup2";
int len = write(fd1, str, strlen(str));
if (len == -1)
{
perror("write err");
return -1;
}
printf("fd : %d, fd1 : %d, fd2 : %d\n", fd, fd1, fd2);
// fd : 3, fd1 : 4
// fd : 3, fd1 : 4, fd2 : 4
close(fd);
close(fd1);
return 0;
}