1、dup函数
作用:复制一个新的文件描述符
man 2 dup
DESCRIPTION
The dup() system call creates a copy of the file descriptor oldfd, using the lowest-numbered unused file descriptor for the new descriptor.
就是会用空闲的最小的文件描述符去创建oldfd的拷贝。
这跟 “每次新打开文件都会占用一个文件描述符,而且是最小的” 是一致的。
RETURN VALUE
On success, these system calls return the new file descriptor. On error, -1 is returned, and errno is set appropriately.
#include <unistd.h>
int dup(int oldfd);
作用:复制一个新的文件描述符
fd=3, int fd1 = dup(fd),
fd指向的是a.txt, fd1也是指向a.txt
从空闲的文件描述符表中找一个最小的,作为新的拷贝的文件描述符
测试:
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
int main() {
int fd = open("a.txt", O_RDWR | O_CREAT, 0664);
int fd1 = dup(fd);
if(fd1 == -1) {
perror("dup");
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");
return -1;
}
close(fd1);
return 0;
}
结果:
fd : 3 , fd1 : 4
返回值:指向与输入参数相同,值不同(选当前最小的文件描述符)。
2、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值相同的话,相当于什么都没有做
DISCRIPTION:
The dup2() system call performs the same task as dup(), but instead of using the lowest-numbered unused file descriptor, it uses the file descriptor number specified in newfd. If the file descriptor newfd was previously open, it is silently closed before being reused.
关闭和重复使用文件描述符 newfd 的步骤是以原子方式执行的。 这一点很重要,因为试图使用 close(2) 和 dup() 实现等效功能会出现竞赛条件,即 newfd 可能在这两个步骤之间被重复使用。 发生这种重复使用的原因可能是主程序被分配文件描述符的信号处理程序中断,也可能是并行线程分配了文件描述符。
请注意以下几点:
* 如果 oldfd 不是有效的文件描述符,则调用失败,newfd 也不会关闭。
* 如果 oldfd 是一个有效的文件描述符,且 newfd 的值与 oldfd 相同,则 dup2() 不会执行任何操作,而是返回 newfd。
RETURN VALUE:
On success, these system calls return the new file descriptor. On error, -1 is returned, and errno is set appropriately.
测试:
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
int main() {
int fd = open("1.txt", O_RDWR | O_CREAT, 0664);
if(fd == -1) {
perror("open");
return -1;
}
int fd1 = open("2.txt", O_RDWR | O_CREAT, 0664);
if(fd1 == -1) {
perror("open");
return -1;
}
printf("fd : %d, fd1 : %d\n", fd, fd1); //3 4
int fd2 = dup2(fd, fd1);
if(fd2 == -1) {
perror("dup2");
return -1;
}
// 通过fd1去写数据,实际操作的是1.txt,而不是2.txt
char * str = "hello, dup2";
int len = write(fd1, str, strlen(str));
if(len == -1) {
perror("write"); //第三章的函数perror
return -1;
}
printf("fd : %d, fd1 : %d, fd2 : %d\n", fd, fd1, fd2);//3 4 4
close(fd);
close(fd1);
return 0;
}
- fd指向1.txt,fd1指向2.txt;
- 执行dup2操作后,fd1指向了1.txt;
- 写数据时,使用的是fd1操作的:write(fd1, str, strlen(str)),所以最后1.txt中内容为:hello, dup2。
- 由于fd2等于fd1,也可通过fd2执行write。
总结:
两者不同点:dup复制到最小的文件描述符,dup2复制指定的newfd的值。